作者:网易数据库团队

DDB(网易杭研自研的MySQL数据库中间件产品)团队小伙伴发现了一个问题,觉得比较奇怪。于是找到我们,希望解释下。过程中除解释了问题的现象,也通过代码了解了更多的InnoDB DML执行逻辑,还发现了MySQL/InnoDB官方在二级唯一索引冲突检查时加锁行为的反复。本系列打算用三四篇文章来聊聊这个事情。这是第三篇,用实际案例来证明假设。

第二篇链接:

MySQL RC级别下并发insert锁超时问题 - 源码分析


我们举update为例,因为update可以转化为delete+insert,所以也就包含了insert的场景。仍然采用前述的表dt和其中的9条记录。

二级唯一索引场景

我们尝试对id为6的记录做2次update,并在第二次的时候gdb跟踪detail7_1的唯一性约束检查流程。

session1-ddb>begin;
Query OK, 0 rows affected (0.00 sec)session1-ddb>update dt set id = 66 where id = 6;
Query OK, 1 row affected (6 min 3.98 sec)
Rows matched: 1  Changed: 1  Warnings: 0session1-ddb>update dt set id = 666 where id = 66;

第一个update将主键id为6的记录更新为66,按照代码逻辑,由于修改了n_uniq字段,所以会走delete+insert,而detail7_1由于主键id在其n_fields中,所以也需要更新该索引,也是走delete+insert。此时detail7_1就存在2条n_uniq均为('1','6')的记录,第一条应该是heap_no为7,第二条应该heap_no为11。

第二个update将主键id为66及记录更新为666,执行的代码逻辑跟第一次update类似,但在唯一性约束检查时需要分别判断heap_no为7和11的记录,并进一步获取heap_no为8的记录('1','7')。代码执行过程如下:

1、首先会将已经存在的当前记录调用btr_cur_del_mark_set_sec_rec删除掉;

上图确认操作的索引的detail7_1。

进一步确认删除的记录heap_no是11。

2、接下来会插入一条新的记录,在插入前会进行唯一性约束检查;

上图的调用栈最下面的红框表明此update操作进入了insert逻辑。中间红框表明进行的是唯一性约束检查。最上面的框表示当前处理的索引是detail7_1,heap_no为7表示找到的记录是id=6那条最早的记录对应的detail7_1索引记录。执行c让其继续执行:

上图可以发现还是在row_ins_scan_sec_index_for_duplicate中,heap_no为11表示处理的是id=66的那条刚删除的记录对应的detail7_1索引记录。

也就是说我们构造出了二级唯一索引存在2个delete-marked但n_uniq相同(都为('1','6'))的记录。让gdb继续执行:

还是在row_ins_scan_sec_index_for_duplicate中,此时处理的是heap_no为8的记录,对应的索引变为('1','7'),唯一性约束检查可以结束了。让gdb继续:

可以发现,此时已经进入到最后一个普通二级索引detail7_2的处理流程。

从上面构造的场景至少可以说明二级唯一索引存在索引键值相同的多条记录。所以在唯一性约束检查时需要使用while循环不断获取游标中的下一条记录,直到发现索引键值不同的记录,如果该记录被其他事务锁住,那么就会导致当前事务阻塞并引发锁超时。

主键索引场景

该场景我们只需要构造不更新主键id,而是更新二级索引列或普通列,观察是否会进入btr_cur_del_mark_set_clust_rec。所以我们尝试对主键id为4的记录做如下更新:

1、更新二级索引列:

session1-ddb>update dt set coupon_id='2' where id = 4;

在对主键索引调用row_upd_changes_ord_field_binary_func函数判断后,并没有进入delete-marked流程,而是马上操作二级索引了,可以发现detail7_1索引的记录需要更新。

2、更新普通列:

主键索引不需要delete-marked,唯一索引detail7_1也不需要。普通索引detail7_2需要。

上面就是简单的GDB调试证明过程。对于二级唯一索引的证明是充分的,因为只需要有这种场景就行。但对主键索引的证明是不充分的,因为我们并没有举例排除所有可能的场景。


前面3篇文章分析了RC隔离级别下并发insert锁超时问题。细心的同学是否发现在二级唯一索引进行唯一性冲突检查时,加的是next-key共享锁。那么为什么要加共享锁呢,RC下不应该是no gap锁吗?这个问题比较有意思,我们在第四篇来分析。

原文链接:MySQL RC级别下并发insert锁超时问题 - 案例验证

insert时调用本身字段_MySQL RC级别下并发insert锁超时问题 - 案例验证相关推荐

  1. insert时调用本身字段_多线程编程时,7件你必须知道的事情

    您是否曾花费几个小时试图调试多线程应用程序中出现的非确定性问题?如果是这样,那么你一定要阅读这篇文章.如果不是,那么它无论如何都是修改您当前关于C#中的线程挑战的知识的好方法.了解有关线程的一些常见事 ...

  2. insert时调用本身字段_「技术篇」ETL工具Kettle数据对比同步以及Java程序中调用

    作为一个技术栈出身的攻城狮,虽然走上管理之路,但是技术是不能扔下的,时不时的拿起来重温一下,理论与实践相结合... 使用背景: 住建部某区块链共享平台(下游系统)需要自于上游系统的生产库数据,数据量不 ...

  3. insert时调用本身字段_python3调用企业微信api!开发一款属于自己的企业微信

    python3调用企业微信api 最后更新时间:2020/5/11 前段时间,我将企业微信官方提供的python接口代码的部分功能修改成了python3的,并且自己也使用并测试过部分功能: 因为并没有 ...

  4. insert时调用本身字段_java中子类调用父类构造方法注意事项

    protected继承 继承有个特点,就是子类无法访问父类的private字段或者private方法.例如,Student类就无法访问Person类的name和age字段: class Person ...

  5. RR级别下的GAP锁范围

    故不尽知用兵之害者,则不能尽知用兵之利也. ​ 对于索引,给人的第一印象可能是查询性能的提高,再者是更新或插入之后的sort/merge开销以及页分裂问题(聚簇索引也是索引). 还有一些同学说索引对于 ...

  6. mysql索引commit卡死_mysql 5.6 read-committed隔离级别下并发插入唯一索引导致死锁一例...

    今天,某个环境又发生了死锁,如下: *** (1) TRANSACTION: TRANSACTION 735307073, ACTIVE 0 sec inserting mysql tables in ...

  7. mysql 5.6 read-committed隔离级别下并发插入唯一索引导致死锁一例

    今天,某个环境又发生了死锁,如下: *** (1) TRANSACTION: TRANSACTION 735307073, ACTIVE 0 sec inserting mysql tables in ...

  8. 数据库之InnoDB可重复读隔离级别下如何避免幻读

    文章目录 一.先介绍几个概念 1.什么是当前读 2.什么是快照读 3.什么是mvcc 二.RR级别下避免幻读的方法 三.RC级别下测试快照读和当前读 3.1.测试快照读 3.2.测试当前读 四.RR级 ...

  9. InnoDB在RR隔离级别下解决幻读问题

    表象:快照读(非阻塞读)-伪MVCC 内在:next-key锁(行锁+gap锁) 当前读和快照读 当前读:select-lock in share mode(共享锁),select-for updat ...

最新文章

  1. python爬虫实战-python爬虫实战一:分析豆瓣中最新电影的影评
  2. jdbc连接mysql视频_jdbc连接mysql数据库视频
  3. python之实现从ftp下载文件到本地
  4. STL(六)——max_element和min_element
  5. [笔记] SRAM Controller
  6. 用集合return多个值_Laravel + Nestedset 扩展:嵌套集合模型实现无限级分类
  7. github添加ToKen到本地并写入netrc实现自动登录
  8. 20165202 实验一 Java开发环境的熟悉
  9. 如何在NVivo中获得最佳质量的音频和最佳的转录准确性
  10. Java EJB到底是什么?
  11. 微信app用户及市场调研
  12. 计算机开机密码设置要求,电脑开机密码怎么设置,开机密码设置很简单!
  13. 三星a5000刷Android原生,三星 A5000中文Recovery刷机教程
  14. win服务器系统下的软路由,如何用Windows 2000 Server充当软路由
  15. MATLAB编程之PTB:实验流程
  16. 扇贝python编程课 百度云,扇贝编程python课程分享
  17. 数值计算之 插值法(5)分段插值,埃尔米特插值
  18. Web攻防--基础入门--特定漏洞
  19. Winform像菜单一样弹出自定义内容实现示例
  20. 维科精密IPO过会:年营收6.8亿 实控人陈燕来父女为外籍

热门文章

  1. 如何判断当前UI component是运行在IC还是non-IC环境下
  2. SAP CRM WebClient UI on new focus工作原理
  3. SAP CRM产品主数据无法根据产品描述字段进行搜索的原因
  4. Jmeter5.3(windows下)安装过程问题总结
  5. 数据可视化|实验八 实现scatterplot关系图
  6. php 栏目循环,帝国CMS listshowclass循环栏目标签_PHP教程
  7. external libraries里没有maven包_Maven企业实战系列(三):彻底看懂maven的体系结构...
  8. 计算机vfp考试题库二级,XYZ计算机等级考试题库系统(二级VFP)
  9. oracle指定源位置怎么弄,ORACLE Goldengate测试解决源端和目标端表结构字段位置不同的2种实现方法...
  10. 三星 P600 android,顶级硬件S pen笔手写—三星P600_三星 Galaxy Note 10.1 2014 Edition P600_平板电脑市场-中关村在线...