- 浏览: 115937 次
文章分类
问题场景
每次节假日之前,公司的业务人员要通过我们开发的短信平台发送大量短信,导致数据库发生死锁。直接结果就是部分更新状态的操作对应的事务回滚,导致月底和移动公司对不平账。
获取死锁详细信息
通过show engine innodb status(在这里要感谢去年12月份世界末日前后吧,张瑞组织的AskHelloDBA数据库技术论坛,基本上那几场除了慢查询日志之外,我就记住了这句,不过还真挺有用。总算公司给报销的60大元+来往杭州的路费没白花,吼吼),获取最近一次发生的死锁详细信息。
update语句更新状态和状态变更时间这两个字段的值,where子句的谓词是判断主键id的值是不是在子查询的到的结果集中。即形如update 表A set .... where id in (一个范围)
此时对应输出(截取部分)为
一条普通的insert语句
InnoDB处理方式:
也就是在同一张表上操作的事务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
每次节假日之前,公司的业务人员要通过我们开发的短信平台发送大量短信,导致数据库发生死锁。直接结果就是部分更新状态的操作对应的事务回滚,导致月底和移动公司对不平账。
获取死锁详细信息
通过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
发表评论
-
[转]mysql中如何重命名数据库 转自运维人生http://opkeep.com
2013-06-24 11:19 822来源:http://opkeep.com/database/m ... -
64位Ubuntu 安装MySQL 5.5.32 错误记录与解决
2013-06-21 19:50 10861. dev.mysql.com/downloads 下载ta ... -
[转]mysql忘记root密码怎么办?重设Mysql密码的方法
2013-06-21 11:36 1121转自:http://it.oyksoft.com/ ... -
其他机器连不上本地infobright,报错'reading initial communication packet', system error: 0
2013-05-20 14:59 1886装好infobright之后,无法在其他机器连接本地ib(ro ... -
非正常关机;[ERROR 2002 (HY000);mysqld无法启动;innodb recovery失败
2013-05-17 16:24 1609os:ubuntu 11.10 db: mysql 旧5.1. ... -
[整理]一行变多行(Oracle)
2013-04-10 10:27 2517来源:http://www.itpub.net/thread- ... -
获取行号
2013-04-10 10:10 832MySQL select @rownum:=@rownum+1 ... -
行转列,列转行
2013-04-09 10:23 853SQL Server http://www.cnblogs.c ... -
多行(结果集)拼接字符串 (多行变一行)
2013-04-09 10:18 1902SQL Server版: select stuff( ... -
[转载]ubuntu安装(ubuntu 下架设LAMP+phpmyadminphpmyadmin)
2013-03-14 16:05 902转载 http://forum.ubuntu.org.cn/v ... -
MySQL慢查询专题
2013-02-25 16:00 803相关命令: mysql> show variables ... -
mssql len datalength oracle:length lengthb mysql: length char_length
2012-12-10 17:18 1868字符长度:oracle length(),mysql char ... -
mysql修改列
2012-11-16 13:40 745alter table t_feedback change u ...
相关推荐
基于yolov5目标检测的跌倒检测数据集(voc格式)——上部
工程代码基于STM32F103C8T6,通过ADC多通道检测4个数据,使用一个电位器产生0-3.3v连续变化的模拟电压信号,和三个传感器:光敏电阻模块,热敏电阻模块,红外反射模块。之后用stm32的adc读取数据,并且通过oled屏幕显示4个数据。
2024年中国便携式RFID读写器行业研究报告
2024年中国超声腐蚀监测系统行业研究报告
惠普打印机主板免芯片编程器固件HP 136NW/W,实测HP 136WM也可以用,另外还有原机固件备份! 免芯片就是加粉不需要更换芯片了,一直显示满粉
蚁群算法MATLAB代码
ManifestDownload_230712_52pojie.zip.cab
【作品名称】:基于Socket作为服务器与传感器通讯手段实现的家庭能源管理系统 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。
2024年中国被动长波红外镜头行业研究报告
简介:配送路线优化系统,Web端项目 算法:遗传算法+蚁群算法+多目标优化 技术栈:前端采用Vue-CLI开发(frontend),后端采用Django框架开发(ulb_manage)
2024年中国超声波凝固和切割装置行业研究报告
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提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
这是一组从网站上的精选用户那里收集的 20,000 多款游戏 Lichess.org,以及如何收集更多游戏。我还将在未来收集更多游戏时上传它们。此套装包含:游戏 ID;额定值 (T/F);开始时间;结束时间;匝数;游戏状态;胜利者;时间增量;白色玩家 ID;白人球员评分;黑色玩家 ID;黑人球员评分;所有动作均采用标准国际象棋符号;Opening Eco(任何给定开口的标准化代码,在此处列出); 开场名称;开盘(开盘阶段的移动次数)
自己的NLP学习笔记,暂时还没有加上参考文章的链接~ 以后一定补上!
建伍8100车载对讲写频软件
ISO 4892-3 2016 塑料实验室光源暴露方法第3部分:荧光紫外灯.pdf
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
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.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提高了应用性能,简化了开发流程,并且能更快地响应市场需求。