Karp 的技术博客

2024-11-22T08:55:23.png
升级前的准备工作实际上是为了消除升级程序中无法自动处理的“不兼容的”变化

  • MySQL 8.0引入了全新的数据字典用于保存数据库中的元信息,Server层和InnoDB层共享一份元数据。MySQL 8.0的information_schema中的视图全部源自于数据字典表,与InnoDB相关的视图被重命名(INNODB_SYS_XXX重命名为INNODB_XXX)。若用户的应用依赖于这些视图,需要确保应用已做出相应的修改。在升级前需要确认业务是否依赖于MySQL 8.0中删除的系统表(如mysql.procmysql.event等),若存在则需使用新的访问方式去获取所需的数据。此外,对于和MySQL 8.0系统表同名的用户表(如catalogsroutines等),需要手动执行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个字节,因此在升级之前需要修改超出限制的ENUMSET
  • 如果.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子句不支持ASCDESC排序规则,因此,在进行升级前,需要修改或删除包含相应句法的存储过程。
  • 在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_ciutf8mb4_0900_ai_ci优先级相同(无法选择排序规则),当新表和迁移表相关字段发生JOIN时,会因为JOIN两端排序规则不兼容导致报错。

为避免出现字符集引发的问题,在升级前需要检查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

mysql

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2024年11月22日 08:55
0

目录

来自 《Mysql 5.7 升级到 Mysql 8.0》
774 文章数
0 评论量
9 分类数
779 页面数
已在风雨中度过 9年277天3小时50分