前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >故障分析 | 一则 INSERT UPDATE 触发 MySQL Crash 的案例

故障分析 | 一则 INSERT UPDATE 触发 MySQL Crash 的案例

作者头像
爱可生开源社区
发布2024-04-30 16:41:13
1090
发布2024-04-30 16:41:13
举报
作者:朱鹏举,初级 DBA,擅长 MySQL,了解 Redis、Oracle。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 700 字,预计阅读需要 2 分钟。

1故障现象

某业务 MySQL 实例(MySQL 5.7.20 社区版)发生 Crash,现需要对其具体原因进行分析。

代码语言:javascript
复制
/mysql/mysql-5.7.20/bin/mysqld(my_print_stacktrace+0x35)[0xf468f5]
/mysql/mysql-5.7.20/bin/mysqld(handle_fatal_signal+0x4a4)[0x7cd434]
/lib64/libpthread.so.0(+0xf100)[0x7f3564112100]
/mysql/mysql-5.7.20/bin/mysqld(_ZN10Field_blob15copy_blob_valueEP11st_mem_root+0x30)[0x7fd160]
/mysql/mysql-5.7.20/bin/mysqld(_Z25mysql_prepare_blob_valuesP3THDR4List14ItemEP11st_mem_root+0x29e)[0xe9901e]
/mysql/mysql-5.7.20/bin/mysqld(_Z12write_recordP3THDP5TABLEP9COPY_INFOS4_+0x212)[0xe995f2]
/mysql/mysql-5.7.20/bin/mysqld(_ZN14Sql_cmd_insert12mysql_insertEP3THDP10TABLE_LIST+0x812)[0xe9a982]
/mysql/mysql-5.7.20/bin/mysqld(_ZN14Sql_cmd_insert7executeEP3THD+0xce)[0xe9b15e]
/mysql/mysql-5.7.20/bin/mysqld(_Z21mysql_execute_commandP3THDb+0xd82)[0xd13b62]
/mysql/mysql-5.7.20/bin/mysqld(_Z11mysql_parseP3THD12Parser_state+0x3a5)[0xd18205]
/mysql/mysql-5.7.20/bin/mysqld(_Z16dispatch_commandP3THDPK8COM_DATA19enum_server_command+0x11bf)[0xd1942f]

2故障分析

根据堆栈打印的信息可以得知,当时 Crash 的时间点 MySQL 正在执行 INSERT 操作,且操作涉及 BLOB 数据类型的数据,在源码执行到 copy_blob_value 函数时触发 Crash。

在本地测试环境中安装同版本 MySQL 实例后,使用 gdb 定位代码具体位置。

代码语言:javascript
复制
gdb ./mysqld
(gdb) b *0x7fd160
Breakpoint 1 at 0x7fd160: file /export/home/pb2/build/sh_0-32013917-1545390211.74/mysql-5.7.25/sql/field.cc, line 3053.

https://github.com/mysql/mysql-server/blob/mysql-5.7.25/sql/field.cc 中找到对应行数的源码,在该代码附近没有 BUG 修复记录。

ctrl+f 搜索函数 copy_blob_value,然后点击左边的 ...,之后选择 View git blame,发现有一个 BUG 修复记录。

根据该 BUG 修复记录描述,MySQL 在执行 INSERT ... UPDATE 类型语句时(也就是 INSERT ... ON DUPLICATE ),当 INSERT 操作失败之后(Unique Key 冲突),会执行 UPDATE 操作,而 UPDATE 操作会在 INSERTVALUE() 中找到需要更新的 Old Data。整个流程如下:

  1. 保存 INSERT 中的数据或 UPDATE 后的新数据
  2. INSERT 失败,进入 UPDATE 流程,找到旧数据
  3. COPY 旧数据

可以看到在找到 Old Data 后,新的指针就会指向这个 Data 内存地址,这时 2 个指针同时指向一个内存地址,此处存在 3 种导致 Crash 的情况:

  1. valgrind error:指针 LHS_FIELD 指向的内存已被释放并重新分配以容纳新数据,将导致空指针问题。
  2. Update Bad Data:指针 LHS_FIELD->ptr 指向的内存未被释放但被重用,并且新数据可以放在相同的内存位置,则更新错误的值。
  3. Both:如果新内存分配在与前一个内存相同的位置,则上述两种情况都可能发生。

BUG 链接

https://bugs.mysql.com/bug.php?id=79243

3触发条件

使用 INSERT ... ON DUPLICATE 语句操作 BLOB 数据类型的列。

4处理方法

  • MySQL 5.7.22 修复该 BUG。
  • 不使用 INSERT ... ON DUPLICATE 语句操作 BLOB 数据类型的列。

本文关键字:#MySQL# #BLOB# #BUG#

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-28,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1故障现象
  • 2故障分析
    • BUG 链接
    • 3触发条件
    • 4处理方法
    相关产品与服务
    云数据库 MySQL
    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档


    http://www.vxiaotou.com