升级前的准备工作实际上是为了消除升级程序中无法自动处理的“不兼容的”变化
- MySQL 8.0引入了全新的数据字典用于保存数据库中的元信息,Server层和
InnoDB
层共享一份元数据。MySQL 8.0的information_schema中的视图全部源自于数据字典表,与InnoDB相关的视图被重命名(INNODB_SYS_XXX
重命名为INNODB_XXX
)。若用户的应用依赖于这些视图,需要确保应用已做出相应的修改。在升级前需要确认业务是否依赖于MySQL 8.0中删除的系统表(如mysql.proc
、mysql.event
等),若存在则需使用新的访问方式去获取所需的数据。此外,对于和MySQL 8.0系统表同名的用户表(如catalogs
、routines
等),需要手动执行RENAME/DROP TABLE
操作。 - RDS MySQL 8.0不再支持部分旧版本数据类型。如果表中字段含有MySQL 8.0不支持的数据类型,需要在升级前通过REPAIR TABLE或逻辑导出+导入的方式修复。更多信息请参见准备升级安装。
- MySQL 8.0中,分区表的处理已由Server层下沉至引擎层,MySQL Server不再支持通用分区。
Non-native
的分区表在MySQL 8.0中被废弃,因此需要将这类分区表改为Native
类型(如InnoDB引擎)或是删除该分区表。 - 较早版本的MySQL 5.7(5.0.17之前的版本)的触发器(
Triggers
)不支持DEFINER属性,因此在MySQL 5.7实例中可能会存在缺失DEFINER属性的触发器,这些触发器会导致升级MySQL 8.0失败。在升级前您需要重新创建这些缺失DEFINER
属性的触发器。 - MySQL 8.0中,外键约束的长度存在限制,如果外键约束过长,在升级过程中可能会导致错误和失败。因此,在进行升级之前,需要将问题外键修改为长度小于
64
个字符的约束。 - MySQL 8.0之前版本,视图的列名长度上限为
255
个字符,而在MySQL 8.0版本中,视图的列名长度上限缩短至64个字符。因此,在进行升级之前,需要将视图中过长的列名修改为长度小于64
个字符的列名。 - MySQL 8.0中,单个ENUM和SET列元素的长度不得超过
255
个字符或1020
个字节,因此在升级之前需要修改超出限制的ENUM
和SET
。 - 如果
.frm
文件和InnoDB
数据字典表元数据信息不一致,那么会导致升级错误。因此,在进行升级之前,需要对数据进行逻辑导出和导入。若存在游离的.frm
文件(即不含.ibd
文件仅有.frm
文件),则需要进行相应清理。 - MySQL 8.0废弃了部分空间函数。如果生成列中包含了已删除的函数(新引入的空间函数以"ST"和"MBR"开头),则需要在升级前对相应的列进行修改。
- 在进行升级前,必须确保MySQL 5.7的实例已经进行了正确的关闭,即需要确保在升级前不存在待应用的REDO日志和等待回滚的事务。
- MySQL 8.0中引入了一些新的保留字,其中大多数禁止用作表名、列名等,因此需要对MySQL 5.7中包含的MySQL 8.0引入的新保留字做处理。
- 在升级前,需要将废弃的
sql_mode
变量内容(例如NO_AUTO_CREATE_USER
等)修改为MySQL 8.0支持的模式,以避免导致实例无法启动。 - 较新版本的MySQL 8.0实例(8.0.13及之后的版本),共享表空间(系统表空间和通用表空间)中不允许存在InnoDB类型的分区表,因此在进行升级前需要将共享表空间移动至独立表空间。
- MySQL 8.0实例中,
GROUP BY
子句不支持ASC
或DESC
排序规则,因此,在进行升级前,需要修改或删除包含相应句法的存储过程。 - 在MySQL 5.7中,
lower_case_table_names
是一个可修改的值,但在MySQL 8.0中,lower_case_table_names
是一个初始化参数,一旦实例初始化完成,就无法在后续进行修改。在进行升级时,若需要将该参数值修改为1,请确保升级前库表名称为小写,以避免出现升级错误。
MySQL 5.7和MySQL 8.0的字符集(
character set
)和排序规则(collation
)的配置可能存在差异,这可能导致索引失效、查询报错等问题,例如:- MySQL 8.0默认字符集为
utf8mb4
,使用1~4字节存储一个字符,MySQL 5.7默认字符集为utf8mb3
,使用1~3字节存储一个字符,因此字段和索引长度会受到影响。在REDUNDANT
或者COMPACT
行格式下,InnoDB
引擎所允许的最大索引长度为767
字节,对应在5.7
中索引允许的最大字符数是255
,而在8.0中则无法创建超过191
字符的索引。 - 当在MySQL 5.7中使用了
utf8mb3
字符集创建表,如果升级MySQL 8.0后默认使用的字符集为utf8mb4
,新建表在没有指定character set
时默认使用utf8mb4
。当新表(utf8mb4)和迁移表(utf8mb3
)相关字段发生JOIN
时,会因为JOIN
两端字符集类型不一致导致索引失效。 - 当在MySQL 5.7中使用了
utf8mb4_general_ci
排序规则创建表,如果升级到MySQL 8.0后,默认使用的排序规则为utf8mb4_0900_ai_ci
,新建表在没有指定collation
时默认使用utf8mb4_0900_ai_ci
。由于utf8mb4_general_ci
和utf8mb4_0900_ai_ci
优先级相同(无法选择排序规则),当新表和迁移表相关字段发生JOIN
时,会因为JOIN
两端排序规则不兼容导致报错。
- MySQL 8.0默认字符集为
为避免出现字符集引发的问题,在升级前需要检查MySQL中的字符集和排序规则使用情况,您也可以通过下述SQL来修改库、表、字段的字符集和排序规则。
# 修改库的字符集和排序规则
ALTER DATABASE database_name CHARACTER SET = charset COLLATE = collation;
# 修改表的字符集和排序规则
ALTER TABLE table_name CONVERT TO CHARACTER SET charset COLLATE collation;
# 修改字段的字符集和排序规则
ALTER TABLE table_name CHANGE column_name column_name type CHARACTER SET charset COLLATE collation;
重要
- 修改列的charset时,MySQL会尝试映射数据值,但如果修改前后charset不兼容,可能会发生数据丢失。
- 在阿里云RDS MySQL中,各版本默认字符集均使用utf8mb3,默认排序规则均使用utf8mb3_general_ci,如果没有手动修改过字符集和排序规则,大版本升级前后不会出现此类问题。
- 更多信息可参考:调整实例character_set_server参数和collation_server参数和MySQL 社区字符集配置。
参考文献 : https://help.aliyun.com/zh/rds/apsaradb-rds-for-mysql/rds-mysql-helps-mysql-5-7-upgrade-8-0