本页面介绍在执行从 Cloud SQL for MySQL 5.7 到 Cloud SQL for MySQL 8.0 的主要版本升级时,在预检操作期间可能会遇到的已知问题和不兼容情况。
如需详细了解主要版本升级,请参阅就地升级数据库主要版本和查看错误日志。
不兼容的 SQL 更改
本部分列出了您在运行预检实用程序时或在升级期间可能会遇到的 Cloud SQL 5.7 和 Cloud SQL 8.0 中的 SQL 不兼容问题,并提供了有关如何解决这些问题的建议。
预留关键字
当您尝试使用预留关键字时,发生以下错误:
Warning: The following objects have names that conflict with new reserved keywords. Ensure queries sent by your applications use `quotes` when referring to them or they will result in errors.
如果您尝试使用现在在 MySQL 8.0 版中归类为预留关键字的字词(例如以下字词),则会发生此错误:
GROUPSLEADRANK
这意味着,之前用作标识符的某些字词现在可能被视为非法字词。如需解决此问题,请使用标识符引用修正受影响的语句,或重命名标识符。
如需查看完整的关键字列表,请参阅关键字和保留字。
移除了带有 GROUP BY 子句的 ASC/DESC
当您尝试将 ASC/DESC 与 GROUP BY 子句搭配使用时,会发生以下错误:
[ERROR] [MY-013235] [Server] Error in parsing Routine db_name.routine_name during upgrade. You may have an error in your SQL syntax; check the manual that corresponding to your MySQL server version for the right syntax to use near 'some_text'
在这种情况下,您还可能会收到以下错误消息:
[ERROR] [MY-013235] [Server] Unknown trigger has an error in its body: 'You have an error in you SQL syntax; [ERROR] [MY-010198] [Server] Error in parsing Triggers from trigger_name.TRG file.
如果您尝试使用 GROUP BY 对查询进行排序,会发生此错误。
之前依赖于 GROUP BY 排序的查询可能会生成与之前 MySQL 版本不同的结果。如需保留给定的排列顺序,请提供 ORDER BY 子句。
如需解决此问题,请使用 ORDER BY 子句。例如,如果存储过程、触发器或事件定义包含使用带有 GROUP BY 子句的 ASC 或 DESC 的查询,则该对象的查询需要 ORDER BY 子句。
如需了解详情,请参阅移除 GROUP BY ASC 和 DESC 的语法。
将空间数据与其他类型的数据混合作为键
如果使用错误的前缀键,则会发生以下错误:
[ERROR] [MY-013140] [Server] Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys [ERROR] [MY-013140] [Server] Too many key parts specified; max 1 parts allowed
如果您尝试将空间数据与其他类型的数据混合用作键,则会发生此错误。
在 MySQL 8.0 及更高版本中,索引不能同时包含空间数据和其他数据类型。您必须移除该键,然后创建一个 MySQL 8.0 版或更高版本支持的新键。如需了解详情,请参阅空间索引。
如需解决此问题,请使用类似于以下内容的查询来识别空间数据索引:
SELECT s.TABLE_SCHEMA, s.TABLE_NAME, s.INDEX_NAME, s.COLUMN_NAME, s.INDEX_TYPE, c.DATA_TYPE FROM information_schema.STATISTICS s JOIN information_schema.COLUMNS c ON s.TABLE_SCHEMA = c.TABLE_SCHEMA AND s.TABLE_NAME = c.TABLE_NAME AND s.COLUMN_NAME = c.COLUMN_NAME WHERE c.DATA_TYPE IN ( 'geometry', 'point', 'linestring', 'polygon', 'multipoint', 'multilinestring', 'multipolygon', 'geometrycollection' ) AND s.INDEX_TYPE = 'BTREE';
无效的 UTF8 字符
当您使用无效的 UTF8 字符串时,会发生以下错误:
[ERROR] [MY-010765] [Server] Error in Creating DD entry for %s.%s [ERROR] [MY-013140] [Server] Invalid utf8 character string: invalid_string
如果命令中包含无效的 UTF8 字符,则会发生此错误。例如,如果表定义包含无效的 UTF8 字符,则将表定义转换为数据字典可能会失败。
如需解决此问题,请将无效字符替换为相应的 UTF8 字符,或将其完全移除。
如需识别和处理无效字符,您可以使用类似于以下内容的查询:
SHOW CREATE TABLE table_name; ALTER TABLE table_name MODIFY COLUMN column_name data_type comment=''; // removing invalid utf8 character from comment
未提交的 XA 事务
如果存在已准备好的 XA 事务,则会发生以下错误:
[ERROR] [MY-013527] [Server] Upgrade cannot proceed due to an existing prepared XA transactions
如果存在未提交的 XA 事务,则会发生此错误,导致主要版本就地升级失败。
如需解决此问题,请在完成升级之前运行 XA RECOVER 语句。此语句会检查未提交的 XA 事务。
如果返回了响应,则通过发出 XA COMMIT 提交 XA 事务,或通过发出 XA ROLLBACK 语句回滚 XA 事务。
如需检查现有的 XA 事务,您可以运行类似如下的命令:
mysql> XA RECOVER CONVERT xid; +----------+--------------+--------------+-------------------------- | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+-------------------------- | 787611 | 9 | 9 | 0x787887111212345678812676152F12345678 | +----------+--------------+--------------+-------------------------- 1 row in set (0.00 sec)
在此示例中,我们可以看到 gtrid 和 bqual 的值以十六进制格式提供,但错误地进行了串联。如需解决此问题,您必须使用以下字段手动构建这些值:
gtrid = 0x787887111212345678bqual = 0x812676152F12345678
如需提交或回滚这些 XA 事务,您可以使用类似如下的命令,根据此信息创建 xid:
xid: gtrid [, bqual [, formatID ]] mysql> XA ROLLBACK|COMMIT 0x787887111212345678,0x812676152F12345678,787611;
超出键长度上限
如果指定的键过长,则会发生以下错误:
[ERROR] [MY-013140] [Server] Specified key was too long; max key length is [INTEGER] bytes
如果提供的密钥长度超出允许的限制,则会发生此错误。
此问题可能是由 sql_mode 配置引起的。在 MySQL 5.7 版中,由于没有严格模式,因此创建索引时可能应用了对前缀或索引长度的限制。
不过,在 MySQL 版本 8.0 中,引入了 STRICT_ALL_TABLES 或 STRICT_TRANS_TABLES 等严格模式,这些模式对索引长度应用了更严格的规则,从而导致了此错误。
如需解决此问题,请将索引前缀长度更新为不超过错误消息中指示的最大字节数。由于默认协议为 UTFMB4,每个字符最多占 4 个字节,这意味着可以通过将最大字节数除以 4 来确定最大字符数。
元数据信息不匹配
当元数据不匹配时,会发生以下错误:
[ERROR] [MY-012084] [InnoDB] Num of Indexes in InnoDB doesn't match with Indexes from server [ERROR] [MY-012069] [InnoDB] table: TABLE_NAME has xx columns but InnoDB dictionary has yy columns
在这种情况下,您还可能会收到以下错误消息:
[ERROR] [MY-010767] [Server] Error in fixing SE data for db_name.table_name
如果您尝试升级元数据不匹配的表,则会发生此错误。
例如,如果您尝试升级 FRM 文件与 InnoDB 数据字典之间元数据不匹配的表,则升级会失败。在这种情况下,FRM 文件可能已损坏。如需解决此问题,您必须先转储并恢复受影响的表,然后再尝试升级。
如需了解详情,请参阅尝试升级元数据不匹配的表。
如需转储和恢复受影响的表,您可以运行类似于以下内容的命令:
mysqldump --databases database_name --host=$host --user=$user --password=$password > database_dump.sql mysql> source database_dump.sql;
外键名称超过 64 个字符
尝试使用过长的外键限制条件名称时,会发生以下错误:
[ERROR] [MY-012054] [InnoDB] Foreign key name:key_name is too long
如果外键名称超过 64 个字符,就会发生此错误。
如需解决此问题,请使用类似于以下内容的命令来确定限制条件名称过长的表:
SELECT CONSTRAINT_NAME, TABLE_NAME FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE CHAR_LENGTH(CONSTRAINT_NAME) > 64;
如果某个表包含超过 64 个字符的限制条件名称,请使用 ALTER TABLE 命令重命名该限制条件,使其不超过此字符数限制:
ALTER TABLE your_table RENAME CONSTRAINT your_long_constraint_name TO your_new_constraint_name;
表名称中的字母大小写不一致
如果您没有使用精确的表名称,会发生以下错误:
[ERROR] [MY-013521] [Server] Table name 'SCHEMA_NAME.TABLE_NAME' containing upper case characters is not allowed with lower_case_table_names = 1.
如果表名称之间存在大小写不一致的情况,则会发生此错误。
如需解决此问题,如果 MySQL 5.7 版实例要求小写字母的表名 (lower_case_table_names=1),则必须先将所有表名转换为小写字母,然后才能升级到 MySQL 8.0 版。
或者,您可以停用该要求 (lower_case_table_names=0),然后升级实例。请注意,如果您将 lower_case_table_names 字段的值从 1 更改为 0,则在 MySQL 8.0 版中无法再将该值改回来。
InnoDB 识别的表属于其他引擎
当 InnoDB 识别出某个表,但该表实际上属于其他引擎时,会发生以下错误:
Error: Following tables are recognized by InnoDB engine while the SQL layer believes they belong to a different engine. Such situation may happen when one removed InnoDB files manually from the disk and creates a table with same name by using different engine.
如果您删除某个表,然后使用其他引擎创建同名的新表,就会发生此错误。
如果数据库中存在 InnoDB 引擎识别但 SQL 层无法识别的表,升级会失败。
如需解决此问题,请找到数据库中不使用 InnoDB 存储引擎的所有表:
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db_name' AND ENGINE != 'InnoDB'
针对每个已识别的表,运行 ALTER TABLE 命令将其存储引擎更改为 InnoDB。
ALTER TABLE db_name.table_name ENGINE='INNODB';
未知存储引擎 partition
当您尝试使用未知存储引擎时,会发生以下错误:
[System] [MY-011012] [Server] Starting upgrade of data directory. [ERROR] [MY-013140] [Server] Unknown storage engine 'partition'
如果引擎中存在不受支持的分区,则会发生此错误。
MySQL 8.0 版仅允许存储引擎中有以下分区:
InnoDBndbcluster
如需解决此问题,您必须检查是否存在具有分区且引擎不是 InnoDB 的表。
如需识别这些表,请使用以下查询:
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%';
查询报告的任何表都必须更新为使用 InnoDB 或配置为非分区表。如需将表存储引擎更改为 InnoDB,请运行以下语句:
ALTER TABLE db_name.table_name ENGINE = INNODB;
长时间运行的 MVU 操作
与主要版本升级相关的底层任务有两项:
- 预检操作:如果未在三小时内完成,则返回超时错误。
- 升级操作:如果未在六小时内完成,则返回超时错误。
如果实例的 MAJOR_VERSION_UPGRADE 操作持续时间长于预期,您可以调查 MySQL 错误日志,以检查该操作是否在元数据升级中受阻,或者是否卡在某个预检查步骤。此问题的最常见原因包括:
- 表、视图或索引的数量非常多
- 资源(例如 CPU 或内存)不足
- 主要事务阻碍数据库关闭,导致升级流程无法开始。您可以使用 Google Cloud 控制台检查当前流程。
系统中打开的文件过多
当系统中有太多打开的文件时,会发生以下错误:
[ERROR] [MY-012592] [InnoDB] Operating system error number 23 in a file operation [ERROR] [MY-012596] [InnoDB] Error number 23 means 'Too many open files in system'
例如,如果实例包含的表超过 200 万个,就会发生此错误。在这种情况下,您可能会收到一条错误消息,指出“系统中的打开文件过多”。
如需解决此问题,请在升级前减少表的数量。
内存不足错误
当内存不足时,会发生以下错误:
Out of memory
如果没有为表分配足够的内存,则会发生此错误。
从 MySQL 5.7 升级到 8.0 时,需要额外的内存才能将旧元数据转换为新的数据字典。
如需解决此问题,我们建议您为每个表分配至少 100 KB 的内存。
如需查找表的数量,请使用以下查询:
SELECT table_schema AS 'Database Name', COUNT(*) AS 'Number of Tables' FROM information_schema.tables
在开始升级之前,您可以通过更改机器类型来暂时增加内存。
对于共享核心实例(例如微型或小型核心,包括 db-f1-micro、db-g1-small、HA db-f1-micro、HA db-g1-small),请在升级操作期间升级到专用核心实例,以避免任何潜在的资源相关问题。您可以在升级操作完成后再将机器类型降级。
MySQL 关停错误
在崩溃后尝试升级时,发生以下错误:
[ERROR] [MY-012526] [InnoDB] Upgrade after a crash is not supported.
如果之前的关停操作花费的时间超出预期,则会发生此错误。
Cloud SQL 会在主要版本升级之前执行正常关停。具有繁重工作负载或长时间运行的事务的实例可能会经历较长的关停过程,从而可能导致超时以及升级失败。
为解决此问题并确保升级成功,请在流量较低且没有长时间运行的事务的时间段内安排升级。