### 2.11.5 准备升级安装 在升级到最新的 MySQL 8.0 版本之前,通过执行下面描述的初步检查,确保您当前的 MySQL 5.7 或 MySQL 8.0 服务器实例已准备好升级。否则升级过程可能会失败。 提示 考虑使用[MySQL Shell 升级检查器实用程序](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-upgrade.html)这使您能够验证 MySQL 服务器实例是否已准备好升级。您可以选择计划升级到的目标 MySQL Server 版本,范围从 MySQL Server 8.0.11 到与当前 MySQL Shell 版本号匹配的 MySQL Server 版本号。升级检查器实用程序执行与指定目标版本相关的自动检查,并建议您应该手动进行进一步的相关检查。升级检查器适用于 MySQL 5.7 和 8.0 的所有 GA 版本。可以找到 MySQL Shell 的安装说明[这里](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-install.html). 初步检查: 1. 不得存在以下问题: - 不得有使用过时数据类型或函数的表。 如果表包含 5.6.4 之前格式的旧时态列,则不支持就地升级到 MySQL 8.0 ([`时间`](time.html),[`约会时间`](datetime.html), 和[`时间戳`](datetime.html)不支持小数秒精度的列)。如果您的表仍使用旧的时间列格式,请使用[`维修台`](repair-table.html)在尝试就地升级到 MySQL 8.0 之前。有关详细信息,请参阅[服务器更改](https://dev.mysql.com/doc/refman/5.7/en/upgrading-from-previous-series.html#upgrade-server-changes), 在[MySQL 5.7 参考手册](https://dev.mysql.com/doc/refman/5.7/en/). - 不能有孤儿`.frm`文件。 - 触发器不得缺少或为空的定义器或无效的创建上下文(由`character_set_client`,`collat​​ion_connection`,`数据库整理`显示的属性[`显示触发器`](show-triggers.html)或者`INFORMATION_SCHEMA` [`触发器`](information-schema-triggers-table.html)桌子)。必须转储并恢复任何此类触发器以解决问题。 要检查这些问题,请执行以下命令: ``` mysqlcheck -u root -p --all-databases --check-upgrade ``` 如果[**mysql检查**](mysqlcheck.html)报告任何错误,纠正问题。 2. 不能有使用不支持本机分区的存储引擎的分区表。要识别此类表,请执行以下查询: ``` SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%'; ``` 查询报告的任何表都必须更改为使用`InnoDB`或不分区。将表存储引擎更改为`InnoDB`,执行这条语句: ``` ALTER TABLE table_name ENGINE = INNODB; ``` 有关转换的信息`MyISAM`表到`InnoDB`, 看[第 15.6.1.5 节,“将表从 MyISAM 转换为 InnoDB”](converting-tables-to-innodb.html). 要使分区表不分区,请执行以下语句: ``` ALTER TABLE table_name REMOVE PARTITIONING; ``` 3. MySQL 8.0 中可能保留了一些以前未保留的关键字。看[第 9.3 节,“关键字和保留字”](keywords.html).这可能导致以前用作标识符的单词变得非法。要修复受影响的语句,请使用标识符引用。看[第 9.2 节,“架构对象名称”](identifiers.html). 4. MySQL 5.7 中不能有表`mysql`与 MySQL 8.0 数据字典使用的表同名的系统数据库。要识别具有这些名称的表,请执行以下查询: ``` SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE LOWER(TABLE_SCHEMA) = 'mysql' and LOWER(TABLE_NAME) IN ( 'catalogs', 'character_sets', 'check_constraints', 'collations', 'column_statistics', 'column_type_elements', 'columns', 'dd_properties', 'events', 'foreign_key_column_usage', 'foreign_keys', 'index_column_usage', 'index_partitions', 'index_stats', 'indexes', 'parameter_type_elements', 'parameters', 'resource_groups', 'routines', 'schemata', 'st_spatial_reference_systems', 'table_partition_values', 'table_partitions', 'table_stats', 'tables', 'tablespace_files', 'tablespaces', 'triggers', 'view_routine_usage', 'view_table_usage' ); ``` 查询报告的任何表都必须被删除或重命名(使用[`重命名表`](rename-table.html))。这也可能需要对使用受影响表的应用程序进行更改。 5. 不能有外键约束名称超过 64 个字符的表。使用此查询来识别约束名称过长的表: ``` SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME IN (SELECT LEFT(SUBSTR(ID,INSTR(ID,'/')+1), INSTR(SUBSTR(ID,INSTR(ID,'/')+1),'_ibfk_')-1) FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN WHERE LENGTH(SUBSTR(ID,INSTR(ID,'/')+1))>64); ``` 对于约束名称超过 64 个字符的表,删除约束并将其添加回来,约束名称不超过 64 个字符(使用[`更改表`](alter-table.html))。 6. 必须没有过时的 SQL 模式定义[`sql_mode`](server-system-variables.html#sysvar_sql_mode)系统变量。尝试使用过时的 SQL 模式会阻止 MySQL 8.0 启动。应修改使用过时 SQL 模式的应用程序以避免它们。有关 MySQL 8.0 中删除的 SQL 模式的信息,请参阅[服务器更改](upgrading-from-previous-series.html#upgrade-server-changes). 7. 不允许有超过 64 个字符的显式定义的列名的视图(MySQL 5.7 中允许列名最多 255 个字符的视图)。为避免升级错误,应在升级前更改此类视图。目前,识别列名超过 64 个字符的视图的唯一方法是使用以下方法检查视图定义[`显示创建视图`](show-create-view.html).您还可以通过查询[`INFORMATION_SCHEMA.VIEWS`](information-schema-views-table.html)桌子。 8. 不能有单独的表或存储过程`枚举`要么`放`长度超过 255 个字符或 1020 个字节的列元素。在 MySQL 8.0 之前,最大组合长度为`枚举`要么`放`列元素为 64K。在 MySQL 8.0 中,个人的最大字符长度`枚举`要么`放`列元素为 255 个字符,最大字节长度为 1020 字节。(1020 字节限制支持多字节字符集)。在升级到 MySQL 8.0 之前,修改任何`枚举`要么`放`超出新限制的列元素。否则会导致升级失败并出现错误。 9. 在升级到 MySQL 8.0.13 或更高版本之前,必须没有表分区驻留在 shared`InnoDB`表空间,包括系统表空间和通用表空间。通过查询识别共享表空间中的表分区`INFORMATION_SCHEMA`: 如果从 MySQL 5.7 升级,请运行以下查询: ``` SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single'; ``` 如果从早期的 MySQL 8.0 版本升级,请运行以下查询: ``` SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single'; ``` 将表分区从共享表空间移动到每表文件表空间使用[`ALTER TABLE ...重新组织分区`](alter-table.html): ``` ALTER TABLE table_name REORGANIZE PARTITION partition_name INTO (partition_definition TABLESPACE=innodb_file_per_table); ``` 10. 不得有来自 MySQL 8.0.12 或更低版本的查询和存储的程序定义使用`ASC`要么`DESC`限定词`通过...分组`条款。否则,升级到 MySQL 8.0.13 或更高版本可能会失败,就像复制到 MySQL 8.0.13 或更高版本的副本服务器一样。有关其他详细信息,请参阅[SQL 更改](upgrading-from-previous-series.html#upgrade-sql-changes). 11. 您的 MySQL 5.7 安装不得使用 MySQL 8.0 不支持的功能。此处的任何更改都必须是特定于安装的,但以下示例说明了要查找的内容: MySQL 8.0 中删除了一些服务器启动选项和系统变量。看[MySQL 8.0 中删除的功能](mysql-nutshell.html#mysql-nutshell-removals), 和[第 1.4 节,“MySQL 8.0 中添加、弃用或删除的服务器和状态变量和选项”](added-deprecated-removed.html).如果您使用其中任何一种,升级需要更改配置。 示例:因为数据字典提供有关数据库对象的信息,服务器不再检查数据目录中的目录名称来查找数据库。因此,`--ignore-db-dir`选项是无关的,已被删除。要处理此问题,请删除任何实例`--ignore-db-dir`从您的启动配置。此外,在升级到 MySQL 8.0 之前删除或移动命名的数据目录子目录。(或者,让 8.0 服务器将这些目录作为数据库添加到数据字典中,然后使用[`删除数据库`](drop-database.html).) 12. 如果您打算更改[`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names)在升级时设置为 1,请确保在升级之前架构和表名称为小写。否则,由于模式或表名字母大小写不匹配,可能会发生故障。您可以使用以下查询来检查包含大写字符的架构和表名称: ``` mysql> select TABLE_NAME, if(sha(TABLE_NAME) !=sha(lower(TABLE_NAME)),'Yes','No') as UpperCase from information_schema.tables; ``` 从 MySQL 8.0.19 开始,如果[`lower_case_table_names=1`](server-system-variables.html#sysvar_lower_case_table_names)、表和模式名称由升级过程检查以确保所有字符都是小写的。如果发现表或模式名称包含大写字符,则升级过程将失败并出现错误。 笔记 改变[`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names)不建议在升级时设置。 如果升级到 MySQL 8.0 由于上述任何问题而失败,服务器会将所有更改还原到数据目录。在这种情况下,删除所有重做日志文件并在现有数据目录上重新启动 MySQL 5.7 服务器以解决错误。重做日志文件(`ib_logfile*`) 默认情况下位于 MySQL 数据目录中。修复错误后,执行慢速关机(通过设置[`innodb_fast_shutdown=0`](innodb-parameters.html#sysvar_innodb_fast_shutdown)) 在再次尝试升级之前。