MySQL自增字段并发插入导致死锁
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';
原理
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
innodb_autoinc_lock_mode
先对自增长字段的插入进行分类,如下:
- 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。
参考
MySQL自增字段并发插入导致死锁相关推荐
- MySQL 唯一索引,并发插入导致死锁
一日志 ------------------------ LATEST DETECTED DEADLOCK ------------------------ 2020-07-27 16:28:53 0 ...
- mysql自增字段_MySQL自增字段的常用语句
学习MySQL数据库,MySQL自增字段是最基础的部分之一,下面为您介绍一些MySQL自增字段的常用语句,希望对您学习MySQL自增字段能些许帮助. 1.创建表格时添加: create table t ...
- MySQL自增字段不连续的原因和解决方法
造成自增字段不连续的原因 1)唯一键冲突导致自增字段值不连续 示例1:创建数据表tb_student3,插入导致唯一键冲突的记录后,在插入数据 mysql> CREATE TABLE tb_st ...
- 含有自增字段的插入问题
mysql中含有自增字段数据表插入数据时需注意的问题 2010-02-22 来自:csharpwin.com 字体大小:[大 中 小] 摘要:本文提示一下大家在mysql中含有自增字段数据表插入数 ...
- mysql 自增字段、属性
mysql自增属性 参考文章 https://www.php.cn/mysql-tutorials-489209.html https://blog.csdn.net/qq_41045806/arti ...
- mysql插入时间字段为空值_php – 如何在mysql日期类型字段中插入一个空值?
如何在 mysql日期类型字段(NULL = yes)中插入NULL或空值. 如果我尝试插入一个空值,它会插入0000-00-00,但是我想保持为空或为空. 感谢帮助. UPDATE 请看我已经将默认 ...
- MySQL 唯一索引 UNIQUE KEY 会导致死锁?
唯一性索引unique影响: 唯一性索引表创建: DROP TABLE IF EXISTS `sc`; CREATE TABLE `sc` (`id` int(11) NOT NULL AUTO_IN ...
- mysql自增字段不连续_MySQL中自增主键不连续之解决方案。(20131109)
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 今天只做了一件事情,但解决了很大的问题.相信这也是令很多程序员和数据库管理员头疼的事情. 假设在一MySQL数据表中,自增的字段为id,唯一字段为abc, ...
- python自增_python mysql自增字段AUTO_INCREMENT值的修改方式
在之前得文章中我们说过,如果使用delete对数据库中得表进行删除,那么只是把记录删除掉,并且id的值还会保持上次的状态. 即删除之前如果有四条数据,删除之后,再添加新的数据,id怎会从5开始. 但是 ...
最新文章
- RxJava 解除订阅---------Disposable.dispose()方法
- python【Opencv计算机视觉库】opencv模块cv2常用函数用法(全)
- Spark2.0流式处理读Kafka并写ES
- FreeBSD长模式不兼容
- C语言版数据结构及算法_快速排序
- java开发汉字显示不全_求java转码ISO-8859-1转UTF-8汉字显示不全补救方案?
- alter procedure是什么意思_板上钉钉的意思
- Select prototyping tools
- Android 意图(Intent) 理论详解
- UML Use Case之间的各种关系
- java什么是耦合_在JAVA编程中什么叫耦合?
- 【Database】人脸数据库介绍及下载链接
- 简单计算机面试题库及答案_计算机面试常问问题及答案
- windows 安装 win32 win32com模块
- 荣耀V8鸿蒙系统刷机包,华为荣耀V8原版rom系统刷机包_荣耀V8最新版升级包更新下载...
- python 切割立方体,python绘制立方体的方法
- 深信服 SANGFOR 设备密码恢复和配置备份恢复
- uva live 4043 km
- PHP——四舍五入取整、向上取整、向下取整、小数截取
- 2.OrientDB连接操作
热门文章
- python中的rstrip函数_Python strip() lstrip() rstrip() 函数 去除空格
- vs为什么打了断点不断_为什么西餐厅里的牛排又嫩又多汁?原来大厨都做了“这一步”...
- java方法criterion_java – JPA Criteria谓词条件
- 14_pytorch.where,pytorch.gather
- 01_Weblogic课程之概念篇:代理服务器,web服务器,应用程序服务器,JNDI概念,JTA概念,Java消息服务,Java验证和授权(JAAS),Java管理扩展,Web客户机,客户机应用程序
- System.getProperty()的用途
- C++中 auto自动变量,命名空间,using作用以及作用域
- Struts result param详细设置
- Oracle单行函数
- 找二叉树中给定元素的的左孩子结点_LeetCode高频题:二叉树(五)