mysql insert导致死锁的案例介绍
本篇内容介绍了“mysql insert导致死锁的案例介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
两个insert语句发生死锁的案例。
一. 准备数据
CREATETABLE`t1`(`a`int(11)NOTNULL,PRIMARYKEY(`a`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;insertintot1values(1);mysql>insertintot1values(1);QueryOK,1rowaffected(0.20sec)mysql>select*fromt1;+---+|a|+---+|1|+---+1rowinset(0.00sec)
二. 发起如下事务
会话1
会话2
会话3
begin;
delete from t1 where a=1;
begin;
insert into t1 select 1;
begin;
insert into t1 select 1;
Commit
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
简单理解下,删除数据的会话持有X锁,导致两条insert语句需要等待,这没问题,
但是为什么删除提交后,两个竞争关系出现了死锁。
show engine innodb status部分结果:
------------------------LATESTDETECTEDDEADLOCK------------------------2020-05-1713:50:240x7f660c3f0700***(1)TRANSACTION:TRANSACTION4377,ACTIVE13secinsertingmysqltablesinuse1,locked1LOCKWAIT3lockstruct(s),heapsize1136,2rowlock(s)MySQLthreadid3,OSthreadhandle140076399294208,queryid59localhostrootexecutinginsertintot1select1***(1)WAITINGFORTHISLOCKTOBEGRANTED:RECORDLOCKSspaceid99pageno3nbits72indexPRIMARYoftable`ming`.`t1`trxid4377lock_modeXlocksrecbutnotgapwaitingRecordlock,heapno2PHYSICALRECORD:n_fields3;compactformat;infobits320:len4;hex80000001;asc;;1:len6;hex000000001114;asc;;2:len7;hex3400000144129f;asc4D;;***(2)TRANSACTION:TRANSACTION4378,ACTIVE10secinserting,threaddeclaredinsideInnoDB1mysqltablesinuse1,locked13lockstruct(s),heapsize1136,2rowlock(s)MySQLthreadid4,OSthreadhandle140076268848896,queryid61localhostrootexecutinginsertintot1select1***(2)HOLDSTHELOCK(S):RECORDLOCKSspaceid99pageno3nbits72indexPRIMARYoftable`ming`.`t1`trxid4378lockmodeSRecordlock,heapno2PHYSICALRECORD:n_fields3;compactformat;infobits320:len4;hex80000001;asc;;1:len6;hex000000001114;asc;;2:len7;hex3400000144129f;asc4D;;***(2)WAITINGFORTHISLOCKTOBEGRANTED:RECORDLOCKSspaceid99pageno3nbits72indexPRIMARYoftable`ming`.`t1`trxid4378lock_modeXlocksrecbutnotgapwaitingRecordlock,heapno2PHYSICALRECORD:n_fields3;compactformat;infobits320:len4;hex80000001;asc;;1:len6;hex000000001114;asc;;2:len7;hex3400000144129f;asc4D;;***WEROLLBACKTRANSACTION(2)
可以看到会话2正在等待一个X行锁,会话3也在等待X行锁,但是同时持有一个S锁。
这个S锁是怎么来的呢?
当进行唯一性冲突检测时,需要先加一个 S 锁。
那么整个过程就是如下所示
会话1
会话2
会话3
begin;
delete from t1 where a=1;
持有a=1就的X行锁
begin;
insert into t1 select 1;
为了判断唯一性,请求a=1的next-key lock S锁被阻塞,等待
begin;
insert into t1 select 1;
为了判断唯一性,请求a=1的next-key lock S锁被阻塞,等待
Commit
释放a=1上的锁
拿到a=1的next-key lock S锁,继续尝试拿a=1的X 行锁,但是被会话3的S锁阻塞
拿到a=1的next-key lock S锁,继续尝试拿a=1的X 行锁,尝试拿到a=1的X 行锁,但是被会话2的S锁阻塞。
触发死锁
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
“mysql insert导致死锁的案例介绍”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。