一个即将写入MySQL源码的官方bug解决之路
作者:周信静,毕业于浙江大学,目前在CDB/CynosDB数据库内核团队参与TXSQL云数据库内核研发工作,参与了热点行更新以及一系列性能优化工作,并修复了多个MySQL官方bug。
1背景
InnoDB的自适应哈希索引(Adpative Hash Index,以下简称AHI),是一种建立在B树索引结构上的索引结构,目的是为了进一步降低BTree的查询代价。
在B树中搜索一个记录时,需要从根节点下降到叶子结点,同时在每个节点中还需要使用二分查找定位。而AHI对此的改进在于它对BTree索引频繁访问的叶子的行记录建立哈希索引,这样在执行B树查询时,通过AHI就可能能定位到叶子结点上的记录位置,避免B树根节点到叶子结点的下降过程,减少了CPU开销。
由于AHI的构建是一个自适应且动态的过程,需要根据查询负载访问模式的变更、页面的换入和淘汰等情况做AHI对应清理或者重建,所以本质上来说AHI也是一个cache,具体的构建逻辑网络上也有很多文章讲解,不是本文讨论的重点。
本文要讨论的是一个鲜为人知的AHI构建锁冲突问题以及相应优化。
2问题
TXSQL 5.7版本在跑sysbench时,我们观察到一个非常有意思的现象。
实验环境是这样的,2台96-core的机器,分别作为sysbench client和mysql server,我们配置buffer pool大小为200GB,同时生成一张120GB的sysbench table。
如下图所示,我们执行128并发的oltp_read_only负载时,观察到QPS首先有一个上升的坡,这段时间我们发现系统有大量的读IO,正在填充buffer pool,属于正常状态。
然后过了100s时突然出现了一个急剧的下降,在400s后开始系统QPS开始缓慢上升,直到800s后达到峰值。
通过perf工具抓取系统在QPS剧降时间点的状态,结果如下图:
分析堆栈,可以发现,大量CPU花费在在AHI的hash table的锁竞争上。
仔细分析不难发现,这个时候大多数页面基本上还没有建立AHI,然后多个线程同时需要对页面建立AHI索引,而这个构建过程需要对同一个AHI hash table加X锁,因此造成了大量等待。
从QPS变化的角度,可以有如下图所示的分析:
3优化
我们注意到,对于一个BTree索引来说,其AHI构建是在BTree叶子结点定位完毕后发生的,对应调用链如下:
btr_cur_search_to_nth_level→ btr_search_info_update→ btr_search_info_update_slow→ btr_search_build_page_hash_index
在btr_search_info_update_slow中,根据统计信息作出决定,调用btr_search_build_page_hash_index把当前页面的记录加入AHI的hash table,这个过程需要独占hash table的X锁。
既然只能有一个线程对hash table进行修改,那么其他并发构建AHI线程等待这个hash table的X锁是相当不明智的,因为这样block住了查询的关键路径,同时只有一个线程在做这个构建工作。
同时我们又注意到AHI只是一个辅助cache,其实用BTree也是能够正确处理查询的。
那么很自然的,我们可以想到如下的优化方式:
1. 当我们在BTree查询路径上经过分析后决定要对某一页构建AHI索引时,我们首先看一下该BTree所对应的hash table的锁是否被其他线程拿住了写锁;
2. 如果被拿住了写锁,我们取消这次针对页的AHI索引构建任务,等待下次再次访问到该页时再尝试去构建,fallback到普通的BTree查询。
4具体实现
从实现角度来说,其实非常简单:在btr_search_info_update_slow根据统计信息判断要对一页的记录建立AHI索引时,我们加入一个条件判断:如果当前有并发AHI构建线程拿住了hash table的X锁,我们直接返回即可。
代码只有几行,大致如下:
有人可能会担心这样直接跳过会不会影响代码正确性?
答案是否定的,因为我们这里没有清除该页面关于AHI的任何统计信息,只是推迟了构建时机,即推迟到hash table锁冲突不严重的时候再进行。
5效果
应用上述的优化后,我们重新执行上述实验,得到如下的结果图:
其中,红线(开启AHI+Contention Avoidance优化)是我们实现上述优化后结果,经过100s左右的预热后,性能稳定,锁瓶颈消失。
6灵感来源
其实在原始的AHI查询路径上已经有一个类似的优化了:
在btr_cur_search_to_nth_level中执行AHI查询前,如果发现AHI的hash table被其他线程X锁住了,直接fallback到BTree查询。
这里的优化考量是类似的:与其等待AHI的hash table的X锁,不如直接走btree搜索,代价很可能比等待X锁更低,并发度更高。
7总结
该优化目前已经在TXSQL5.7最新版本中上线,将会有效缓解AHI构建的锁竞争问题,可能的场景包括不限于:系统启动、AHI开关刚开启、主备切换时,所有页面都还没有AHI记录,高并发可能导致大量的AHI构建工作。
同时经过我们验证,在官方MySQL的5.7和8.0最新版本中都存在该问题,因此我们也已经将这个优化思路贡献给了官方, https://bugs.mysql.com/bug.php?id=100512 ,目前正在评估,相信不久将合入主线。
手机运维小程序限时免费体验!
手机运维小程序——腾讯云数据库上线啦,从此在手机里可以实现实例信息查看,健康报告接收,慢SQL分析和异常查看等功能,以后回家终于可以不背电脑了!
上云就上腾讯云,双十一全网年度最低价来袭:MySQL高可用版1C2G低至99元/年!更有价值11000元代金券大礼包等你来领取,玩法简单直接,错过又要等一年!
↓↓点击直达双11会场~
【腾讯程序员视频号交流沙龙活动预告】
11月21日周六下午2点 深圳
想参与可添加微信:journeylife1900
(备注:视频号)
一个即将写入MySQL源码的官方bug解决之路相关推荐
- 转 MySQL源码分析
看到一个不错的介绍,原址如下: http://software.intel.com/zh-cn/blogs/2010/08/20/mysql0/ MySQL源码分析(0):编译安装及调试 作者: Yu ...
- MySQL源码bug#65995
之前博客<mysql源码中的bug>中描述了在调试源码时的一个bug,已经被MySQL官方确认,感兴趣的可以进行查看.尤其是有源码癖的朋友,在调试过程中可以进行参考. MySQL官方bug ...
- Linux安装MySQL(源码安装)
文章目录 一.下载 二.最小化安装配置 三.MySQL的安装的几种方式 1.MySQL安装方式 2. 三种安装方式的区别 四.MySQL的GLIBC版本安装 1. 上传软件包解压 2. 软件安装 3. ...
- MySQL 源码 需要 什么基础_MySQL 基础之 源码 部署
源码部署 1. 需要先卸载一些软件 centos7 中需要先卸载 mariadb-libs 软件包 # rpm -e --nodeps mariadb-libs 2. 安装依赖包 yum -y ins ...
- 怒肝两个月MySQL源码,我总结出这篇2W字的MySQL协议详解(超硬核干货)!!
写在前面 最近,在开发一个分库分表中间件,由于功能需求,需要分析MySQL协议,发现网上对于MySQL协议分析的文章大部分都过时了,原因是分析的MySQL版本太低了.怎么办呢?于是乎,我便硬着头皮开始 ...
- mysql输入错误怎样更正_HotDB MySQL 篇| MySQL 源码系列的补充与更正
热璞数据库HotDB 产品是基于Mysql 的分布式事务数据库,在上一part的分享中,我们讲到了MySQL源码系类中的2个问题: 1.trigger的event到底怎么回放的,为什么没有主键冲突? ...
- mysql long类型_怒肝两个月MySQL源码,我总结出这篇2W字的MySQL协议详解(超硬核干货)!!...
点击上方蓝色"冰河技术",关注并选择"设为星标" 持之以恒,贵在坚持,每天进步一点点! 作者个人研发的在高并发场景下,提供的简单.稳定.可扩展的延迟消息队列框架 ...
- 怎么查看MySQL 源码编译了什么_Mysql 源码编译教程贴
题外话:这是一篇教程贴,不仅学的是mysql的编译,还是一些编译的知识.我也是一个菜鸟,写一些感悟和心得,有什么问题可以批评指正,谢谢! 如果只是为了安装请移到我的另一篇安装贴: Mysql安装贴 环 ...
- Mysql源码编译和调试debug
下载源码 直接从github 上下载了源码.git 地址:https://github.com/mysql/mysql-server 下载路径如:/work/mysql-server 编译 依赖 ma ...
最新文章
- php页面最大执行时间 set_time_limit函数不起作用
- java流实例_java流汇总以及使用实例
- Element UI格式化日期
- python finally语句里面出现异常_Python异常处理中的else和finally
- 【并发技术16】线程同步工具Exchanger的使用
- 实用收藏Linux命令备忘
- Ubuntu系统下允许Apache的mod_rewrite功能
- 一文看懂 BDTC 2018:探秘大数据新应用(附 PPT 下载)
- 北京信息科技大学计算机专业学科评估,北京信息科技大学学科评估结果排名(第四次):最新完整...
- 【每日算法Day 62】LeetCode 815. 公交路线
- 连接mongoDB根据ObjectID写入json数据(初步)
- Atitit 知识体系概论 attilax著 三大类型 学术型 应用型 职业技术教育	1 附表1、CIP-2000学科群设置情况总表	1 三大层次 分类 学科 专业	2 20个知识大类	2 需
- 微信小程序开发学习资料
- 51单片机定时器实现钟表(LCD1602显示)
- php掷骰子小游戏代码,C语言实现掷骰子游戏代码及解析
- 利用群发短信进行精准高效的会员营销
- HDU 5811 (拓扑排序 LIS)
- SSL: CERTIFICATE_VERIFY_FAILED
- 北京理工大学ACM冬季培训课程之C++的应用
- linux切换用户时 su-,Linux切换用户(su)