暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

MySQL8.0.29出现重大bug,现已下架

简述

请勿使用 MySQL8.0.29,官方已经把这个版本下架了,这种下架小版本安装包的做法实属罕见,可能是 MySQL 史上第一次遇到。官方给出的理由如下:

This release is no longer available for download. It was removed due to a critical issue that could cause data in InnoDB tables having added columns to be interpreted incorrectly. Please upgrade to MySQL 8.0.30 instead.

潜台词: 8.0.30 Fix 了

我初次发现这个问题

初次发现这个问题,在 2022-07-29,我看到 percona 博客的这篇文章,当时就觉得问题很严重,并把我的发现转发到朋友圈了。只是没想到问题已经严重到官方要把版本直接下架以减少用户影响了。
https://www.percona.com/blog/percona-xtrabackup-8-0-29-and-instant-add-drop-columns/

这个 Bug 产生的原因是,Oracle 官方的 MySQL8.0.29 版本扩展了对 ALTER TABLE ... ALGORITHM=INSTANT
的支持:

  1. 允许用户立即在表的任何位置添加列 (原本INSTANT 算法只支持添加最后一列)
  2. 支持立即删除列。(原本 INSTANT 算法只支持 add column,不支持 drop column)

为了实现上面的扩展,服务器上所有 DML 操作的 redo log 格式有修改。这种新的 redo log 格式引入了一个设计缺陷,该缺陷可能导致 INSTANT ADD/DROP COLUMNS 过的表数据损坏。(加粗这四个字够严重了吧。。)

我们知道 Xtrabackup 是基于 InnoDB 的崩溃恢复功能来做一致性备份的。他首先直接复制 InnoDB 数据文件,导致内部不一致的数据, 但随后它对文件执行崩溃恢复,使它们再次成为一致、可用的数据库。

所以,Percona 的这篇文章主要讲的是为了应对这个 bug,首先他们在 Percona Server 上修复了这个 Bug,然后赶紧给 Oracle 官方提交了修复代码补丁,然后接着修改 Xtrabackup 源码,新版 Xtrabackup8.0.29 检查到数据库有 INSTANT ADD/DROP COLUMNS 过的表则备份不工作!因为备份出来那份备份必然是损坏的!

Bug的细节是什么?

Percona 的这篇文章主要讲的是这个 Bug 影响了他们 Xtrabackup 的行为,但 Bug 的细节是什么?最简单的办法就是看 Oracle 官方 Bug report 网站 https://bugs.mysql.com/

可惜的是,我无论用什么关键字,搜索不到相关 Bug。

我们看 8.0.30 的 release note 可以发现这个 bug 已经修复,修复内容:

InnoDB: After upgrading to MySQL 8.0.29, a failure occurred when attempting to access a table with an instantly added column. (Bug #34233264)

这个 Bug 是长编号,意味着这是一个内部 Bug,如果这个 Bug 有外部客户发现,也会有对应的短 Bug 号,但我的理解, Oracle 有可能会因为这个 Bug 过于重大而把外部 Bug 直接关闭了,也或者官方内部也发现了这个 Bug,属于重复 Bug 了,而关闭外部 Bug 编号。

那么我们就不知道这个 Bug 的细节了吗?

所幸的是,前面我们提到,这个 Bug 实际上是由 Percona 官方首次发现并提供补丁修复,所以 Bug 的内容我们是能从 Percona 的 jira 找到。
https://jira.percona.com/browse/PS-8292

这里有显示 MySQL 官方的短编号 Bug 链接,也就是这个 Bug 外部用户也发现了,正如我说的,官方因为 Bug 太重大关闭了,成为内部才能看的内部 Bug 了。
https://bugs.mysql.com/bug.php?id=107611
(如图,短 Bug 编号链接已无权访问)

以下两个链接是相同的 Bug,也被关闭了。
https://bugs.mysql.com/bug.php?id=107458
https://bugs.mysql.com/bug.php?id=107459

从 id 来看这个 bug 绝非 percona 第一个发现,所以官方在 percona 之前就知道这个 bug 了。

如何复现这个Bug?

回到刚才我提到的这个链接,https://jira.percona.com/browse/PS-8292

里面有提供大概的模拟步骤,先决条件大概是

  1. 某张表执行过 ALTER INSTANT
  2. 关于这张表的 redo log 尚未 checkpoint
  3. mysqld crash 或 kill -9

除了模拟步骤,我还需要一份 MySQL8.0.29 的安装包,这个官方已无法下载,好消息是我之前下载过了,我可以模拟和复现。另外一个好消息是我太菜了,我复现不了。(没错 ,这个也是个好消息)

这个Bug最早什么时候被人发现的?

最早是今年 5 月 21 日被用户发现,发到官方的论坛里,这个 Bug 对他的影响是 '自从升级到 8.0.29 以来,七天内 300 台 MySQL 有 6 台 innodb 损坏了",我只能说恐怖如斯了。

那么论坛里能获取到复现 Bug 的详细步骤吗?答案是不能!正如我前面说的,官方不会公布重大 Bug 的细节,他们视这些为安全隐患,也许会被有心人士利用,这也是他们关闭外部短 Bug 编号链接的原因。如图(均是谷歌机器翻译) 

https://forums.mysql.com/read.php?22,704532,704968#msg-704968

给官方点赞!

如何规避这个 Bug 的影响?

已经升级到 8.0.29 版本的同学,请检查是否有使用过快速加/删列功能

mysql> SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE TOTAL_ROW_VERSIONS > 0;
+-------------+
|  NAME       |
+-------------+
|  fander/tb1 |
+-------------+
1 rows in set (0.02 sec)

如果这个查询显示一个空的结果集,那么一切都很好。上述显示我有一张表使用过快速加/删列,在备份之前对表列表运行 OPTIMIZE TABLE 可以解决。

mysql> OPTIMIZE TABLE fander.tb1;
+------------+----------+----------+-------------------------------------------------------------------+
| Table      | Op       | Msg_type | Msg_text                                                          |
+------------+----------+----------+-------------------------------------------------------------------+
| fander.tb1 | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| fander.tb1 | optimize | status   | OK                                                                |
+------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (1.03 sec)

mysql> SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE TOTAL_ROW_VERSIONS > 0;
Empty set (0.00 sec)

无论是否有使用过,都应当马上停止使用这个功能,这些功能目前认为还不稳定,立刻安排时间尽快升级到 8.0.30,数据库升级前请用 set global innodb_fast_shutdown=0
 关库后升级。

注意:

  1. 升级小版本前也要注意备份
  2. 永远先升级从库再升级主库
  3. 升级请跳过8.0.29 这个版本(当然了,现在也下载不到了),直升到8.0.30

写在最后

实际上,这个问题的触发除了官方引入的 redo log 设计缺陷外,还要一个触发条件,就是 mysql crash 或者人为地 kill -9 mysqld
。我每次看到kill -9 mysqld
我就想起姜老师那篇文章《如何正确地关闭 MySQL 数据库?99%的 DBA 都是错的!》。Anyway,关注我,不能变成大佬,但能学习到奇怪的知识,躲避坑,至少 kill -9
不用跑路了。


最后修改时间:2023-05-26 16:27:31
文章转载自芬达的数据库学习笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论