背景
线上发现mysql
数据库报错死锁日志,版本为5.7.25
,默认隔离级别为rr
,具体的错误日志就不贴出来了,原因是有同事使用了insert duplicate key update
语法,进行存在就更新的操作
那么问题来了,应该从哪入手呢
先通过show engine innodb status
看看死锁日志吧,我在这都加上注释了,并且去掉了无关信息
LATEST DETECTED DEADLOCK
------------------------
//死锁发生的时间 utc时间
2020-12-21 12:51:32 0x7f1bc0d79700
//事务1
*** (1) TRANSACTION:
// 事务1的事务编号和运行了时间
TRANSACTION 9181426, ACTIVE 33 sec inserting
//一张表被用到,一张表被锁
mysql tables in use 1, locked 1
//在等3个锁,为什么是三个锁呢 , 锁占用的内存, 两个行被锁
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
//正在等待获取的锁
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
//这里说的是record lock 以及位置内存信息等,关键是后面的 lock_mode X locks gap before rec insert intention waiting 后面会说到
RECORD LOCKS space id 55 page no 4 n bits 112 index orderid of table `db0`.`t_test` trx id 9181426 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 42 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000384; asc ;;
1: len 4; hex 800000d2; asc ;;
//事务2
*** (2) TRANSACTION:
//~~~
TRANSACTION 9181425, ACTIVE 36 sec inserting
//一张表被用到,一张表被锁
mysql tables in use 1, locked 1
//等待四个锁,三行被锁
4 lock struct(s), heap size 1136, 3 row lock(s)
//持有的锁
*** (2) HOLDS THE LOCK(S):
//这里依然说的是record lock 并且说明了具体的位置,重点依然是后面的 lock_mode X locks gap before rec
Record lock
RECORD LOCKS space id 55 page no 4 n bits 112 index orderid of table `db0`.`t_test` trx id 9181425 lock_mode X locks gap before rec
Record lock, heap no 42 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4