MySQL中由load data语句引起死锁的解决案例

2019-01-04 16:51:40王冬梅

1) 插入第一条数据

2) 申请AUTO_INC锁

3) 插入第二条

4) 申请AUTO_INC 锁(因为已经是自己的,直接成功)

5) 。。。。。。插入剩余所有行

6) 释放AUTO_INC锁。

所以这个流程就简单描述为:插入第一行,申请AUTO_INC锁,然后插入剩下的所有行后再释放。

我们前面提到过,插入第一条数据时可能需要访问的记录锁,是要等到整个事务结束后才释放的.

有了上面的这些背景知识,我们来复现一下死锁出现的过程

2016122171638180.png (580×207)

可以看到触发条件还是比较苛刻的,尤其是session2要刚好要用到session1锁住的那个记录锁。需要说明,由于InnoDB内部对记录的表示,同一个记录锁并不表示主键值一定相同。

8、解决方案1:去掉不必要的AUTO_INCREMENT字段

在这个业务中,由于所有的数据都是通过LOAD DATA进去,而且都已经指定了自增字段的值,因此这个AUTO)INCREMENT属性是不需要的。

少了一个,就死锁不了了。

9、解决方案2:强制模式1

前面我们说到innodb_autoinc_lock_mode这个参数的可选值有0、1、2。当设置为1的时候,在LOAD DATA语句会退化为模式0。但若设置为2,则无论如何都会使用模式1。

我们前面说到使用模式1会导致LOAD DATA生成的自增id值不连续,这样会导致在binlog_format是1时主从不一致,因此设置为2的前提,是binlog_format 是row.

在binlog_format='row'时,设置innodb_autoinc_lock_mode为2是安全的。

若允许,方案2比方案1更轻量些,不需要修改数据和表结构。

您可能感兴趣的文章:

Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQLMySQL中使用load data命令实现数据导入的方法mysql中Load Data记录换行问题的解决方法mysql load data infile 的用法(40w数据 用了3-5秒导进mysql)mysql中的Load data的使用方法mysql 的load data infilemysql Load Data InFile 的用法mysql遇到load data导入文件数据出现1290错误的解决方案