升级宝典!阿里云RDS MySQL助力MySQL5.7升级到8.0

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介: 2023年10月,社区MySQL5.7停服。阿里云RDS MySQL对MySQL5.7的服务将进行到2024年10月21日,同时,并将通过有效的方案和大量的升级经验,鼓励和助力广大企业和开发者将MySQL5.7升级到MySQL8.0。

1. 前言

2015 年 10 月,Oracle 正式推出 MySQL 5.7,相比 MySQL 5.6,其具备更好的性能、更多的功能、更高的安全性,逐步成为了 MySQL 的首选版本。2018 年, MySQL 8.0 发布,相比 MySQL 5.7 有了进一步的提升 。2023 年 10 月 25 日,社区推出 MySQL 5.7.44,该版本为最后一个 5.7 版本,意味着社区将停止对 MySQL 5.7 的维护,不再进行缺陷的修复和功能的更新,同时社区也鼓励用户将 MySQL 5.7 升级到 MySQL 8.0[1-2]

图 1  MySQL 生命周期

事实上 MySQL 5.7 作为备受信赖的服务版本,现今依然拥有广大的用户群体。据 Shadowserver 数据统计[3],截止至 2022 年 5 月,在 MySQL 的使用者中,约有 47% 的人仍在坚持使用 5.7 作为主要服务版本。在阿里云 RDS MySQL 实例列表中,MySQL 5.7 的使用比例也达到了相近的数量。然而,随着生命周期结束,由于缺乏后续的更新和支持,不再维护的 MySQL 5.7 面临着种种问题,难以满足不断变化的需求。

image.png

图 2  社区MySQL主要服务版本

相对于 MySQL 5.7,MySQL 8.0 中带来了众多强大、实用的特性,如:

表 1  MySQL 8.0 部分新特性

功能

收益

DDL log

解决了 MySQL 5.7 中 DDL 中断的文件残留问题,确保了文件操作的原子性,同时解决了 Server 层和引擎层数据不一致的问题。

Instant DDL

大大缩短 DDL 执行的时长,快速完成表结构的变更,同时消除了 Binlog 复制延迟。

增强 JSON 支持

新增了多个 JSON 相关的函数,同时对 JSON 的内存使用做了优化。

隐藏索引

可设置索引对优化器不可见,避免了潜在的重复删除、重建索引的操作。

克隆插件

免去传统备份恢复 + 主从复制的方式,直接在源实例上授权、克隆,大大提高了可拓展性。


与此同时,阿里云 RDS MySQL 8.0 在社区 MySQL 8.0 的基础上做了深度优化,开发了许多高级特性[4],如 Binlog in Redo 功能通过在事务提交时将 Binlog 内容同步写入到Redo Log中以减少磁盘操作,提高了数据库性能;通用云盘 IO 加速功能通过扩展InnoDB Buffer Pool将一部分数据页和温数据缓存,在无任何成本变化和业务改动的情况下,可以获得实例 IO 性能的大幅度提升;冷热数据分离功能通过将云盘归档数据转存至 OSS 端,大幅降低用户存储成本;RTO 相关优化通过优化 REDO 应用过程和启动路径等,大幅缩短实例启动时间,提升实例的可用性。通过架构的持续演进和内核的不断优化,阿里云 RDS MySQL 相较社区版本拥有更高的稳定性和安全性、更强的性能和更多的功能,为用户提供稳定可靠、简单易用的数据库服务。

更多 RDS MySQL 自研的高级特性可参考阿里云 RDS 官方文档

作为更强大的分支,MySQL 8.0 的维护周期将会更长久,也会逐步解决现有问题。长久来看,无论是个人用户还是企业用户,都应该推动 MySQL 5.7 到 MySQL 8.0 的升级。


2. 升级前的检查

图 3  MySQL 8.0 与 MySQL 5.7 的主要差异

尽管有许多不得不升级的理由,但实际上从 MySQL 5.7 升级到 8.0 并不是一件轻而易举的事情。MySQL 8.0 与 MySQL 5.7 相比有许多跨度很大的变化,包括了数据字典、存储引擎和SQL语法等方面的改动。由于版本间的差异,在升级之前,用户需要充分评估并做好充足的准备工作。

和 MySQL 5.6 升级到 MySQL 5.7 不同,MySQL 5.7 升级到 MySQL 8.0 是通过 inplace upgrade 的方式进行的,直接使用 MySQL 8.0 的二进制文件拉起 5.7 旧实例,升级程序就会自动进行相关的检查和升级。前文所述的升级前的准备工作实际上就是去消除升级程序中无法自动处理的的“不兼容的”变化,主要工作包括[5-9]


  1. MySQL 8.0 中引入了全新的数据字典用于保存数据库中的元信息,Server 层和 InnoDB 层共享一份元数据。8.0 中的 information_schema 中的视图全部源自于数据字典表,和 InnoDB 相关的视图被重命名(INNODB_SYS_XXX 重命名为 INNODB_XXX),若用户的应用依赖于这些视图,需要确保应用上做出对应的修改;在升级前需要确认业务是否依赖于 8.0 中被删除的系统表(如 mysql.proc、mysql.event 等),若存在则需使用新的访问方式去获取所需的数据;此外,对于和 8.0 系统表同名的用户表(如 catalogs、routines 等),需要手动执行 RENAME/DROP TABLE 操作。
  2. 8.0 不再支持的旧的数据类型(如 old style decimals, old style varchar, old style TIME、DATETIME 和 TIMESTAMP 等),问题表需要在升级前通过 REPAIR TABLE 或逻辑导出 + 导入的方式做修复。
  3. 分区表的处理在 8.0 中由 Server 层下沉至引擎层,MySQL Server 不再支持通用分区。 non-native 的分区表在 8.0 中被废弃,因此需要将此类的分区表修改为 native 类型的分区表(如 InnoDB 引擎)或是删除该分区表。
  4. 较老版本的 5.7(version < 5.0.17)的 trigger 不支持 definer 属性,因此在 5.7 实例中可能会存在缺失 definer 的 trigger,这将会导致升级到 8.0 的过程失败,因此需要在升级前重新创建此类 trigger 。
  5. 8.0 中对于外键约束的长度有限制,超长的外键约束会在升级的过程中报错导致失败,因此需要在升级前将问题外键修改为小于 64 字符长度的约束;8.0 之前视图的列名长度上限是 255 字符,而 8.0 对于视图的列名长度的上限是 64 字符,因此需要在升级前将视图的超长列名修改为小于 64 字符长度的列名;8.0 中单个 ENUM 和 SET 列元素的长度不得超过 255 个字符或 1020 个字节,因此需要在升级前超出限制的 ENUM 和 SET 进行修改。
  6. 若 frm 文件和 InnoDB 数据字典表元数据信息不匹配会导致错误,这种情况需要在升级前对数据做逻辑导出和导入;若存在游离的.frm 文件(即不含.ibd 文件仅有.frm 文件),则需要做相应的清理。
  7. 8.0 废弃了部分空间函数,如果生成列中包含了此类被删除的函数(新引入的空间函数以"ST"和"MBR"开头),则需要在升级前对对应的列做修改。
  8. 升级前必须保证 5.7 实例 clean shutdown ,即需要保证升级前没有待应用的 REDO log 和等待回滚的事务。
  9. 8.0 中引入了新的保留字,大多数的保留字禁止作为表名、列名等,因此需要对 5.7 包含 8.0 引入的新保留字的部分做处理。
  10. 使用废弃的 sql_mode 变量内容(如 NO_AUTO_CREATE_USER 等)会导致 8.0 实例无法启动,因此需要在升级前修改 sql_mode 至 8.0 支持的模式。
  11. 较新版本的 8.0 实例(version >= 8.0.13),共享表空间(系统表空间和通用表空间)中不能存在 InnoDB 类型的分区表,因此在升级前需要把共享表空间移动至独立表空间。
  12. 新版本的 8.0 实例不支持GROUP BY...[ASC | DESC]的语法,因此需要在升级前修改/删除包含相应句法的存储过程。
  13. 5.7 中 lower_case_table_names 是一个可修改的值,但在 8.0 中 lower_case_table_names 是一个初始化参数,实例一旦初始化就无法在后续做修改。若在升级时修改修改该参数为 1,需要确保升级前库表名称为小写,避免出现升级错误。

   

     除了上述的准备工作外,版本间存在的驱动、错误码、参数、优化器差异等也需要业务上做适配。对于自建用户,5.7 到 8.0 的大版本升级过程前的准备可以利用 MySQL shell、mysqlcheck 工具和社区的升级检查文档进行检查。关于 5.7 到 8.0 的变化和检查细节可以参考文末的社区文档链接。


3. 为什么升级还是失败了?

尽管社区提供了相应的检查工具和帮助文档去帮助用户做升级前的检查和问题的解决,然而常常会发现升级过程还是失败了,抛出了各式各样的错误,难以从日志信息中去逐一分析升级失败的原因。分析困难的原因包括但不局限于以下几点:

  1. 报错不明确,不同原因导致的错误可能会在日志中记录相同/相似的错误。用户需要花费大量的时间和精力来排查错误的根本原因,增加了升级的困难度。
  2. 报错不完整,当问题出现时,针对性解决后发现重复的问题再次导致失败,原因是升级程序在首次检测到某一类错误时就提前退出了,相同问题无法被一次性全部检测。用户需要进行多次尝试和排查,增加了升级的复杂性和时间成本。
  3. 部分错误只给出错误提示,却没有对应的解法。用户需要自行查找解决方案或向社区寻求帮助,增加了升级过程中的困惑和不确定性。
  4. 部分 5.7 或更老版本存在的问题被修复,但依旧缺少对存量实例的处理。

笔者在解决大版本升级问题中发现,由于版本差异,加上存在更老的 5.x 版本信息残留,大版本升级涉及的问题琐碎繁多,升级失败的根源大多集中在数据字典上。


4. 轻松升级到阿里云 RDS MySQL 8.0

阿里云 RDS MySQL 拥有国内乃至亚洲最大规模的 MySQL 实例,每月有数十个的实例进行 5.7 到 8.0 的大版本升级。在此过程中,我们积累了大量的经验,搭建了完备的预检查逻辑并对多个大版本升级相关 Bug 进行了分析和修复。

笔者所在的阿里云 RDS MySQL 团队所做的 5.7 升级 8.0 的专项治理,旨在提前发现问题、平滑升级过程,提升大版本升级的成功率,让用户拥有更舒适的大版本升级体验,享受到阿里云 RDS MySQL 8.0 提供的高性能和可靠性。此外,RDS 将对 MySQL 各个版本提供更长期的支持[10],给用户留下更长的缓冲期。


表 2 社区 MySQL 和 阿里云 RDS MySQL EOF

数据库大版本

社区发布时间

RDS发布时间

社区生命周期结束时间

RDS停止支持时间

MySQL 8.0

2018年04月19日

2019年05月

预计2026年04月

预计2027年04月19日

MySQL 5.7

2015年10月21日

2016年11月

预计2023年10月25 日

预计2024年10月21日


在自建 MySQL 5.7 升级 8.0 的过程中,除去前期繁复的检查工作外,根据报错信息逐步进行修复的过程可能会持续多次,并且还存在问题难以修复导致无法升级的情况。整个升级过程停机时间长、返工次数多、耗费时间精力。

图 4  自建 MySQL 5.7 和阿里云 RDS MySQL 5.7 升级到 8.0 流程对比


针对线上常见大版本升级失败问题,阿里云 RDS MySQL 内核侧做了修复工作,当用户的实例存在修复覆盖下的问题时,升级过程将不会失败,可实现无感升级;对于内核侧无法直接修复的问题,阿里云 RDS MySQL 管控侧主动进行多项兼容性检测,在实例触发大版本升级动作前提前发现问题并做出提示,用户在无需重复启停的情况下就能够解决大部分问题,同时对于升级失败的节点会自动回滚到升级前的状态,不影响业务。相比自建用户的升级,用户在进行阿里云 RDS MySQL 的大版本升级时,无需复杂的检查、无需反复核查错误日志并逐一解决问题,仅仅需要点击控制台的升级按钮,一切的升级动作都将在后台完成。经过系列的治理,2023 ~ 2024 年阿里云 RDS MySQL 5.7 升级 8.0 的成功率达到了 97.3% 以上。


表 3 阿里云 RDS MySQL 5.7 升级 8.0 的部分治理工作

导致升级失败的问题

治理

是否需要用户进一步干预

Server与InnoDB字段、索引大小写不一致[11]

在升级过程主动检测并修复 Server 层和 InnoDB 的不一致问题,用户无需手动干预即可直接实现升级。

无需用户操作

表、字段、索引和存储过程包含乱码[12]

在升级过程中主动检测并清除无效的乱码信息,用户无需手动检查和处理;在预检查逻辑中定位涉及到数据的乱码信息,并向用户告知错误信息。

需要用户处理有效数据的乱码信息

5.x 老版本临时表残留[13]

在升级过程中主动清除系统表中临时表残留的元信息,解决用户无法升级的问题。

无需用户操作

外键分区表不兼容[14]

在预检查逻辑中定位包含外键和分区表冲突的表信息,方便用户提前处理。

需要用户解决表中外键和分区表的冲突

空间列和 B-tree 索引不兼容[15]

在预检查逻辑中定位包含空间列和 B-tree 索引冲突的表信息,方便用户提前处理。

需要用户解决表中空间列和 B-tree 索引的冲突

外键约束、视图列名、enum/set 长度超限制

在预检查逻辑定位不满足长度要求的外键约束、视图列名和 enum/set 字段,方便用户提前处理

需要用户修改超出限制的长度

包含 discard 表空间

在预检查逻辑定位 discard 的表空间,方便用户提前处理

需要用户导入表空间或删除表信息。

包含待 repair 的表

在预检查逻辑定位 待 repair 的表,方便用户提前处理

需要用户执行 repair 的操作。


案例 1:Server与InnoDB字段、索引大小写不一致导致升级失败

自建 MySQL 升级失败:

[ERROR] [MY-013140] [Server] Comment for table 'test.t4' contains an invalid utf8mb3 character string: '\xF0\x9F\x90'.
[ERROR] [MY-010022] [Server] Failed to Populate DD tables.
[ERROR] [MY-010119] [Server] Aborting

RDS MySQL 自动修正引擎元数据,升级成功:

[Warning] [MY-012071] [InnoDB] Column name case mismatch: From InnoDB: id_c From Server: Id_c, DD will be consistent with Server one.
[Note] [MY-011088] [Server] Data dictionary initializing version '80023'.


案例 2:表、字段、索引和存储过程包含乱码导致升级失败

自建 MySQL 升级失败:

[ERROR] [MY-013140] [Server] Comment for table 'test.t4' contains an invalid utf8mb3 character string: '\xF0\x9F\x90'.
[ERROR] [MY-010022] [Server] Failed to Populate DD tables.
[ERROR] [MY-010119] [Server] Aborting

RDS MySQL 自动清除表、字段和索引注释的乱码,升级成功:

[Warning] [MY-025076] [Server] Clear utf8mb3 character strings: '\xF0\x9F\x90' in comment of table 'test.t4'.
[Note] [MY-011088] [Server] Data dictionary initializing version '80023'.


案例 3:5.x 老版本临时表残留导致升级失败

自建 MySQL 升级失败:

[ERROR] [MY-012216] [InnoDB] Cannot open datafile for read-only: '/tmp/#sql1dc6f_2_0.ibd' OS error: 71
[ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
[ERROR] [MY-010119] [Server] Aborting

RDS MySQL 自动清理残留的元信息,升级成功:

[ERROR] [MY-012216] [InnoDB] Cannot open datafile for read-only: '/tmp/#sql8947_1_0.ibd' OS error: 71
[Warning] [MY-025078] [InnoDB] Skip orphaned tablespace during upgrade, space_id: 7, filepath: /tmp/#sql8947_1_0.ibd.
[Note] [MY-011088] [Server] Data dictionary initializing version '80023'.


当然,阿里云 RDS MySQL 团队并不是完全根解了 MySQL 5.7 升级到 8.0 过程的所有问题,在场景上、方案上都有需要完善之处。当前大版本升级过程为了保证用户实例不受影响,升级过程首先会在源实例的克隆实例上进行,当克隆实例完成升级后再将用户实例做切换,并释放旧版本实例,这个过程难免会有更多的时间和资源的消耗,更好、更快的方案值得探索;当前的治理手段无法覆盖到所有的升级失败场景,无法保证 100%的升级成功率,同时用户行为和升级冲突的情形往往也需要用户介入去做进一步的处理,无法做到完全的全自动升级,进一步降低用户干预占比是需要持续努力的方向。

关于 RDS MySQL 的升级,更多的细节可以参考官方的升级帮助文档[16]


5. 总结

升级前详细的检查、升级中逐步解决引发失败的问题、升级后做好验证和测试工作,这些都是大版本升级必须要关注的问题。大版本升级失败问题的解决不是一蹴而就的,阿里云 RDS MySQL 团队持续在进行相关问题的修复和建设,同时随着 8.0 版本走向稳定,相信大版本升级的问题会逐步收敛,直至完全解决。


6. 参考文档

[1] https://www.mysql.com/support/

[2] https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-44.html

[3] https://www.shadowserver.org/news/over-3-6m-exposed-mysql-servers-on-ipv4-and-ipv6/

[4] https://help.aliyun.com/zh/rds/apsaradb-rds-for-mysql/overview-of-alisql-features

[5] https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html

[6] https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html

[7] https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html

[8] https://dev.mysql.com/blog-archive/upgrading-to-mysql-8-0-here-is-what-you-need-to-know/

[9] https://dev.mysql.com/doc/refman/8.0/en/upgrade-prerequisites.html

[10]https://help.aliyun.com/zh/rds/apsaradb-rds-for-mysql/major-version-lifecycle-description

[11] https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html

[12] https://bugs.mysql.com/bug.php?id=110177

[13] https://bugs.mysql.com/bug.php?id=110722

[14] https://bugs.mysql.com/bug.php?id=111134

[15] https://bugs.mysql.com/bug.php?id=111616

[16] https://help.aliyun.com/zh/rds/apsaradb-rds-for-mysql/upgrade-the-major-engine-version-of-an-apsaradb-rds-for-mysql-instance

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
4月前
|
存储 关系型数据库 MySQL
【免费动手教程上线】阿里云RDS MySQL推出大容量高性能存储:高性能本地盘(最高16TB存储空间)、高性能云盘(最高64TB存储空间)
阿里云RDS MySQL提供高性能本地盘与高性能云盘等存储方案,满足用户大容量、低延迟需求。高性能本地盘单盘最大16TB,IO延时微秒级;高性能云盘兼容ESSD特性,支持IO性能突发、BPE及16K原子写等能力。此外,阿里云还提供免费动手体验教程,帮助用户直观感受云数据库 RDS 存储性能表现。
|
7月前
|
关系型数据库 MySQL 数据库
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
随着数据量增长和业务扩展,单个数据库难以满足需求,需调整为集群模式以实现负载均衡和读写分离。MySQL主从复制是常见的高可用架构,通过binlog日志同步数据,确保主从数据一致性。本文详细介绍MySQL主从复制原理及配置步骤,包括一主二从集群的搭建过程,帮助读者实现稳定可靠的数据库高可用架构。
381 9
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
|
9月前
|
关系型数据库 MySQL Linux
MySQL版本升级(8.0.31->8.0.37)
本次升级将MySQL从8.0.31升级到8.0.37,采用就地升级方式。具体步骤包括:停止MySQL服务、备份数据目录、下载并解压新版本的RPM包,使用`yum update`命令更新已安装的MySQL组件,最后启动MySQL服务并验证版本。整个过程需确保所有相关RPM包一同升级,避免部分包遗漏导致的问题。官方文档提供了详细指导,确保升级顺利进行。
911 16
|
9月前
|
关系型数据库 MySQL Linux
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
当MySQL 8.4启动时报错“io_setup() failed with EAGAIN”时,通常是由于系统AIO资源不足所致。通过增加AIO上下文数量、调整MySQL配置、优化系统资源或升级内核版本,可以有效解决这一问题。上述解决方案详细且实用,能够帮助管理员快速定位并处理此类问题,确保数据库系统的正常运行。
307 9
|
10月前
|
SQL DataWorks 关系型数据库
阿里云 DataWorks 正式支持 SelectDB & Apache Doris 数据源,实现 MySQL 整库实时同步
阿里云数据库 SelectDB 版是阿里云与飞轮科技联合基于 Apache Doris 内核打造的现代化数据仓库,支持大规模实时数据上的极速查询分析。通过实时、统一、弹性、开放的核心能力,能够为企业提供高性价比、简单易用、安全稳定、低成本的实时大数据分析支持。SelectDB 具备世界领先的实时分析能力,能够实现秒级的数据实时导入与同步,在宽表、复杂多表关联、高并发点查等不同场景下,提供超越一众国际知名的同类产品的优秀性能,多次登顶 ClickBench 全球数据库分析性能排行榜。
464 6
|
11月前
|
监控 关系型数据库 MySQL
如何升级MySQL数据库?
【10月更文挑战第16天】如何升级MySQL数据库?
|
4月前
|
关系型数据库 数据库 RDS
【瑶池数据库训练营及解决方案本周精选(探索PolarDB,参与RDS迁移、连接训练营)】(5.30-6.8)
本周精选聚焦数据库迁移训练营、快速连接云数据库RDS训练营及智能多模态搜索解决方案。为用户提供模拟教程与实战演练,学习RDS MySQL实例连接与数据管理技能,助力企业智能化发展。每周解锁数据库实战新场景,抓紧时间,精彩不容错过!
|
5月前
|
存储 关系型数据库 数据挖掘
【瑶池数据库动手活动及话题本周精选(体验ADB、 SelectDB,参与 RDS 迁移训练营)】(4.21-4.27)
本文为 “瑶池数据库动手活动及话题精选” 系列第一期,聚焦 SelectDB 日志分析、AnalyticDB Zero-ETL 集成、RDS 迁移训练营三大实战,设积分、实物等多重奖励,同步开启话题互动。点击链接参与,每周解锁数据库实战新场景。
|
5月前
|
人工智能 运维 关系型数据库

相关产品

  • 云数据库 RDS MySQL 版
  • 云数据库 RDS
  • 推荐镜像

    更多