5 月 31 2020
MySQL 8.0.20 升級筆記
這陣子在處理 MySQL 5.6 -> 5.7 -> 8.0 升級的事,踩到一些地雷;紀錄一下。
目前新版的 MySQL 5.7 & 8.0 在全新安裝時會隨機產生 root 的密碼,並把密碼寫在 log 裡面。
這行為在自動化佈署時會遇上點麻煩,而避免隨機產生 root 密碼的方式是在 script 作這樣的事:
... mysqld --initialize-insecure systemctl start mysqld echo "ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' BY '##########';" | mysql ...
(5.7 -> 8.0)升級方面,第一個變化是 mysql_upgrade 不需要執行了;server 在啟動時會檢查,並自行升版。
原本在 5.7 版仍能使用的幾個 Server System Variables 在 8.0 版必須移除:
- query_cache_type = 0
- query_cache_size = 0
- innodb_large_prefix = 1
- innodb_file_format = Barracuda
expire_logs_days 也應移除,改用 binlog_expire_logs_seconds。
我另外在 8.0 版補上這兩個設定:
- mysqlx = 0
- default_authentication_plugin = mysql_native_password
5.7 -> 8.0 的預設語系/字元集有變化:
character_set_server | collation_server | |
MySQL 5.7 | latin1 | latin1_swedish_ci |
MySQL 8.0 | utf8mb4 | utf8mb4_0900_ai_ci |
特別提 8.0.20 是因為使用 Percona XtraBackup 時踩到地雷(Ref. percona-xtrabackup-80 does not work with mysql 8.0.20);原因是 Redo log 格式被更改了,Changes in MySQL 8.0.20 (2020-04-27, General Availability) 裡面有這段:
InnoDB: Redo log records for modifications to undo tablespaces increased in size in MySQL 8.0 due to a change in undo tablespace ID values, which required additional bytes. The change in redo log record size caused a performance regression in workloads with heavy write I/O. To address this issue, the redo log format was modified to reduce redo log record size for modifications to undo tablespaces. (Bug #29536710)
(有興趣深究的可以看看這個 commit)
Percona XtraBackup – Documentation 裡面也有這段說明:
Due to changes in MySQL 8.0.20 released by Oracle at the end of April 2020, Percona XtraBackup 8.0, up to version 8.0.11, is not compatible with MySQL version 8.0.20 or higher, or Percona products that are based on it: Percona Server for MySQL and Percona XtraDB Cluster.
另外一顆地雷是 Drupal 7 在連線初始化時會設定 SQL mode,但 NO_AUTO_CREATE_USER 在 8.0 被拿掉了;目前先用 這個 comment 裡面夾帶的 patch 作修正。
7 月 31 2020
MySQL 8.0.20 升級後記(踩 & 拆雷記)
續前一篇,這陣子除了表訂工作之外,就是觀察 MySQL 升級後有哪些地雷被引爆,接著開始救傷。
一顆跟 Java/JDBC 有關,錯誤訊息如下圖;原因是 MySQL 8 沒有 query_cache_size 等等的參數,而解決方式是更新 MySQL Connector/J。

另外一顆的成因/故事就比較長了…
MySQL 8 之前的版本,我們習慣把 character_set_server 設為 utf8 ,而 collation_server 設為 utf8_general_ci ;升版前看到這兩個變數預設值都換掉了,就很開心的拿掉… 於是部份(年紀比較大)的 PHP web server 就爆了,錯誤訊息如下圖。

初步研判以為是 PHP 認不得 utf8mb4 ,仔細追查後發現真因是「認不得 utf8mb4_0900_ai_ci」,解決方式是把 collation_server 設為 utf8mb4_general_ci 。

附帶一提, PHP 5.3 的 ext/mysqlnd 沒這問題,僅 5.4 ~ 5.6 受影響,而 PHP 7 之後都支援 UCA Ver.9 的 collations …

分享此文:
By Joe Horn • Database, JAVA, PHP 0 • Tags: charset, collation, JAVA, JDBC, MySQL, mysqlnd, PHP, uca