今日はなにの日。

気になったこと勉強になったことのメモ。

今日は、MySQL Shell にある「アップグレード チェッカー」とやらを試してみるの日。

目次

とある日

最近MySQL5から8に上げるときに気をつけることをずっと調べてて見つけた「アップグレードチェッカユーティリティ」を使ってみた記事です。

アップグレードチェッカユーティリティとは

MySQL Shell にある機能、`util.checkForServerUpgrade() 関数`を実行するだけで、MySQL サーバーインスタンスのアップグレード準備ができているかどうかをチェックしてくれます。

さらに、指定されたターゲットリリースに関連する自動チェックを実行し、手動で行う必要がある関連チェックをさらにアドバイスしてくれます。

MySQL :: MySQL Shell 8.0 :: 8.1 アップグレードチェッカユーティリティ

検証環境

WSL2のDocker環境で5.7のMySQLを立ててその中にMySQL Shellをインストールしてやって行きます。

  • Docker Compose version v2.7.0
  • image: mysql:5.7.39-debian

MySQL Shellインストール

docker環境なので無理やりインストールしました。

(互換性が必要なものを片っ端からインストールしました)

 apt --fix-broken install  libpython3.7-minimal  python3.7-minimal   libexpat1 lsb-release python3.7 python3-minimal libpython3-stdlib mime-support  distro-info-data

MySQL :: MySQL Shell 8.0 :: 2.2 Linux への MySQL Shell のインストール

アップグレードチェッカユーティリティを実行する

実行する前に、MySQL8.0に上げると問題となるものを作成して行きます。

MySQL 8.0での考慮事項

以下のブログを参考にして、チェックしてくれそうな項目を追加して行きます。

MySQL :: MySQL 8.0 にアップグレードしますか? ここにあなたが知る必要があるものがあります...

mysql スキーマ内で競合する名前を持つユーザー テーブル

トランザクション データ ディクショナリ(DD)のサポートは MySQL 8.0 で導入され、mysql スキーマにいくつかの新しい DD テーブルが作成されます。したがって、アップグレードの前に、mysql スキーマ内で競合する名前を持つユーザー テーブルを削除するか、名前を変更する必要があります。DD テーブル名は次のとおりです。'catalogs'、'character_sets'、'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', 「テーブルスペース」、「トリガー」、「view_routine_usage」、「view_table_usage」。 名前の変更または削除が必要なテーブルは、MySQL 5.7 で次のクエリを実行することで識別できます。(この例では、カタログは、DD 名と競合する mysql スキーマに存在するユーザー テーブルです。)

適当に競合しそうな名前のテーブルを作成します。

CREATE TABLE resource_groups (a int PRIMARY KEY AUTO_INCREMENT);

古いスタイルのデータ型

古いスタイルのdecimal 古いスタイルのvarchar、古いスタイルのTIME/DATETIME および TIMESTAMP などのデータ型は、それぞれMySQL 5.1 MySQL 5.0 および MySQL 5.6 で廃止され、バイナリ アップグレードにより MySQL 5.7 まで存続していましたが、サポートされません。 MySQL 8.0 で。これらのテーブルは、アップグレード前に MySQL 5.7 でCHECK TABLE…FOR UPGRADE またはcheck-upgradeオプションを指定して mysqlcheckを実行することで識別できます。さらに、古いスタイルの TIME/DATETIME および TIMESTAMP を使用するテーブル以下で説明するセッション変数を有効にすることで識別できます。ブログ.

これはうまく認識されているか不明です。

SET
    SESSION show_old_temporals = ON;

CREATE TABLE `ts` (
    `f_time` time
    /* 5.5 binary format */
    DEFAULT NULL,
    `f_timestamp` timestamp
    /* 5.5 binary format */
    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `f_datetime` datetime
    /* 5.5 binary format */
    DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = latin1;

64 文字を超える外部キー制約名

MySQL 8.0 より前のバージョンでは、InnoDB は、ユーザーが明示的に指定していない場合、テーブル名に 'ibfk_X' (X は数字) を付加して外部キー制約名を自動生成します。テーブル名が、以下の例で使用されているキリル文字のテーブル名 'имябазывкодировкеутф8длинойбольшечем45имяазывкодировк' のように、64 文字のマルチバイトである場合、自動生成された外部キー制約名は 64 文字を超えます。

外部キーの名前が既定値を超えるテーブルを作成します。

CREATE TABLE t1 (`fld1` int(11) PRIMARY KEY AUTO_INCREMENT);

CREATE TABLE `имя_базы_в_кодировке_утф8_длиной_больше_чем_45имя_азы_в_кодировк` (
    `fld1` int(11) DEFAULT NULL,
    `fld2` int(11) NOT NULL,
    PRIMARY KEY (`fld2`),
    CONSTRAINT `имя_базы_в_кодировке_утф8_длиной_больше_чем_45имя_азы_в_кодировк_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)
) ENGINE = InnoDB DEFAULT CHARSET = latin1;

長すぎる列挙型リテラル(つまり、255 文字を超える)

MySQL 8.0 より前では、FRM ファイルに 2 バイトで格納されていたため、すべての enum 要素の合計の長さは最大で約 64k になる可能性がありました。したがって、テーブルとストアド プロシージャは、255 文字を超える列挙型要素で作成される可能性があります。ただし、MySQL 8.0 では、長すぎる列挙型リテラル(つまり、255 文字を超える)を含むテーブルまたはストアド プロシージャはサポートされていません。

enumの長さが既定値を超えるテーブルを作成します。

CREATE TABLE `t_long_enum` (
    `i` int(11) NOT NULL,
    `b` enum(
        '\n         1         2         3         4         5         6         7         8         9         0\n                                                                                                   0\n                                                                                                   0'
    ) DEFAULT NULL,
    PRIMARY KEY (`i`)
) ENGINE = InnoDB DEFAULT CHARSET = latin1;

廃止された空間関数

これらの空間関数は、空間関数の名前空間が変更されたため、MySQL 8.0 で削除されました。この変更により、命名規則の一貫性が保たれます。つまり、関数が正確な操作を実行する場合は 'ST' で始まり、最小境界四角形に基づいて操作を実行する場合は 'MBR' で始まります。このような関数を使用して生成された列は、アップグレード前に変更する必要があります。削除された空間関数のリストは、次のドキュメントにあります。 生成された列は、対応する「ST」または「MBR」関数を使用するように変更する必要があります。

廃止される空間関数を使っているテーブルを作成します。

CREATE TABLE t_gcol_dep (
    fid INTEGER NOT NULL PRIMARY KEY,
    g POINT GENERATED ALWAYS AS (PointFromText(POINT(10, 10)))
);

util.checkForServerUpgrade()実行してみる

mysqlshをインストールして起動します。

root@18f5f01bc5b4:/# mysqlsh
Cannot set LC_ALL to locale en_US.UTF-8: No such file or directory
MySQL Shell 8.0.30

Copyright (c) 2016, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
 MySQL  JS >

この状態で、以下コマンドを実行します。

 util.checkForServerUpgrade("root@localhost:3306");

MySQL :: MySQL Shell 8.0 :: 8.1 アップグレードチェッカユーティリティ

すると色々と表示されます。

Please provide the password for 'root@localhost:3306': ****
Save password for 'root@localhost:3306'? [Y]es/[N]o/Ne[v]er (default No): y
The MySQL server at localhost:3306, version 5.7.39 - MySQL Community Server
(GPL), will now be checked for compatibility issues for upgrade to MySQL
8.0.30...

1) Usage of old temporal type
  No issues found

2) Usage of db objects with names conflicting with new reserved keywords
  No issues found

3) Usage of utf8mb3 charset
  No issues found

4) Table names in the mysql schema conflicting with new tables in 8.0
  No issues found

5) Partitioned tables using engines with non native partitioning
  No issues found

6) Foreign key constraint names longer than 64 characters
  No issues found

7) Usage of obsolete MAXDB sql_mode flag
  No issues found

8) Usage of obsolete sql_mode flags
  Notice: The following DB objects have obsolete options persisted for
    sql_mode, which will be cleared during upgrade to 8.0.
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html#mysql-nutshell-removals

  global system variable sql_mode - defined using obsolete NO_AUTO_CREATE_USER
    option

9) ENUM/SET column definitions containing elements longer than 255 characters
  Error: The following columns are defined as either ENUM or SET and contain at
    least one element longer that 255 characters. They need to be altered so that
    all elements fit into the 255 characters limit.
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/string-type-overview.html

  test.t_long_enum.b - ENUM contains element longer than 255 characters

10) Usage of partitioned tables in shared tablespaces
  No issues found

11) Circular directory references in tablespace data file paths
  No issues found

12) Usage of removed functions
  No issues found

13) Usage of removed GROUP BY ASC/DESC syntax
  No issues found

14) Removed system variables for error logging to the system log configuration
  To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
  More information:
    https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-13.html#mysqld-8-0-13-logging

15) Removed system variables
  To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html#optvars-removed

16) System variables with new default values
  To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
  More information:
    https://mysqlserverteam.com/new-defaults-in-mysql-8-0/

17) Zero Date, Datetime, and Timestamp values
  No issues found

18) Schema inconsistencies resulting from file removal or corruption
  No issues found

19) Tables recognized by InnoDB that belong to a different engine
  No issues found

20) Issues reported by 'check table x for upgrade' command
  No issues found

21) New default authentication plugin considerations
  Warning: The new default authentication plugin 'caching_sha2_password' offers
    more secure password hashing than previously used 'mysql_native_password'
    (and consequent improved client connection authentication). However, it also
    has compatibility implications that may affect existing MySQL installations.
    If your MySQL installation must serve pre-8.0 clients and you encounter
    compatibility issues after upgrading, the simplest way to address those
    issues is to reconfigure the server to revert to the previous default
    authentication plugin (mysql_native_password). For example, use these lines
    in the server option file:

    [mysqld]
    default_authentication_plugin=mysql_native_password

    However, the setting should be viewed as temporary, not as a long term or
    permanent solution, because it causes new accounts created with the setting
    in effect to forego the improved authentication security.
    If you are using replication please take time to understand how the
    authentication plugin changes may impact you.
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-compatibility-issues
    https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-replication

Errors:   1
Warnings: 1
Notices:  1

ERROR: 1 errors were found. Please correct these issues before upgrading to avoid compatibility issues.

結果を見る

長いので要点だけまとめて見てみます。

  • No issues foundは問題ない項目
  • Errorsが1件
    • enumの話
    • 9)The following columns are defined as either ENUM or SET and contain at least one element longer that 255 characters
  • Warningsが1件
    • MySQL 8.0のデフォルト認証の話
    • 8)The new default authentication plugin 'caching_sha2_password' offers more secure password hashing than previously used 'mysql_native_password'
  • Noticesが1件
    • sql_modeの話
    • 21)The following DB objects have obsolete options persisted for sql_mode, which will be cleared during upgrade to 8.0.

結果だけ見ると、事前に仕込んだものの殆どは検知されていない様子です。(理由は不明)

それぞれの問題のある項目を見ると下の方にアドバイスがあります。

8) Usage of obsolete sql_mode flags Notice: The following DB objects have obsolete options persisted for sql_mode, which will be cleared during upgrade to 8.0. More information: https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html#mysql-nutshell-removals

global system variable sql_mode - defined using obsolete NO_AUTO_CREATE_USER option

↓翻訳

お知らせ 以下のDBオブジェクトには、旧式のオプションが保存されています。 sql_mode に古いオプションが残っていますが、8.0 へのアップグレード時に削除されます。 詳細はこちら。 https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html#mysql-nutshell-removals

グローバルシステム変数sql_mode - 時代遅れのNO_AUTO_CREATE_USERを使用して定義されています。 オプション

sql_modeNO_AUTO_CREATE_USERがあります。

MySQL 8.0は無いオプションなので削除される内容が書かれています。

検知された項目に対応する

以下の項目を解消してみます。

  • Errorsが1件
    • enumの話
    • 9)The following columns are defined as either ENUM or SET and contain at least one element longer that 255 characters
  • Warningsが1件
    • MySQL 8.0のデフォルト認証の話
    • 8)The new default authentication plugin 'caching_sha2_password' offers more secure password hashing than previously used 'mysql_native_password'
  • Noticesが1件
    • sql_modeの話
    • 21)The following DB objects have obsolete options persisted for sql_mode, which will be cleared during upgrade to 8.0.

9)The following columns are defined as either ENUM or SET and contain at least one element longer that 255 characters

対処法はもとのブログに書かれているのでそれをそのまま使用します。

mysql> ALTER TABLE t_long_enum MODIFY b enum('\n         1         2         3         4\n');
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

8)The new default authentication plugin 'caching_sha2_password' offers more secure password hashing than previously used 'mysql_native_password'

my.cnfファイルに以下を追加します。

[mysqld]
default-authentication-plugin=mysql_native_password

21)The following DB objects have obsolete options persisted for sql_mode, which will be cleared during upgrade to 8.0.

mysql> SELECT @@global.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@global.sql_mode                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

現在の設定を取り出して、NO_AUTO_CREATE_USERだけ削除した内容をmy.cnfに追記します。

sql-mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

Docker再起動

Docker環境なのでコンテナごと再起動します。

再度util.checkForServerUpgrade()実行してみる

 MySQL  JS > util.checkForServerUpgrade("root@localhost:3306");
The MySQL server at localhost:3306, version 5.7.39 - MySQL Community Server
(GPL), will now be checked for compatibility issues for upgrade to MySQL
8.0.30...

1) Usage of old temporal type
  No issues found

2) Usage of db objects with names conflicting with new reserved keywords
  No issues found

3) Usage of utf8mb3 charset
  No issues found

4) Table names in the mysql schema conflicting with new tables in 8.0
  No issues found

5) Partitioned tables using engines with non native partitioning
  No issues found

6) Foreign key constraint names longer than 64 characters
  No issues found

7) Usage of obsolete MAXDB sql_mode flag
  No issues found

8) Usage of obsolete sql_mode flags
  No issues found

9) ENUM/SET column definitions containing elements longer than 255 characters
  No issues found

10) Usage of partitioned tables in shared tablespaces
  No issues found

11) Circular directory references in tablespace data file paths
  No issues found

12) Usage of removed functions
  No issues found

13) Usage of removed GROUP BY ASC/DESC syntax
  No issues found

14) Removed system variables for error logging to the system log configuration
  To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
  More information:
    https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-13.html#mysqld-8-0-13-logging

15) Removed system variables
  To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html#optvars-removed

16) System variables with new default values
  To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
  More information:
    https://mysqlserverteam.com/new-defaults-in-mysql-8-0/

17) Zero Date, Datetime, and Timestamp values
  No issues found

18) Schema inconsistencies resulting from file removal or corruption
  No issues found

19) Tables recognized by InnoDB that belong to a different engine
  No issues found

20) Issues reported by 'check table x for upgrade' command
  No issues found

21) New default authentication plugin considerations
  Warning: The new default authentication plugin 'caching_sha2_password' offers
    more secure password hashing than previously used 'mysql_native_password'
    (and consequent improved client connection authentication). However, it also
    has compatibility implications that may affect existing MySQL installations.
    If your MySQL installation must serve pre-8.0 clients and you encounter
    compatibility issues after upgrading, the simplest way to address those
    issues is to reconfigure the server to revert to the previous default
    authentication plugin (mysql_native_password). For example, use these lines
    in the server option file:

    [mysqld]
    default_authentication_plugin=mysql_native_password

    However, the setting should be viewed as temporary, not as a long term or
    permanent solution, because it causes new accounts created with the setting
    in effect to forego the improved authentication security.
    If you are using replication please take time to understand how the
    authentication plugin changes may impact you.
  More information:
    https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-compatibility-issues
    https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-replication

Errors:   0
Warnings: 1
Notices:  0

NOTE: No fatal errors were found that would prevent an upgrade, but some potential issues were detected. Please ensure that the reported issues are not significant before upgrading.

Errorsとかは消えましたが、Warningsは消えてないです。

色々と試行錯誤しましたが「警告なので消えないのでは?」と思い込むことにしました。

まとめ

実際にアップグレードするとなると大変なのであくまでもチェックするまでをやりました。

もっと検知される想定でしたが、やり方が悪かったのか、そもそもそこまでは検知してくれないのかあやふやでした。

  • MySQL Shellで8.0にアップグレードできるかチェックしてくれるユーティリティがある
  • 21項目でアップグレードできるかチェックしてくれる
  • アドバイスもしてくれる
  • MySQL Shellは\quitで終了できる

結論MySQL 5.7 から 8.0に上げるのは大変そう」という感想です。

なんやかんや初めてMySQL Shellを使いました。

コンソール上だとMySQLのところの文字が色変わってていいなってなりました。

参考記事

mysql — RDSでのMySQL 8.0「アップグレードチェッカー」の使用

MySQL :: MySQL Shell 8.0 :: 8.1 アップグレードチェッカユーティリティ

Upgrading to MySQL 8? Meet the MySQL Shell Upgrade Checker Utility - Percona Database Performance Blog

MySQL5.7からMySQL8.0へのインプレースアップグレード | Yakst

MySQL :: Upgrading to MySQL 8.0? Here is what you need to know...

MySQL :: MySQL 8.0 リファレンスマニュアル :: 4.4.5 mysql_upgrade — MySQL テーブルのチェックとアップグレード

MySQL :: 古い形式の時間型を持つテーブルを簡単に識別する方法!

MySQL :: MySQL 8.0: 古いテンポラル データ型のサポートの削除