爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 700 字,预计阅读需要 2 分钟。
某业务 MySQL 实例(MySQL 5.7.20 社区版)发生 Crash,现需要对其具体原因进行分析。
根据堆栈打印的信息可以得知,当时 Crash 的时间点 MySQL 正在执行 INSERT 操作,且操作涉及 BLOB 数据类型的数据,在源码执行到 copy_blob_value
函数时触发 Crash。
在本地测试环境中安装同版本 MySQL 实例后,使用 gdb 定位代码具体位置。
在 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
操作会在 INSERT
的 VALUE()
中找到需要更新的 Old Data。整个流程如下:
INSERT
中的数据或 UPDATE
后的新数据INSERT
失败,进入 UPDATE
流程,找到旧数据可以看到在找到 Old Data 后,新的指针就会指向这个 Data 内存地址,这时 2 个指针同时指向一个内存地址,此处存在 3 种导致 Crash 的情况:
LHS_FIELD
指向的内存已被释放并重新分配以容纳新数据,将导致空指针问题。LHS_FIELD->ptr
指向的内存未被释放但被重用,并且新数据可以放在相同的内存位置,则更新错误的值。https://bugs.mysql.com/bug.php?id=79243
使用 INSERT ... ON DUPLICATE
语句操作 BLOB 数据类型的列。
INSERT ... ON DUPLICATE
语句操作 BLOB 数据类型的列。本文关键字:#MySQL# #BLOB# #BUG#