ITPub博客

首页 > 数据库 > MySQL > sysbench花式踩坑之三:自增值导致的锁等待

sysbench花式踩坑之三:自增值导致的锁等待

原创 MySQL 作者:沃趣科技 时间:2019-02-21 16:57:18 1 删除 编辑

上篇文章 《sysbench花式采坑之二:自增值导致的主键冲突》 遗留了一个问题,为什么在RR级别下delete一条id不存在的列,再在另一个事务用同样的id插入一条数据会发生锁等待,在RC级别下就不会出现锁等待?

| 自增值导致的锁等待

看到RR级别和RC级别下不同的锁等待表现,第一个应该想到的原因就是gap锁。

我们知道gap锁会阻塞insert,那么delete会产生gap锁吗?借用mysql 8.0新加入的performance_schema.data_locks观察一下。

首先准备测试所用的表结构和表数据。  

id为主键列,age为索引列,首先我们删除id为12的这条数据,观察一下锁信息。

可以看到delete产生了一个意向排它表锁和一个排它行锁。

回滚这个事务,然后我们删除一条id不存在的数据,观察一下锁信息。

发现行锁变成了gap锁,这时候我们往锁住的范围里面做insert操作都是会等待的。 

这时通过performance_schema.data_locks查看锁信息

  • 事务1 

  • 事务2  

  • 锁信息 

发现表中显示的insert的事务有一条GAP锁正在等待delete的GAP锁。

这里竟然是GAP锁等待GAP锁,前面也验证了,两条对同一个不存在的id进行delete的语句相互之间不会冲突,也就是说delete产生的GAP锁不会阻塞delete产生的GAP锁。

  • 事务1 

  • 事务2 

  • 锁信息

可以看到,上述两个锁信息的图中除了第一张的lock status为waiting外,其他内容完全相同,这么看来performance_schema.data_locks里面记录的信息不是太全面,那我们看一下insert锁等待的时候具体点的锁信息吧。

  • 事务1 

  • 事务2 

  • show engine innodb status\G 

发现insert持有的锁为insert intention lock,那么这个insert intention lock为什么在performance_schema.data_locks显示为GAP呢,看一下官方文档insert intention lock的解释。 

第一句就表明了insert intention lock是GAP锁的一种,因此performance_schema.data_locks显示为GAP好像也没什么毛病,只是和两个delete的锁信息对比起来就比较容易让人困扰了,再上图仔细感受一下:  

| 总结

  • 对不存在的行以id为where条件进行delete或者update的时候会产生gap lock;

  • gap lock和gap lock之间互相兼容;

  • insert intention lock是一种特殊的gap lock,当先持有gap lock时,会阻塞后面的insert intention lock;

  • sysbench压测的时候自增值要设置为1,否则对数据的间隙进行dml的时候存在很多问题。


| 作者简介

李文航·沃趣科技数据库技术专家

熟悉MySQL体系结构和工作原理、SQL调优、数据库故障诊断、数据迁移、备份恢复

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28218939/viewspace-2636609/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
杭州沃趣科技股份有限公司创建于2012年(股票代码:839849),是一家专注为企业用户提供基于高性能、高可用、可扩展的开放数据库云平台解决方案的国产厂商。公司创始团队为原阿里巴巴数据库技术团队核心骨干,凭借丰富的研发及运维经验,为行业客户提供数据库云产品及软硬件一体化解决方案。

注册时间:2016-07-18

  • 博文量
    290
  • 访问量
    994536