2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

RDSのMySQL5.7がサポート終了に伴い、MySQL8.0へのバージョンアップが必要になりました。
その際に調べたことについて書いていこうと思います。

環境

  • 仮装環境
    • Docker
  • 言語&フレームワーク
    • PHP8系
    • Laravel10
  • DB
    • MySQL5.7
    • MySQL8.0

アップグレード時の注意点

1. デフォルト文字コードの変更

MySQL8.0から、デフォルトの文字コードがutf8mb4になった。

絵文字や幾つかの特殊な文字を保存できるようになった反面、今まで使用していた文字コードと変わってしまう。

加えて、defaultのcharacter setで設定していた人は、 今まで使っていた文字コードと変わってしまうので、自分で以前使っていた文字コードを指定する必要がある。

2. 予約語の追加

MySQL8.0で幾つか予約語が追加された。

それにより今までのSQL文やカラム名で使用できていた単語が予約語に引っかかり構文エラーなどが生じる。

  • CUBE
  • EMPTY
  • JSON_TABLE
  • LAST_VALUE
  • RANK
    etc

詳しくは「公式サイト」を参照

3. 変数、関数の削除と追加

クエリの中で使える変数や関数にも変更があった。

削除されたものを使用している場合、実行されなくなる。

  • 変数(廃止)
    • query_cache_size, query_cache_type
      • クエリキャッシュはMySQL 8.0で完全に削除された
    • secure_auth
      • この変数は廃止され、MySQL 8.0以降ではセキュアなパスワード認証は常に必須となった
    • old_passwords
      • MySQLの旧バージョンのパスワードハッシュ方式に関連していたが、MySQL 8.0では削除された
  • 関数(廃止)
    • PASSWORD()
      • ユーザーパスワードのハッシュを生成するために使われていたが、廃止された
    • ENCRYPT()
      • この関数は暗号化のためのものだったが、他のより安全な関数やアルゴリズムに置き換えられた
    • DES_ENCRYPT(), DES_DECRYPT()
      • これらの関数も同様に暗号化のためのものだったが、MySQL 8.0で削除された
  • 関数(追加)
    • JSON_ARRAYAGG()
      • JSON配列として集約された結果セットの値を返す
    • JSON_OBJECTAGG()
      • キーと値のペアを使用して、集約された結果セットからJSONオブジェクトを作成する
    • JSON_TABLE()
      • JSONドキュメントを関係データの行と列に変換、通常のテーブルのようにJOINやクエリを実行できる
    • JSON_OVERLAPS()
      • 2つのJSONドキュメントが共通の要素やキーを持っているかどうかを判定する
    • JSON_MERGE_PATCH()
      • 2つのJSONドキュメントを統合するが、 JSON_MERGE_PRESERVE()とは異なり、2つ目のオブジェクトでNULLの値を持つキーは最初のオブジェクトから削除される
    • JSON_STORAGE_SIZE()
      • JSONドキュメントがディスク上で消費するバイト数を返す
    • JSON_STORAGE_FREE()
      • JSONドキュメント内で未使用のスペースのバイト数を返す
    • JSON_KEYS()
      • JSONオブジェクトのキーの配列を返す
        etc

詳しくは「公式サイト」を参照

4. デフォルトの認証プラグインの変更

MySQL8.0からデフォルトの認証プラグインとしてcaching_sha2_passwordが導入された。

旧バージョンのmysql_native_passwordよりもセキュリティが向上している。

これにより、アプリケーションやライブラリが新しい認証プラグインをサポートしているかどうかを確認し、必要に応じて更新や設定変更を行う。

アップグレード手順

  1. docker-compose.ymlの修正
    Laravel以外(SQLで直接)から新規でテーブルとカラムを追加する可能性がない場合

    services:
      db:
    -    image: mysql:5.7
    +    image: mysql:8.0
    

    Laravel以外(SQLで直接)から新規でテーブルとカラムを追加する可能性がある場合
    my.cnfファイルの作成
    下記の内容を記載したmy.cnfファイルをdockerディレクトリへ格納する。

    [mysqld]
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    

    docker-compose.ymlの修正

    // 既存
    services:
      db:
    -    image: mysql:5.7
    +    image: mysql:8.0
    +    volumes:
    +          - ./_docker/my.cnf:/etc/mysql/my.cnf
    

 
2. コンテナ再作成
docker-compose downで既存のコンテナをストップさせてからdocker-compose up -dの実行を行う。
 
3. テスト実行
問題なく動くか確認する。

検証時に行った手順

アプリケーション側の自動テストが充実してたこともあり、アップグレード時の注意点を頭に入れつつとりあえず、アップグレードすることにしました。

  1. docker-compose.ymlの修正
    services:
      db:
    -    image: mysql:5.7
    +    image: mysql:8.0
    

 
2. docker-compose up -dの実行
既存のコンテナを削除してdocker-compose up -dの実行を行う。
 
3. マイグレーションの実行
現在の環境がPHP8系、Laravel10ということもあり、caching_sha2_password認証プラグインに対応している。(PHP7.4以降から対応されている)

もしも古いバージョンの場合はこの段階でエラー発生します。

その場合、前項にも挙げた「デフォルトの認証プラグインの変更」の影響があるので、バージョンアップの前に下記の手順を行う。

3-1. MySQL5.7のdefault-authentication-pluginを確認

5.7(認証).png
MySQL5.7

何も行わず、MySQL8.0へバージョンを上げると
8(認証).png
MySQL8.0

3-2. my.cnfを追加とdocker-compose.ymlの修正
my.cnfとは、MySQLの設定ファイルで、パラメータの設定などをする際に用いられる。
詳しくは「公式サイト」を参照
 
下記の内容を記載したmy.cnfファイルをdockerディレクトリへ格納する。

[mysqld]
default-authentication-plugin = mysql_native_password

その後、docker-compose.ymlのvolumesにmy.cnfファイルを指定する。

services:
  db:
    image: mysql:8.0
+	volumes:
+      - ./my.cnf:/etc/mysql/my.cnf

3-3. バージョンアップ処理
マイグレーションまで問題なく実行される。
default-authentication-pluginが変更されていることも確認
5.7(認証) (1).png
MySQL8.0
 
4. テストの実行
 テスト成功
 
5. MySQLの文字コードを確認
 テストは成功したが、バージョンアップの注意点にもあった文字コードを確認する。

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
   FROM information_schema.SCHEMATA
   WHERE SCHEMA_NAME = 'データベース名';

5.7_文字コード.png
MySQL5.7

8_文字コード.png
MySQL8.0

DEFAULT_CHARACTER_SET_NAMEとDEFAULT_COLLATION_NAMEが変更されてしまっている。

これが変更されることにより、新規テーブル、新規カラム作成時にこちらの文字コードがデフォルトへ設定されてしまう。

しかし、Laravelの[config/database.php]に文字コードを設定していた場合、以降の対応は不要

<?php

return [
    'connections' => [
        'mysql' => [
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
        ],
    ],
];

※マイグレーションから操作する場合は問題ないが、MySQLを直接操作して、新規テーブル、新規カラム作成する場合、バージョンアップ前に以降の設定が必要

5-1. my.cnfを追加とdocker-compose.ymlの修正
下記の内容を記載したmy.cnfファイルをdockerディレクトリへ格納する。

# 既存のLaravelと同じにしたい場合
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

# MySQL5.7と同じ設定にしたい場合
[mysqld]
character-set-server = latin1
collation-server = latin1_swedish_ci

その後、docker-compose.ymlのvolumesにコピー先を指定する。

services:
  db:
    image: mysql:8.0
	volumes:
      - ./my.cnf:/etc/mysql/my.cnf

5-2. アップグレード処理
テストまで終了し、文字コードを確認する

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
	FROM information_schema.SCHEMATA
	WHERE SCHEMA_NAME = 'データベース名';

8_文字コード(対応後_新).png
MySQL8.0(対応後、既存のLaravelと同じにしたい場合)
8_文字コード(対応後).png
MySQL8.0(対応後、MySQL5.7と同じ設定にしたい場合)

参考サイト

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?