一 现象
数据库运维平台执行DDL操作导致了死锁问题
二 死锁日志关键点
1 事务包含语句 replace into (更新操作)
2 事务等待锁 lock mode AUTO-INC waiting
三 过程执行语句
1 pt-osc INSERT LOW_PRIORITY IGNORE INTO
持有 AUTO-INC 锁 申请 主键行锁(x)
2 触发器 replace into
持有 主键行锁(x) 等待 auto-inc锁
可以发现 互相等待形成死锁
四 分析
1 replace into 加锁方式
会对主键相关记录加X锁,针对冲突的记录,会执行delete+insert操作.后续申请auto-inc锁
2 insert into 加锁方式
1 申请 auto-inc(表级锁) 加锁 2 释放auto-inc加锁 3 获取 INSERT INTENTION LOCK(插入意向锁) 4 存在冲突,针对冲突主键添加S锁,最后针对行获取X锁
四 解决方法
1 设置pt-osc的chunk-size为更小的值 可以减少死锁的发生,但是不可能避免死锁的发生。
2 innodb_autoinc_lock_mode的值为2
3 mysql版本为8.0.18以上版本
4 其本质还是由于触发器的replace into语句导致的