1. 本际云推荐 - 专业推荐VPS、服务器,IDC点评首页
  2. 云主机运维
  3. VPS运维

记一次死锁解析

介绍

你好,我是本际云服务器推荐网的小编小本本。在MySQLDBA和开发工作过程中,死锁问题是一个比较常见的并发系统问题,会出现在数据库系统的并发读写请求场景中。今天我要分享一个RR(REPEATABLE-READ)隔离级别下由于GAP锁导致的死锁案例。

记一次死锁解析

死锁案例分析

当发现死锁发生时,首先查看数据库隔离级别为默认的RR(REPEATABLE-READ)模式。然后再查看innodb存储引擎日志可以看到最近一次死锁的相关信息。

从日志中可以看出死锁发生在表T_ORDERBILL_TASK上而且是两条相同类型的针对表T_ORDERBILL_TASK插入的insert语句!

检查T_ORDERBILL_TASK表结构可见ORG_CODE上有二级索引。

经过查阅业务开发提供的该模块儿的业务逻辑和发生死锁时间上下文业务日志可整理出事务1和事务2的执行顺序为:

  • 事务1:select … for update;
  • 事务1:insert;
  • 事务2:select … for update;
  • 事务2:insert;

由此可知:当session1执行select…forupdate当前读,由于ORG_CODE=110026的数据不存在,因此会加上gap锁(110019,110036)。Session2执行select…forupdate当前读,同样也会加上gap锁(110019,110036),由于gap锁不互斥,所以该语句也可成功执行。但是到第三步时无论是session1先插入还是session2先插入都会等待对方的gap锁,第四步时后插入的也会被对方的gap锁阻塞。两个session进入互相等待状态形成死锁,最后死锁检测将session2回滚。

结论

GAP锁,就是RR隔离级别相对于RC隔离级别不会出现幻读的关键。在RR隔离级别下,条件列上为非唯一索引时,当前读通过条件列未定位到满足条件的记录时会加GAP锁,保证后续的insert不能插入相同值的数据,以防止出现幻读。需要注意的是GAP锁并不互斥但是和插入意向锁互斥。相同语句的情况下RR模式由于会加GAP锁可能锁住更多的数据,虽然防止了幻读,但是会影响一定的并发。在配置RC和RR隔离级别的时候一定要根据业务场景进行选择。

更多精彩干货分享,请点击下方名片关注IT那活儿。

原创文章,作者:小编小本本,如若转载,请注明出处:https://www.benjiyun.com/yunzhujiyunwei/vps-yunwei/6152.html