就地升級至 MySQL 8.0 主要版本的已知問題

本頁面說明從 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) 現在會歸類為保留字。也就是說,先前用做 ID 的某些字詞現在可能視為違法。如要修正受影響的陳述式,請使用 ID 引號或重新命名 ID。

如需完整關鍵字清單,請參閱「關鍵字和保留字」。

已移除含有 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 子句。

如果預存程序、觸發程序或事件定義包含使用 ASCDESCGROUP 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)
  

在本例中,gtridbqual 的值是以十六進位格式提供,但卻錯誤地串連在一起。如要解決這個問題,請使用下列欄位手動建構這些值:

  • 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_TABLESSTRICT_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 版不允許在 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 或記憶體等資源不足
  • 重大交易會阻礙資料庫關機,導致升級程序無法啟動。您可以使用 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-microdb-g1-smallHA db-f1-microHA db-g1-small),請在升級作業期間升級至專用核心執行個體,以免發生任何資源相關問題。升級作業完成後,您可以降級。

MySQL 關機錯誤

以下是錯誤訊息範例:

[ERROR] [MY-012526] [InnoDB] Upgrade after a crash is not supported.

Cloud SQL 會先執行乾淨關機,再升級主要版本。如果執行個體的工作負載繁重或交易時間較長,關機程序可能會延長,進而導致逾時,升級作業也會失敗。為確保升級成功,請在流量偏低且沒有長時間執行的交易時升級。

後續步驟