本页面介绍了在从 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.
某些关键字(例如 GROUPS
、LEAD
或 RANK
)在 MySQL 版本 8.0 中现在被归类为保留字。这意味着,之前用作标识符的一些字词现在可能被视为非法。如需修正受影响的语句,请使用标识符引用或重命名标识符。
如需查看完整的关键字列表,请参阅关键字和预留字词。
移除了带有 GROUP BY 子句的 ASC/DESC
以下是错误消息示例:
[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
排序的查询可能会生成与之前 MySQL 版本不同的结果。如需保留给定的排序顺序,请提供 ORDER BY
子句。
如果存储过程、触发器或事件定义包含使用 ASC
或 DESC
以及 GROUP BY
子句的查询,则相应对象的查询需要 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 字符
以下是错误消息示例:
[ERROR] [MY-010765] [Server] Error in Creating DD entry for %s.%s [ERROR] [MY-013140] [Server] Invalid utf8 character string: invalid_string
如果表定义包含无效的 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 事务
以下是错误消息示例:
[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 = 0x787887111212345678
bqual = 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 识别的属于其他引擎的表
以下是错误消息示例:
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';
未知存储引擎分区
以下是错误消息示例:
[System] [MY-011012] [Server] Starting upgrade of data directory. [ERROR] [MY-013140] [Server] Unknown storage engine 'partition'
MySQL 8.0 不允许在 InnoDB
和 ndbcluster
以外的引擎中使用分区。您必须检查是否存在具有分区且引擎不是 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 操作
与主要版本升级相关的底层任务有两项:
- 预检查操作:如果未在 3 小时内完成,则返回超时错误。
- 升级操作:如果未在六小时内完成,则返回超时错误。
如果实例的 MAJOR_VERSION_UPGRADE
操作持续时间长于预期,您可以调查 MySQL 错误日志,以检查该操作是否因元数据升级而受阻,或者是否卡在某个预检查步骤。此问题的最常见原因包括:
- 表、视图或索引的数量非常多
- 资源(例如 CPU 或内存)不足
- 主要事务阻止数据库关闭,以便开始升级流程。您可以使用 Trusted Cloud by S3NS 控制台检查当前进程。
系统中的打开文件过多
以下是错误消息示例:
[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 万个,您可能会收到一条错误消息,指出“系统中的打开文件过多”。您可能需要先将表的数量减少到 200 万个以下,然后才能升级。
内存不足错误
从 MySQL 5.7 升级到 8.0 时,需要额外的内存才能将旧元数据转换为新的数据字典。为避免在主要版本升级期间收到“内存不足”错误,Cloud SQL 建议每个表至少有 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 会在主要版本升级之前执行干净关机。工作负载繁重或事务运行时间较长的实例可能会经历较长的关停过程,这可能会导致超时并导致升级失败。为确保升级成功,请在流量较低且没有长时间运行的交易的时间段内安排升级。