searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

一次mysqld重启core问题分析

2024-11-08 09:21:30
4
0
  • 现象
 
业务在执行Update 表时,mysqld异常重启,但mysqld重启一直不成功,不断产生core 文件.
 
  • 分析
首先从core文件定位具体发生的场景, gdb 查看core 堆栈信息如下:
 
 
 
对照源码分析,这个逻辑是在mysql启动执行事务回滚的线程中,执行undo 的回滚,对应core的代码如下:
 
通过代码判断可能是table指针为空,查看堆栈验证 ,确实为空值.仔细分析代码的整个执行流程,未能发现给table 赋值的地方,初步怀疑是在重启回滚的流程中完全缺失给table赋值。
 
 
查看代码历史提交记录,发现官方已经有针对table 为空的修复commit 。
该commit id为:
f298f8922c8acced88ebe0a48c662dfeb88bb746
 
Bug#31391126 : ROLLBACK AN UPDATE AFTER INSTANT DDL CAUSE CRASH Mayank Prasad on 6/18/2020, 1:16:54 PM Background: After first INSTANT columns is added to table, for any new row, there is 1 (or 2) extra byte added in record header to keep number of fields present in the row. NOTE : This won't affect the existing rows. ...
该commit修改了两个关键的地方:
row0upd.h : upd_t的 is_modified 成员函数增加了table为空的判断
 
 
tre0rec.cc :trx_undo_update_rec_get_update 函数增加 table 的赋值
 
 
该bug触发的条件:
重启恢复过程,出现事务回滚,同时行数据有需要ext 页存储\的场景才会进入 is_modified的判断中(如blog,text ,json 等等类型),具体代码逻辑详见: dtuple_convert_big_rec 函数 ,此时触发bug. 我们遇到的场景就是存在text 字段的更新(h_article.content) .
 
 
正常回滚没有出现问题? 
table 为空是比较严重问题,为啥这个bug没有大规模出现?而仅在重启恢复过程发现?
通过代码分析可以发现,在已经正常运行的mysqld 回滚流程中,undo 记录是有对table 赋值的,因此不会影响运行中进程正常的事务回滚。
 
 
 
  • 总结
该bug 是由于没有给Table指针赋值导致 重启回滚事务失败,已在官方的commit 中做了fix. 更新的版本是8.0.22 .
 
0条评论
作者已关闭评论
tbLu
7文章数
0粉丝数
tbLu
7 文章 | 0 粉丝
原创

一次mysqld重启core问题分析

2024-11-08 09:21:30
4
0
  • 现象
 
业务在执行Update 表时,mysqld异常重启,但mysqld重启一直不成功,不断产生core 文件.
 
  • 分析
首先从core文件定位具体发生的场景, gdb 查看core 堆栈信息如下:
 
 
 
对照源码分析,这个逻辑是在mysql启动执行事务回滚的线程中,执行undo 的回滚,对应core的代码如下:
 
通过代码判断可能是table指针为空,查看堆栈验证 ,确实为空值.仔细分析代码的整个执行流程,未能发现给table 赋值的地方,初步怀疑是在重启回滚的流程中完全缺失给table赋值。
 
 
查看代码历史提交记录,发现官方已经有针对table 为空的修复commit 。
该commit id为:
f298f8922c8acced88ebe0a48c662dfeb88bb746
 
Bug#31391126 : ROLLBACK AN UPDATE AFTER INSTANT DDL CAUSE CRASH Mayank Prasad on 6/18/2020, 1:16:54 PM Background: After first INSTANT columns is added to table, for any new row, there is 1 (or 2) extra byte added in record header to keep number of fields present in the row. NOTE : This won't affect the existing rows. ...
该commit修改了两个关键的地方:
row0upd.h : upd_t的 is_modified 成员函数增加了table为空的判断
 
 
tre0rec.cc :trx_undo_update_rec_get_update 函数增加 table 的赋值
 
 
该bug触发的条件:
重启恢复过程,出现事务回滚,同时行数据有需要ext 页存储\的场景才会进入 is_modified的判断中(如blog,text ,json 等等类型),具体代码逻辑详见: dtuple_convert_big_rec 函数 ,此时触发bug. 我们遇到的场景就是存在text 字段的更新(h_article.content) .
 
 
正常回滚没有出现问题? 
table 为空是比较严重问题,为啥这个bug没有大规模出现?而仅在重启恢复过程发现?
通过代码分析可以发现,在已经正常运行的mysqld 回滚流程中,undo 记录是有对table 赋值的,因此不会影响运行中进程正常的事务回滚。
 
 
 
  • 总结
该bug 是由于没有给Table指针赋值导致 重启回滚事务失败,已在官方的commit 中做了fix. 更新的版本是8.0.22 .
 
文章来自个人专栏
皮皮鲁的专栏
7 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0