免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1441 | 回复: 0
打印 上一主题 下一主题

MySQL5.0.X自增列引发Deadlock报错 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:46 |只看该作者 |倒序浏览

最近在上午高峰期间,APP有如下较多的报错:
Deadlock found when trying to get lock; try restarting transaction

报错的SQL是对InnoDB表的insert语句,且插入auto_increment值

MySQL 5.0.X的InnoDB的auto-incrment列上的 auto-inc lock 是 X lock(排他锁/互斥锁),而且是个表级锁,且在insert完成之前不会释放 auto-inc lock,因此可以说无法真正并发的同时执行需要auto-incrment取值的insert语句

从 mysql> show innodb status\G 得到的信息大致意思是:
1. trx id 1412498935 得到 AUTO-INC lock,等待 InnoDB queue(每个表的auto-increment列在内存中都有一个计数器)给出自增值
2. trx id 1412498945 请求 AUTO-INC lock,但得到的是 AUTO-INC waiting lock,等待 AUTO-INC lock 被给予
3. trx id 1412515772 又来请求 AUTO-INC lock,这时MySQL认为“TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH”,意思就是说“等待 AUTO-INC lock 的事务太多了”,于是对该事务进行了回滚,但是MySQL对于这种情况给出的是“Deadlock found when trying to get lock; try restarting transaction”的报错

在InnoDB引擎中,在一条记录上同一时间有超过 200 个 X lock 时,MySQL会给出“TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH”信息,并放弃所有的锁检测,直接报“Deadlock found when trying to get lock”错误

官方说法,在InnoDB引擎上,当同一条记录上的锁深度(个数)超过LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK(代码中这个常量值为200)或锁开销大于LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK(代码中这个常量值为1000000)时,MySQL会给出“TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH”信息,并放弃所有的锁检测,直接报“Deadlock found when trying to get lock”错误

MySQL 5.1.X中,提供了新的锁模式,对于简单的取自增值insert语句,只在获得auto_increment值的时候对自增计数器加上一个轻量级的 X lock,而非表级锁,并且在得到auto_increment值后就立即释放了,而不是等到insert语句执行完才释放
设置 innodb_autoinc_lock_mode=0 沿用表级auto-inc锁
设置 innodb_autoinc_lock_mode=1 使用新的计数器级auto-inc锁




您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP