线上遇到一起死锁问题,一条DELETE语句与一条UPDATE语句产生了死锁,经过和印风的讨论分析找到原因:DELETE语句通过二级索引删除记录,加锁顺序:二级索引(WHERE使用到二级索引)–>主键索引 –> 所有其它二级索引,UPDATE语句的加锁顺序:二级索引(WHERE条件使用二级索引)–>主键索引 –>包含更新字段的其它二级索引,由于DELETE操作更新了UPDATE语句WHERE条件使用到的索引,这导致DELETE与UPDATE加锁顺序相反,导致死锁
为了进一步研究InnoDB update操作加锁流程,进行了下列实验(update操作为inplace-update),关于mysql update的上层调用可以参考: MySQL update语法SQL解析源码分析 和 Oracle/PostgreSQL UPDATE…RETURNING…在MySQL中的实现
[……]