MySQL 5.7と8.0の違いのうち、移行で実際に問題になるのは「既定の認証方式」「既定の文字コードと照合順序」「SQLの非互換」の3つです。性能の優劣はワークロードによって変わり、既定値や内部処理の変更によって8.0で実際に遅くなる場合もあります。そして2026年10月時点では、5.7は2023年10月、8.0は2026年4月にOracleの延長サポートが終わり、新しい修正が出ないSustaining Supportに入っています。移行先は8.4 LTSか9.7 LTSです。この記事では、5.7.44・8.0.46・8.4.11・9.7.2の公式Dockerイメージに同じSQLを流した結果を並べ、どこで何が変わるかを示します。
まとめ:5.7と8.0の違いと移行先の選び方
- サポート:5.7は最終版5.7.44(2023年10月25日)、8.0は最終版8.0.46(2026年4月21日)でOracleの延長サポートが終了。どちらにも通常のセキュリティ修正は出ません。
- 移行先:オンプレミスや自前のコンテナなら9.7 LTS(延長サポートは2034年4月まで)、Amazon RDSなら現時点で正式提供されている8.4 LTS(同2032年4月まで)が基準です。
- 経路:5.7から8.4・9.7へは直接上げられません。5.7→8.0→8.4→9.7と1段ずつ上げます。実測でも5.7のデータを8.4で起動すると失敗しました。
- 最も詰まる点:8.4以降はmysql_native_passwordが既定で読み込まれず、5.7から引き継いだユーザーはERROR 1524でログインできなくなります。
- 黙って変わる点:GROUP BYの並び順、照合順序(「はは」と「ぱぱ」が同じ扱い、末尾空白の扱い)、再起動後のAUTO_INCREMENTはエラーを出さずに結果が変わります。テストで拾うべきはこちらです。
MySQL 5.7・8.0・8.4・9.7の既定値と機能比較
既定値の行は、各版の公式Dockerイメージを設定ファイルなしで起動し、SHOW VARIABLESで読んだ値です。サポート期限はOracle Lifetime Support Policy(2026年10月2日改定版)の値です。
| 項目 | 5.7 | 8.0 | 8.4 LTS | 9.7 LTS |
|---|---|---|---|---|
| GA | 2015年10月 | 2018年4月 | 2024年4月 | 2026年4月 |
| 現行・最終の版 | 5.7.44(最終) | 8.0.46(最終) | 8.4.11 | 9.7.2 |
| 延長サポート終了 | 2023年10月 | 2026年4月 | 2032年4月 | 2034年4月 |
| 既定の認証 | mysql_native_password | caching_sha2_password | caching_sha2_password | caching_sha2_password |
| mysql_native_password | 既定 | 使用可(非推奨) | 既定で無効 | 削除済み |
| character_set_server | latin1 | utf8mb4 | utf8mb4 | utf8mb4 |
| utf8mb4の既定照合順序 | utf8mb4_general_ci | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
| バイナリログ(log_bin) | OFF | ON | ON | ON |
| innodb_autoinc_lock_mode | 1 | 2 | 2 | 2 |
| explicit_defaults_for_timestamp | OFF | ON | ON | ON |
| クエリキャッシュ | あり(既定OFF) | 削除 | 削除 | 削除 |
| CTE・ウィンドウ関数 | なし | あり | あり | あり |
| 降順インデックス | 構文のみ(無視) | あり | あり | あり |
| ALGORITHM=INSTANT | なし | あり | あり | あり |
この表では5.7と8.0の差が目立ちますが、8.4以降にも認証以外の非互換があります。例えば8.4では、非一意キーなどを参照する外部キーを新規作成する操作が既定で制限されます。この記事では、5.7からの移行で特に詰まりやすい2点、つまり8.0への段階のSQL非互換と、8.4への段階の認証方式を重点的に扱います。
同じSQLを5.7と8.0以降で実行した結果
以下の結果は、公式Dockerイメージで各版を起動し、同じSQLファイルを順に流して得たものです(2026年10月17日・Docker 29.9.0・x86_64)。5.6との比較だけはmysql:5.6(5.6.51)を同じ手順で起動しました。
docker network create my4251
for t in 5.7.44 8.0.46 8.4 9.7; do
docker run -d --name "m${t//./}" --network my4251 -e MYSQL_ROOT_PASSWORD=pw "mysql:$t"
done
# 初期化が終わるまで待つ(pingが通れば接続可能)
for n in m5744 m8046 m84 m97; do
until docker exec "$n" mysqladmin -uroot -ppw ping >/dev/null 2>&1; do sleep 3; done
done
# 同じSQLを全版に流す(--forceでエラー後も続行)
for n in m5744 m8046 m84 m97; do
echo "## $n"; docker exec -i "$n" mysql -uroot -ppw --force -t < test.sql
done
test.sqlには、この章の表に出てくるSQL(GROUP BY c ASCやCREATE TABLE rank (id INT)など)を1行ずつ並べます。
タグmysql:8.4は8.4.11、mysql:9.7は9.7.2で起動しました。タグなしのmysql:latestは2026年に26系へ切り替わっているので、系列を指定するにはタグを使い、同じ版で再現したい検証ではパッチ版タグまたはイメージのダイジェストを固定します。タグの選び方はDockerでMySQLを構築する手順にまとめています。
MySQL 5.7から8.0以降への移行でエラー・警告になるSQL
| SQL | 5.7.44 | 8.0.46以降 |
|---|---|---|
GROUP BY c ASC |
成功 | ERROR 1064 |
CREATE TABLE rank (id INT) |
成功 | ERROR 1064 |
SELECT … FOR UPDATE UNION SELECT … |
成功 | ERROR 1064 |
GRANT … IDENTIFIED BY '…' |
成功(ユーザー作成) | ERROR 1064 |
SQL_CALC_FOUND_ROWS |
成功 | 成功+警告1287 |
CHARACTER SET utf8 |
utf8で作成 | utf8mb3で作成+警告3719 |
RANKは8.0でウィンドウ関数とともに予約語になりました。列名やテーブル名に使っている場合は、バッククォートで囲むか名前を変えます。GRANTでユーザーを作る書き方はMySQL 8.0の変更点一覧で削除と明記されており、先にCREATE USERを流す形に直します。UNIONの各SELECTにFOR UPDATEを付ける場合は、8.0では各SELECTを括弧で囲む必要があります。
逆方向、つまり8.0の新構文を5.7に流すと、WITH RECURSIVEとROW_NUMBER() OVERはERROR 1064、ALGORITHM=INSTANTはERROR 1800(Unknown ALGORITHM)になります。8.0へ上げた後にアプリへCTEを入れると、切り戻し先の5.7では動かないことになります。
エラーを出さずに結果だけが変わる挙動
エラーが出ないため、移行前後で結果を比べないと気づけない挙動です。
CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, c VARCHAR(10));
INSERT INTO t (c) VALUES ('b'),('a'),('c'),('a'),('b');
SELECT c, COUNT(*) FROM t GROUP BY c;
-- 5.7.44の結果: a 2 / b 2 / c 1 (cの昇順に並ぶ)
-- 8.0.46の結果: b 2 / a 2 / c 1 (並び順の保証なし)
- GROUP BYの暗黙ソート:公式のORDER BY最適化の節に、5.7以前は条件によってGROUP BYが暗黙にソートしていたが8.0では行わない、とあります。GROUP BYの結果順に依存した画面では並びが変わるため、並びが必要なクエリには
ORDER BYを明示します。 - 降順インデックス:5.7で
KEY ka (a DESC)と書くと、エラーは出ずにSHOW CREATE TABLE上はKEY ka (a)(昇順)として作られました。8.0では(a DESC)のまま残ります。 - AUTO_INCREMENTの再起動後の値:IDが1〜3の行を入れ、3を消してからサーバーを再起動し、1行足しました。5.7.44では新しい行のIDが3(消した番号を再利用)、8.0.46では4でした。8.0はカウンタの最大値をredoログに書くため、再起動で巻き戻りません。IDの再利用を前提にした処理は8.0で動きが変わります。
文字コードと照合順序の違い(utf8mb4_0900_ai_ci)
8.0ではcharacter_set_serverがlatin1からutf8mb4になり、utf8mb4の既定の照合順序もutf8mb4_general_ciからutf8mb4_0900_ai_ciに変わりました。照合順序は=やLIKE、GROUP BY、一意制約の判定に効くため、日本語データでは検索結果の件数が変わります。9行(はは・ぱぱ・ハハ・半角ハハ・a・A・末尾に空白付きのa・寿司と麦酒の絵文字)を入れた表で、各照合順序の一致件数を数えました。
| 照合順序 | 「はは」に一致 | 「a」に一致 | 寿司の絵文字に一致 | PAD属性 |
|---|---|---|---|---|
| utf8mb4_general_ci(5.7既定) | 1件 | 3件(Aと末尾空白も) | 2件(麦酒も) | PAD SPACE |
| utf8mb4_unicode_ci | 4件 | 3件 | 2件 | PAD SPACE |
| utf8mb4_0900_ai_ci(8.0既定) | 4件 | 2件(Aのみ) | 1件 | NO PAD |
| utf8mb4_ja_0900_as_cs | 3件 | 1件 | 1件 | NO PAD |
| utf8mb4_ja_0900_as_cs_ks | 1件 | 1件 | 1件 | NO PAD |
| utf8mb4_bin | 1件 | 2件(末尾空白も) | 1件 | PAD SPACE |
8.0既定のutf8mb4_0900_ai_ciは、ひらがなとカタカナ、全角と半角、清音と半濁音(は/ぱ)を区別しません。一方で絵文字同士は区別し、末尾の空白も区別します(NO PAD)。5.7のutf8mb4_general_ciで起きていた「寿司と麦酒の絵文字が等しくなる」問題は消えますが、代わりに「はは」で検索すると「ぱぱ」「ハハ」「ハハ」も当たります。読みの違いを区別したい列には、清濁・大小・かなの種類まで区別するutf8mb4_ja_0900_as_cs_ksを列単位で指定します。
もう1つの落とし穴は、5.7から引き継いだテーブルと8.0で新しく作ったテーブルの混在です。アップグレードは既存データベースやテーブルの照合順序を変えません。既存データベース内で文字コードを書かずに作ったテーブルはデータベースの既定(utf8mb4_general_ci)を継承しますが、CHARACTER SET utf8mb4だけを指定して照合順序を書かないと、8.0.46ではutf8mb4の既定であるutf8mb4_0900_ai_ciで作られました。ORMやマイグレーションツールが文字コードだけを明示する場合はこの形になります。こうしてできた新テーブルと旧テーブルを文字列列で結合すると、次のエラーになりました。
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT)
and (utf8mb4_0900_ai_ci,IMPLICIT) for operation '='
対策は、データベースの既定照合順序をALTER DATABASE … COLLATEで旧テーブルに合わせてから新テーブルを作るか、旧テーブルをALTER TABLE … CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ciで揃えるかのどちらかです。後者は一意制約の判定が変わるため、変換前に重複が出ないかを確認してから流します。
性能の違いと「8.0にすると遅くなる」原因
Oracleは製品ページでMySQL 8.0は5.7より最大2倍高速と案内しています。8.0にはヒストグラム統計、ハッシュ結合、降順インデックスなどがありますが、それぞれの効果はクエリとデータ分布によって変わります。アップグレード直後に遅くなった場合は、8.0そのものより既定値の変化を先に疑います。
- バイナリログが既定でON:比較表のとおり、5.7.44は
log_bin=OFF、8.0.46はONで起動しました。レプリケーションを組んでいない環境で5.7から上げると、更新のたびにバイナリログの書き込みが増えます。ポイントインタイム復旧に使うので基本は残し、ディスクの書き込み性能とbinlog_expire_logs_seconds(既定30日)による容量を見積もります。 - クエリキャッシュの削除:5.7.44の既定は
query_cache_type=OFFでした。影響を受けるのは5.7で明示的に有効にしていた環境だけです。その場合は同じ結果の再取得をアプリ側のキャッシュへ移します。 - 実行計画の変化:コストモデルが変わったため、同じSQLで別のインデックスが選ばれることがあります。移行前に主要クエリの
EXPLAINを5.7で保存し、8.0の結果と差分を取ります。遅くなったクエリの特定にはスロークエリログの設定と見方が使えます。
認証方式の違いと接続エラーの再現条件
caching_sha2_passwordでERROR 2061が出る条件
8.0の既定認証caching_sha2_passwordは、パスワードを送る経路にTLSかRSA鍵交換を要求します。「古いクライアントは繋がらない」と説明されがちですが、5.7.44付属のmysqlクライアントは、TLSを使う既定の接続なら8.0.46のcaching_sha2_passwordユーザーにそのまま接続できました。失敗したのはTLSを切った場合です。
# TLSなし・サーバー側キャッシュなし(新規ユーザーの初回、または再起動後)
mysql -h m8046 --ssl-mode=DISABLED -uu3 -p
ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error:
Authentication requires secure connection.
# 公開鍵の取得を許可すると成功
mysql -h m8046 --ssl-mode=DISABLED --get-server-public-key -uu3 -p
一度成功するとサーバーがパスワードのハッシュをメモリに保持するため、同じ設定のTLSなし接続も通るようになります。「普段は繋がるのに、DBの再起動後だけアプリが接続エラーになる」という症状はこの仕組みで起きます。本番環境ではサーバー証明書を検証するTLS接続を優先します。TLSを使わない場合は信頼できる公開鍵を事前配置する方法があり、安全なネットワーク内に限ってドライバ側で公開鍵の取得(Connector/JならallowPublicKeyRetrieval=true)を許可することです。PHPのmysqlndのように、ドライバが独自実装で版が古いものは認証方式そのものを知らないことがあるので、ドライバの版も確認します。
8.4・9.7へ上げたときのmysql_native_password
5.7で作られたユーザーはmysql_native_passwordのまま8.0へ引き継がれ、8.0では問題なく使えます。問題は次の8.4です。5.7→8.0と上げたデータディレクトリを8.4.11で起動すると、アップグレード自体は完了しますが、rootでのログインが失敗しました。
mysql -uroot -p
ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded
8.4のマニュアルのとおり、このプラグインは8.4で既定で無効、9.0.0で削除されました。8.4は--mysql-native-password=ONで起動すれば読み込めますが、9.7.2に同じオプションを付けるとunknown variable 'mysql-native-password=ON'で起動しません。延命策は8.4までしか効かないので、8.0の段階で各ユーザーをALTER USER 'app'@'%' IDENTIFIED WITH caching_sha2_password BY '…';で切り替えてから8.4へ上げます。どのユーザーが旧方式かはSELECT user, host, plugin FROM mysql.user;で確認できます。
サポート期限と延長サポートの有無
OracleのEOL告知では、5.7は2023年10月25日から、8.0は2026年4月21日からSustaining Support(新しい修正を出さない段階)に入りました。告知は移行先として8.4 LTSと9.7 LTSを挙げています。各版の最新のパッチは8.4のリリースノートで確認でき、2026年8月18日の8.4.12はDockerイメージだけを対象にしたセキュリティ更新です。
マネージドサービスでは、期限後も有償の延長サポートで使い続けられます。Amazon RDS for MySQLのバージョン管理ページの値は次のとおりです。
| RDS for MySQL | 標準サポート終了 | 延長サポート終了 |
|---|---|---|
| 5.7 | 2024年2月29日 | 2029年6月30日 |
| 8.0 | 2026年7月31日 | 2029年7月31日 |
| 8.4 | 2029年7月31日 | 2032年7月31日 |
| 9.7 | プレビュー環境のみ | - |
RDSの5.7と8.0は2026年8月以降、延長サポート料金が加算される期間に入っています。料金の目安はAWS RDSの料金を東京リージョンの実額で計算する記事で扱っています。Aurora MySQL version 3(8.0互換)は標準サポートが2028年4月30日までと、コミュニティ版の8.0より長く残ります。Aurora側の8.4への移行はAurora MySQL 8.4とversion 3からのアップグレード手順を参照してください。
9.7 LTSと26.7 Innovationの関係
MySQLは8.1以降、数年サポートされるLTSと、次の版が出ると修正が止まるInnovationの2系統で出ています。8.1〜8.3と9.0〜9.6がInnovation、8.4と9.7がLTSです。9.7.0は2026年4月21日に出ました。9.7マニュアルのリリースモデルの節によると、9.7は連番方式の最後の系列で、以降は暦に基づく番号に移りました。2026年7月28日には26.7.0が出ています。長期運用と変更の少なさを優先する本番環境にはLTSを推奨します。Innovationも本番品質のリリースですが、短い周期での更新と互換性テストを継続できる環境向けです。
8.4と9.7の選択は、使う基盤で決まります。RDSやAuroraを使うなら、正式提供されている8.4です。自前のサーバーやコンテナで新しく作るなら、サポートが2年長い9.7を選びます。ただし8.0から9.7へは8.4を経由する必要があります(次章)。
5.7・8.0からのアップグレード経路と事前チェック
公式の経路と実測した失敗例
9.7マニュアルのアップグレード経路表では、LTSから上げられるのは次のLTSまでで、5.7から8.4へは8.0を挟むよう書かれています。データディレクトリをそのまま使うインプレース方式で、各組み合わせを試した結果です。
| 移行元のデータ | 起動した版 | 結果 |
|---|---|---|
| 5.7.44 | 8.4.11 | 失敗(Data Dictionary initialization failed) |
| 5.7.44 | 8.0.46 | 成功 |
| 8.0.46 | 9.7.2 | 失敗(MY-014060) |
| 8.0.46 | 8.4.11 | 成功(rootはERROR 1524) |
| 8.4.11 | 9.7.2 | 成功(rootの認証方式を切り替えた後) |
8.0.46から9.7.2へ直接上げたときのログは次のとおりで、8.0は「最後のLTS」ではないので次のメジャー版へは上げられない、と明示されます。
[ERROR] [MY-014060] [Server] Invalid MySQL server upgrade: Cannot upgrade from 80046
to 90702. Upgrade to next major version is only allowed from the last LTS release,
which version 80046 is not.
もう1点、5.7を正常に停止しないまま新しい版で起動すると、版の組み合わせに関係なく[MY-012526] Upgrade is not supported after a crash or shutdown with innodb_fast_shutdown = 2で止まりました(検証スクリプトの待機処理の誤りで、初期化中の5.7を止めてしまった回の記録です)。上げる前にSET GLOBAL innodb_fast_shutdown=0;を実行してから正常終了させると確実です。
戻す方向はさらに厳しく、8.0から5.7へのダウングレードはサポートされません。切り戻しは、アップグレード前に取得したバックアップから5.7環境を復元する方法を基本にします。5.7を残していても、8.0で受け付けた更新を5.7へ逆方向に複製する構成は原則サポートされないため、切替後の更新データをどう扱うかも事前に決めます。
MySQL Shellの互換性チェック
上げる前に、MySQL Shellのutil.checkForServerUpgrade()で非互換を一覧にします。上の実測で使った5.7.44(予約語のテーブルrankとutf8の列を作成済み)に対して、mysql:8.0.46イメージに入っているMySQL Shell 8.0.46で実行しました。
mysqlsh --js -h m5744 -P 3306 -u root -p \
-e 'util.checkForServerUpgrade(null, {targetVersion:"8.0.46"})'
結果はErrors 0・Warnings 3・Notices 1でした。ただしconfigPathを指定していないため、設定ファイルに関する一部のチェックは未実施です。実施済みのチェックでは、予約語と衝突するd.rank、utf8mb3の列、既定認証の変更が警告に出ました。同じ5.7に対して、mysql:8.4イメージに入っているMySQL Shell 8.4.10でtargetVersionを8.4.10にすると、Errors 1・Warnings 10に増えました。Errorはdefault_authentication_pluginがmysql_native_passwordのままで、8.4.0へ上げる前に直す必要がある、という指摘です。あわせてtargetVersion=8.0で実行し直すよう促されます。8.0への段階と8.4への段階でそれぞれ実行します。ただし、GROUP BYの並び順や照合順序による件数の違いはチェッカーでは検出されないので、前章のような結果の比較テストを別に用意します。
MySQL 5.6と5.7の違い
5.6(延長サポートは2021年2月に終了)から5.7への変化で最も影響が大きいのは、既定のsql_modeが厳格になったことです。5.6.51と5.7.44で同じSQLを流した結果です。
| 項目 | 5.6.51 | 5.7.44 |
|---|---|---|
| 既定のsql_mode | NO_ENGINE_SUBSTITUTIONのみ | STRICT_TRANS_TABLES等7個 |
| VARCHAR(3)に6文字 | 3文字に切り詰め+警告1265 | ERROR 1406 |
| GROUP BY列に関数従属しない非集計列をSELECT | 成功(値は不定) | ERROR 1055 |
| JSON型 | ERROR 1064 | 使用可(5.7.8〜) |
| 生成列 | ERROR 1064 | 使用可 |
| sysスキーマ | なし | あり |
| mysql.userのパスワード列 | Passwordとauthentication_string | authentication_stringのみ |
5.6から上げる場合も経路は5.6→5.7→8.0→8.4と1段ずつで、5.7への段階で厳格モードによるINSERTエラーとGROUP BYのエラー、8.0への段階で前章の非互換、8.4への段階で認証、と山が3つになります。各段階で本番相当のデータを使った試験が要るので、件数が多い場合はデータベース設計・移行支援のような外部の支援を使う選択肢もあります。
よくある質問
MySQL 5.7はまだ使えますか?
動作はしますが、最終版5.7.44(2023年10月25日)以降、Oracleから修正は出ていません。Amazon RDSでは有償の延長サポートで2029年6月30日まで使えますが、その間に8.0を経由して8.4へ上げる計画を立てる必要があります。
MySQL 5.7と8.0はどちらが速いですか?
Oracleは8.0を5.7より最大2倍高速と案内していますが、この最大値だけでは個々のワークロードの優劣は判断できません。ただし8.0はバイナリログが既定でONになるため、5.7で無効だった環境では更新処理の書き込みが増えます。移行前に主要クエリの実行計画と更新性能を両方で比べてください。
MySQL 8.0のサポート終了後はどのバージョンへ移行すべきですか?
RDSやAuroraなら8.4 LTS、自前で運用するなら9.7 LTSが基準です。延長サポートの期限は8.4が2032年4月、9.7が2034年4月です。どちらへ行くにも、8.0のうちにmysql_native_passwordのユーザーをcaching_sha2_passwordへ切り替えておきます。
MySQL 5.7から8.4へ直接アップグレードできますか?
できません。公式の経路は5.7→8.0→8.4で、実測でも5.7.44のデータディレクトリを8.4.11で起動するとData Dictionaryの初期化に失敗しました。8.0から9.7へも同様に、8.4を経由します。
MySQLの最新バージョンはいくつですか?
2026年10月17日時点の公式ダウンロードページでは、LTSが9.7.2と8.4.11、Innovationが26.7.0です。本番向けはLTSのどちらかで、新しい版はMySQL Community Serverのダウンロードページで確認できます。MySQLの全体像や採用の判断はMySQLとは?特徴とバージョン選定で解説しています。