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

本文涉及的产品
云数据库 PolarDB MySQL 版,列存表分析加速 8核16GB
RDS Agent(兼容OpenClaw),2核4GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 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;
相关文章
|
9月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1442 152
|
9月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1056 156
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
10月前
|
存储 SQL 关系型数据库
RDS DuckDB技术解析一:当 MySQL遇见列式存储引擎
RDS MySQL DuckDB分析实例以​列式存储与向量化计算​为核心,实现​复杂分析查询性能百倍跃升​,为企业在海量数据规模场景下提供​实时分析能力​,加速企业数据驱动型决策效能。​​
|
9月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
9月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
9月前
|
SQL 关系型数据库 MySQL
阿里云的云数据库RDS简介
阿里云关系型数据库RDS(Relational Database Service)是一种安全稳定、高性价比、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供容灾、备份、恢复、监控、迁移等全套解决方案,帮助用户轻松应对数据库运维挑战。RDS具备高可用性、高安全性、轻量运维和弹性伸缩等优势,适用于各类业务场景,助力企业降低成本、提升效率。
|
9月前
|
关系型数据库 MySQL 数据库
云时代MySQL:RDS与自建数据库的抉择
在云计算时代,选择合适的数据库部署方案至关重要。本文深入对比了AWS RDS与自建MySQL的优劣,帮助您在控制权、运维成本和业务敏捷性之间找到最佳平衡点。内容涵盖核心概念、功能特性、成本模型、安全性、性能优化、高可用方案及迁移策略,为您提供全面的决策参考。
|
10月前
|
关系型数据库 MySQL 程序员
从自建MySQL到阿里云RDS:程序员的数据库减负革命
如果你正在为自建MySQL数据库的高成本运维发愁,为凌晨三点的主从同步故障告警而崩溃,为开发团队频繁索要新测试库的要求感到窒息——是时候开启一场数据库的自我救赎了。 程序员更需构建"技术敏锐度+工程落地能力+跨域协作"的三维竞争力,通过创建技术组合形成差异化优势。企业应建立持续学习机制,提供AI沙盒环境促进技术转化。
|
存储 关系型数据库 MySQL
【免费动手教程上线】阿里云RDS MySQL推出大容量高性能存储:高性能本地盘(最高16TB存储空间)、高性能云盘(最高64TB存储空间)
阿里云RDS MySQL提供高性能本地盘与高性能云盘等存储方案,满足用户大容量、低延迟需求。高性能本地盘单盘最大16TB,IO延时微秒级;高性能云盘兼容ESSD特性,支持IO性能突发、BPE及16K原子写等能力。此外,阿里云还提供免费动手体验教程,帮助用户直观感受云数据库 RDS 存储性能表现。

相关产品

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

    更多