`

记一次MySQL死锁(对同一张表update和insert)的解决

阅读更多
问题场景
    每次节假日之前,公司的业务人员要通过我们开发的短信平台发送大量短信,导致数据库发生死锁。直接结果就是部分更新状态的操作对应的事务回滚,导致月底和移动公司对不平账。

获取死锁详细信息
通过show engine innodb status(在这里要感谢去年12月份世界末日前后吧,张瑞组织的AskHelloDBA数据库技术论坛,基本上那几场除了慢查询日志之外,我就记住了这句,不过还真挺有用。总算公司给报销的60大元+来往杭州的路费没白花,吼吼),获取最近一次发生的死锁详细信息。
------------------------
LATEST DETECTED DEADLOCK
------------------------
130426 15:01:53
*** (1) TRANSACTION:
TRANSACTION 0 2428709, ACTIVE 0 sec, process no 22752, OS thread id 139964634302208 fetching rows
mysql tables in use 2, locked 2
LOCK WAIT 20 lock struct(s), heap size 3024, 862 row lock(s)
MySQL thread id 1211536, query id 12990681 localhost 127.0.0.1 db Sending data

update语句更新状态和状态变更时间这两个字段的值,where子句的谓词是判断主键id的值是不是在子查询的到的结果集中。即形如update 表A set .... where id in (一个范围)
此时对应输出(截取部分)为
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 2479 n bits 136 index `PRIMARY` of table `db`.`lock_occured_table` trx id 0 2428709 lock_mode X waiting


*** (2) TRANSACTION:
TRANSACTION 0 2428707, ACTIVE 1 sec, process no 22752, OS thread id 139964634904320 inserting, thread declared inside InnoDB 500
mysql tables in use 1, locked 1
10 lock struct(s), heap size 1216, 6 row lock(s), undo log entries 63
MySQL thread id 1211510, query id 12990732 localhost 127.0.0.1 db update

一条普通的insert语句
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 2479 n bits 136 index `PRIMARY` of table `db`.`lock_occured_table` trx id 0 2428707 lock_mode X locks rec but not gap
Record lock, heap no 57 PHYSICAL RECORD: n_fields 9; compact format; info bits 0
 0: len 30; hex 30333464373737362d376535622d346435392d613638342d383231373036; asc 034d7776-7e5b-4d59-a684-821706;...(truncated); 1: len 6; hex 000000250f23; asc    % #;; 2: len 7; hex 8000000b41034c; asc     A L;; 3: len 11; hex 3135383430353039343531; asc 15840509451;; 4: len 30; hex 64633965613930382d643066312d396264382d626563392d353135323939; asc dc9ea908-d0f1-9bd8-bec9-515299;...(truncated); 5: SQL NULL; 6: len 2; hex 2d31; asc -1;; 7: len 8; hex 8000124ef4ffbe48; asc    N   H;; 8: len 30; hex 64333066323435312d336339312d346230352d383032622d383762346335; asc d30f2451-3c91-4b05-802b-87b4c5;...(truncated);

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 2447 n bits 136 index `PRIMARY` of table `db`.`lock_occured_table` trx id 0 2428707 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 21 PHYSICAL RECORD: n_fields 9; compact format; info bits 0
 0: len 30; hex 30303138393466332d363262652d343365622d626266312d643265633462; asc 001594f3-62be-43eb-bbf1-d2ec4b;...(truncated); 1: len 6; hex 000000110936; asc      6;; 2: len 7; hex 80000009820454; asc       T;; 3: len 11; hex 3138373231303433353639; asc 18721043569;; 4: len 30; hex 63353563366632332d656238352d613735382d393466362d353132303633; asc c35c6f23-ec85-a758-94f6-512063;...(truncated); 5: len 8; hex 8000124eee70f814; asc    N p  ;; 6: len 1; hex 31; asc 1;; 7: len 8; hex 8000124eee70e769; asc    N p i;; 8: len 30; hex 38653966386339362d393266372d343638662d626536352d353863323035; asc 8c9f8d96-92f7-468f-be65-58c205;...(truncated);



InnoDB处理方式:
*** WE ROLL BACK TRANSACTION (1)


也就是在同一张表上操作的事务1与事务2冲突了,结果回滚了更新状态的事务1。
其实理解这短短几句话,费了我很长时间——因为看着眼晕,我瞟两眼就不看了,隔几天再瞟两眼又晕又不看了。这会再看看,其实问题描述得已经很明显了嘛。

最后我的理解是update和insert都想对同一张表的主键索引加排它锁。

根据MySQL 5.1(这会才出版本号,XD,哼哼 具体为5.1.67)的文档对InnoDB事务隔离级别的描述(见http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html),偶终于知道原因了,解决方法也很明显了。

于是乎,做个测试(先说明,偶们的库采用的是默认的事务隔离级别Repeatable Read,其实对这个场景来说哪个隔离级别都一样)
事务1:
start transaction
update 表A set 状态=3 where id=55;

事务2:
start transaction
向表A insert 一条记录

现在不管这两个事务的执行顺序如何,最后都可以再执行commit而不像之前那样show engine innodb status中会看到由于等待时间长死锁或直接死锁。

告诉开发同事,先将要update的记录的id都取出来(select不会像事务1那样对主键索引加排它锁哦),然后对每个id单独执行update(更新指定的单条记录也不会像原来那样哦),这样就能避免事务1(update操作)与事务2(批量insert)发生冲突了。

从此天下太平,五一又要到了,终于不用担心这个问题了。

P.S.记得SQL Server的事务隔离级别也是默认重复读。改天试试会不会有类似问题。

(
思路参考 http://www.chriscalender.com/?p=426
关于innodb的概述,可查看 http://www.mysqlperformanceblog.com/2006/07/17/show-innodb-status-walk-through/
)

下面转一个DB2和 Oracle的 DB2和 Oracle的并发控制(锁)比较:
http://sunxboy.iteye.com/blog/387625
分享到:
评论

相关推荐

    基于yolov5目标检测的跌倒检测数据集(voc格式)-上部

    基于yolov5目标检测的跌倒检测数据集(voc格式)——上部

    STM32通过ADC多通道检测数据

    工程代码基于STM32F103C8T6,通过ADC多通道检测4个数据,使用一个电位器产生0-3.3v连续变化的模拟电压信号,和三个传感器:光敏电阻模块,热敏电阻模块,红外反射模块。之后用stm32的adc读取数据,并且通过oled屏幕显示4个数据。

    2024年中国便携式RFID读写器行业研究报告.docx

    2024年中国便携式RFID读写器行业研究报告

    2024年中国超声腐蚀监测系统行业研究报告.docx

    2024年中国超声腐蚀监测系统行业研究报告

    惠普打印机主板免芯片编程器固件HP 136NW/W,实测HP 136WM也可以用

    惠普打印机主板免芯片编程器固件HP 136NW/W,实测HP 136WM也可以用,另外还有原机固件备份! 免芯片就是加粉不需要更换芯片了,一直显示满粉

    蚁群算法MATLAB代码

    蚁群算法MATLAB代码

    ManifestDownload_230712_52pojie.zip.cab

    ManifestDownload_230712_52pojie.zip.cab

    基于python实现的Socket服务器与传感器通讯手段实现的家庭能源管理系统

    【作品名称】:基于Socket作为服务器与传感器通讯手段实现的家庭能源管理系统 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。

    2024年中国被动长波红外镜头行业研究报告.docx

    2024年中国被动长波红外镜头行业研究报告

    配送路线优化系统,Web端项目,遗传算法+蚁群算法+多目标优化

    简介:配送路线优化系统,Web端项目 算法:遗传算法+蚁群算法+多目标优化 技术栈:前端采用Vue-CLI开发(frontend),后端采用Django框架开发(ulb_manage)

    2024年中国超声波凝固和切割装置行业研究报告.docx

    2024年中国超声波凝固和切割装置行业研究报告

    node-v4.5.0-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    国际象棋游戏数据集 CSV 2W+场次 (Lichess)

    这是一组从网站上的精选用户那里收集的 20,000 多款游戏 Lichess.org,以及如何收集更多游戏。我还将在未来收集更多游戏时上传它们。此套装包含:游戏 ID;额定值 (T/F);开始时间;结束时间;匝数;游戏状态;胜利者;时间增量;白色玩家 ID;白人球员评分;黑色玩家 ID;黑人球员评分;所有动作均采用标准国际象棋符号;Opening Eco(任何给定开口的标准化代码,在此处列出); 开场名称;开盘(开盘阶段的移动次数)

    属于一枚普通学生的NLP学习笔记

    自己的NLP学习笔记,暂时还没有加上参考文章的链接~ 以后一定补上!

    建伍8100车载对讲写频软件

    建伍8100车载对讲写频软件

    ISO 4892-3 2016 塑料实验室光源暴露方法第3部分:荧光紫外灯.pdf

    ISO 4892-3 2016 塑料实验室光源暴露方法第3部分:荧光紫外灯.pdf

    node-v4.8.6-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    特斯拉AP(autopilot)和FSD(Full+Self-Drive.pdf

    特斯拉AP(autopilot)和FSD(Full Self-Drive

    node-v7.7.4-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v8.2.1-linux-arm64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics