MySQL带自增字段的表在并发插入时发生死锁

问题

'int' object has no attribute 'encode'", <class 'mysql.connector.errors.InternalError'>, (1213, '1213 (40001): Deadlock found when trying to get lock; try restarting transaction', u'40001'))

tbl_a有一个自增字段id(PRI,auto_increment),在python脚本中通过线程池并发执行insert into语句

insert into tbl_a (name) select name from tbl_b where name = '%s';

发生死锁错误:
(1213, ‘1213 (40001): Deadlock found when trying to get lock; try restarting transaction’, u’40001’))

原理

AUTO-INC

MySQL对于自增字段有一种锁机制:AUTO-INC Locking,从MySQL用户手册可以看到:

InnoDB uses a special lock called the table-level AUTO-INC lock for inserts into tables with AUTO_INCREMENT columns. This lock is normally held to the end of the statement (not to the end of the transaction), to ensure that auto-increment numbers are assigned in a predictable and repeatable order for a given sequence of INSERT statements

对于自增字段的插入会触发表级的AUTO-INC锁,这个锁作用于语句的而不是事务(即语句执行完了锁就会被释放)。使用这种锁是为了确保自增列的值的可预见性和可重复性。可预见性是说当一条insert语句作用于多行时,这些行的自增列基于第一行来说是可预见的;可重复执行是指基于语句的复制在slave重放时自增列的值与master的一致。
带自增字段的表插入在并发数大于208以上可能出现很多死锁

innodb_autoinc_lock_mode

在5.1.22版本之后,MySQL InnoDB存储引擎提供了一种轻量级互斥量的自增长实现机制,这种机制大大提高了自增长值插入的性能。参数innodb_autoinc_lock_mode,用于控制向有auto_increment 列的表插入数据时相关锁的行为,实现性能与安全(主从的数据一致性)的平衡。

  • 先对自增长字段的插入进行分类,如下:

    • insert-like:指所有的插入语句,如insert,replace,insert—select,replace—select,load data等。
    • simple insert:指能在插入之前就确定插入行数的语句。这些语句包含insert、replace等,需要注意的是:simple inserts不包含insert—on duplicater key update这类SQL语句,例如insert into t(name) values(‘test’)。
    • bulk inserts:指在插入之前不能确定得到插入行数的语句,如insert—select,replace–select,load data。
    • mixed-mode inserts:指插入中有一部分的值是自增长的,有一部分是确定的。例如insert into t(id,name) values(1,‘a’),(null,‘b’),(5,‘c’);
  • innodb_autoinc_lock_mode的取值范围是0, 1, 2,默认值是1:

    • 0(traditonal模式):兼容MySQL5.1.22版本之前的自增长实现方式,即通过表锁的AUTO-INC Locking方式。
    • 1(consecutive连续模式):对于simple inserts,该值会用互斥量去对内存中的计数器进行累加的操作,对于bulk inserts,还是使用传统表锁的AUTO-INC Locking方式。在这种配置下,如果不考虑回滚操作,对于自增长列的增长还是连续的,并且在这种方式下,statement-based方式的replication还是能很好地工作。需要注意的是,如果已经使用AUTO-INC Locking方式去产生自增长的值,而这时需要进行simple inserts的操作时,还是需要等待AUTO-INC Locking的释放。
    • 2(interleaved交错模式):在这个模式下,对于所有的insert-like自增长的产生都是通过互斥量,而不是通过AUTO-INC Locking的方式,显然这时性能最高的方式。然而会带来一定的问题。因为并发插入的存在,在每次插入时,自增长的值可能不是连续的。最重要的是,基于Statment-base replication会出现问题。因此,使用这个模式,任何时候都应该使用row-base replication,这样才能保证最大的并发性能及replication主从数据的一致。
  • innodb_autoinc_lock_mode = 2 不安全,但是在 binlog_format=ROW,transaction-isolation=READ-COMMITTED , innodb_autoinc_lock_mode = 2 是非常安全的。

回顾

查了一下测试环境MySQL参数,innodb_autoinc_lock_mode果然是1。

mysql> show variables like 'innodb_autoinc_lock_mode';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_autoinc_lock_mode | 1     |
+--------------------------+-------+
1 row in set (0.00 sec)

不过因为是脚本工具,仅执行一次,将并发量改成10之后问题消失了。根本的解决方法还是将innodb_autoinc_lock_mode设置为2。

参考

http://www.xuchanggang.cn/archives/1087.html
https://blog.csdn.net/poxiaonie/article/details/72899975
https://www.cnblogs.com/JiangLe/p/6362770.html

MySQL自增字段并发插入导致死锁相关推荐

  1. MySQL 唯一索引,并发插入导致死锁

    一日志 ------------------------ LATEST DETECTED DEADLOCK ------------------------ 2020-07-27 16:28:53 0 ...

  2. mysql自增字段_MySQL自增字段的常用语句

    学习MySQL数据库,MySQL自增字段是最基础的部分之一,下面为您介绍一些MySQL自增字段的常用语句,希望对您学习MySQL自增字段能些许帮助. 1.创建表格时添加: create table t ...

  3. MySQL自增字段不连续的原因和解决方法

    造成自增字段不连续的原因 1)唯一键冲突导致自增字段值不连续 示例1:创建数据表tb_student3,插入导致唯一键冲突的记录后,在插入数据 mysql> CREATE TABLE tb_st ...

  4. 含有自增字段的插入问题

    mysql中含有自增字段数据表插入数据时需注意的问题 2010-02-22  来自:csharpwin.com  字体大小:[大 中 小] 摘要:本文提示一下大家在mysql中含有自增字段数据表插入数 ...

  5. mysql 自增字段、属性

    mysql自增属性 参考文章 https://www.php.cn/mysql-tutorials-489209.html https://blog.csdn.net/qq_41045806/arti ...

  6. mysql插入时间字段为空值_php – 如何在mysql日期类型字段中插入一个空值?

    如何在 mysql日期类型字段(NULL = yes)中插入NULL或空值. 如果我尝试插入一个空值,它会插入0000-00-00,但是我想保持为空或为空. 感谢帮助. UPDATE 请看我已经将默认 ...

  7. MySQL 唯一索引 UNIQUE KEY 会导致死锁?

    唯一性索引unique影响: 唯一性索引表创建: DROP TABLE IF EXISTS `sc`; CREATE TABLE `sc` (`id` int(11) NOT NULL AUTO_IN ...

  8. mysql自增字段不连续_MySQL中自增主键不连续之解决方案。(20131109)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 今天只做了一件事情,但解决了很大的问题.相信这也是令很多程序员和数据库管理员头疼的事情. 假设在一MySQL数据表中,自增的字段为id,唯一字段为abc, ...

  9. python自增_python mysql自增字段AUTO_INCREMENT值的修改方式

    在之前得文章中我们说过,如果使用delete对数据库中得表进行删除,那么只是把记录删除掉,并且id的值还会保持上次的状态. 即删除之前如果有四条数据,删除之后,再添加新的数据,id怎会从5开始. 但是 ...

最新文章

  1. RxJava 解除订阅---------Disposable.dispose()方法
  2. python【Opencv计算机视觉库】opencv模块cv2常用函数用法(全)
  3. Spark2.0流式处理读Kafka并写ES
  4. FreeBSD长模式不兼容
  5. C语言版数据结构及算法_快速排序
  6. java开发汉字显示不全_求java转码ISO-8859-1转UTF-8汉字显示不全补救方案?
  7. alter procedure是什么意思_板上钉钉的意思
  8. Select prototyping tools
  9. Android 意图(Intent) 理论详解
  10. UML Use Case之间的各种关系
  11. java什么是耦合_在JAVA编程中什么叫耦合?
  12. 【Database】人脸数据库介绍及下载链接
  13. 简单计算机面试题库及答案_计算机面试常问问题及答案
  14. windows 安装 win32 win32com模块
  15. 荣耀V8鸿蒙系统刷机包,华为荣耀V8原版rom系统刷机包_荣耀V8最新版升级包更新下载...
  16. python 切割立方体,python绘制立方体的方法
  17. 深信服 SANGFOR 设备密码恢复和配置备份恢复
  18. uva live 4043 km
  19. PHP——四舍五入取整、向上取整、向下取整、小数截取
  20. 2.OrientDB连接操作

热门文章

  1. python中的rstrip函数_Python strip() lstrip() rstrip() 函数 去除空格
  2. vs为什么打了断点不断_为什么西餐厅里的牛排又嫩又多汁?原来大厨都做了“这一步”...
  3. java方法criterion_java – JPA Criteria谓词条件
  4. 14_pytorch.where,pytorch.gather
  5. 01_Weblogic课程之概念篇:代理服务器,web服务器,应用程序服务器,JNDI概念,JTA概念,Java消息服务,Java验证和授权(JAAS),Java管理扩展,Web客户机,客户机应用程序
  6. System.getProperty()的用途
  7. C++中 auto自动变量,命名空间,using作用以及作用域
  8. Struts result param详细设置
  9. Oracle单行函数
  10. 找二叉树中给定元素的的左孩子结点_LeetCode高频题:二叉树(五)