スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL Shell の dumpInstance() を使ってMySQL5.6をバージョンアップする

はじめに

ご存じの方も多いかもしれませんが、長年親しまれてきた「MySQL5.6」は2021年2月に Extended Support が終了し、今後コミュニティ版の新しいバージョンがリリースされなくなりました(最終バージョンは5.6.51)。

その影響か、これまでMySQL5.6を利用していたユーザがMySQL5.7ないしMySQL8.0に移行(バージョンアップ)するケースが増えており、弊社にもそういった依頼を多くいただいております。

こうした場合、どのような方法でバージョンアップをするのか悩む方も多いのではないでしょうか。
アップグレード手順に関しては、公式マニュアルにも記載がありますが、大きく分けて3つの方法がございます。

方法 説明 メリット
インプレース 現行のMySQL5.6サーバをそのままアップグレードする 今動いているサーバをそのまま使える
物理バックアップ 新しく構築したMySQLサーバに現行環境から取得した物理バックアップ(ex. MEB) バックアップのリストア時間が短い
論理バックアップ 上記の論理バックアップ版(ex. mysqldump) 文字コード、DDLの変更などがしやすい

この中で、今回は論理バックアップを使ったバージョンアップ方法のやり方の一つとして、「MySQL ShellのdumpInstance()を使ったやり方」について取り上げたいと思います。

MySQL Shellを使ったバージョンアップ

論理バックアップを使ったバックアップを行う場合、従来はmysqldumpコマンドを使うやり方が一般的でした。例えば、以下のようなコマンドです。

この方法の場合、データロード時に断片化したデータの再構成が行われたり、バージョン間でファイルフォーマットや文字コードを変更したい要望に応えやすいというメリットがあります。
しかし、全テーブルを全件INSERTする上、処理がシングルスレッドになってしまうため、dumpのロード時間が最大のネックとなってしまいます(データが大きいほど時間が長くなります)。
特に、定期メンテナンスのタイミングなどでバージョンアップを一気に終わらせたいケースなどでは悩みの種になってしまうのではないでしょうか?

この問題の解決策となりうるのが、MySQL Shellの dumpInstance() コマンド(Dump Utility)です。このコマンドは、mysqldump と同じように論理バックアップを取得するのですが以下のような違いがあります。

  • テーブルデータ(レコード)をINSERTではなく、tsv形式のファイルで出力する
  • データのエクスポート・インポート共に、並列スレッドで実行可能
  • 整合性や取得するデータのフィルタリングをコマンドオプションで柔軟に選べる

上記のようなメリットから、dumpInstance()コマンドを使うことで論理バックアップを使ったバージョンアップがより高速かつ効率的に実施できることが期待できます。以下の項目でそのやり方について解説していきます。

※ Dump Utilityの処理速度の優位性については、昨年のブログ記事をご参照ください

なお、以前は mysqlpump が上記のような mysqldump の後継を担っていましたが、最近の開発の動きとしては dump utility の方を後継として注力しているようです。

検証環境構築

OCIを使って、検証環境を構築します。

なお、MySQL5.6のバージョンは実際に今もMySQL5.6を使っているお客様のケースを想定し、少し古いバージョンにします。今回は、2年前時点(2019/06/14)の最新版である「5.6.44」にします。

また、移行先として想定するMySQL5.7/8.0に関しては、2021/06/14時点の最新バージョンである [5.7.34]と「8.0.25」にします。

MySQL Shellに関しても、最新バージョンである「8.0.25」にします。

【検証環境スペック(OCI)】

以下の検証で使用するサーバのスペックは全て同一にします。

インスタンスタイプ OS CPU MEMORY Disk NW
VM.Standard.E4.Flex Oracle Linux 7.9 8 OCPU(16 コア) 32 MB NVMe SSD 300 GB 8 Gbps (1 × OCPU)

※ セキュリティグループの設定で、プライベートネットワーク(10.0.0.XX)間の 3306 ポートの通信は許可してあります
※ SELinux、iptables(firewalld) は無効にしてあります
※ ディスクは以下のコマンドでブートボリュームの拡張を実施しました

移行元(MySQL5.6)構築

1. プリインストールされているMySQLを削除します

2. MySQLのyumリポジトリと yum-utils をインストールします

3. リポジトリを5.6向けに切り替え、MySQL5.6.44をインストールします

4. 簡単なmy.cnfを設定してから、MySQLを起動します

5. sysbenchをインストールします

Oracle Linux上でsysbench の yum リポジトリからインストールをすると、 ver.1.0.17(2019/05/15)がインストールされてしまいました。
今回は最新のバージョン(1.0.20)の sysbench を使いたいため、ソースコードからビルドします。

6. sysbenchでテストデータをロードします

同じレコード数、テーブル数のテストデータを作成します。

この時、ランダムデータの分布形式(random numbers distribution)が異なるデータベースを4つ用意します。
ちなみにデフォルトの形式は “special” です。

※ マニュアル上は –rand-type=zipfian も指定できるようですが、実際に試してみると存在しないオプションでした

ロードしたデータの合計サイズは 18GB × 4 = 72GB でした。

移行先(MySQL5.7 + MySQL8.0)構築

次に移行先である MySQL5.7 / MySQL8.0 を構築します。これらは最新バージョンを使用します。

1. MySQL5.7をインストール

2. MySQL5.7の初期設定

3. MySQL8.0をインストール

OCI環境であれば、最初からMySQL8.0の最新バージョンがプリインストールされているはずです。
それ以外の環境であれば、以下のような手順でインストールしてください。

4. MySQL8.0の初期設定

データベースの文字コードをMySQL8.0のデフォルトである「utf8mb4」に変更します。
また、innodb_file_formatパラメータ変数はMySQL8.0で廃止されたため削除しました。

dumpInstance()でバージョンアップ

環境の準備ができましたので、MySQL ShellのdumpInstance()を使ったバージョンアップ(データ移行)を試してみましょう。

1. 移行先サーバ(5.7 & 8.0)にMySQL Shell 8.0をインストール

2. 移行元サーバ(5.6)にMySQL Shell用ユーザを作成

今回の環境では各サーバにプライベートIP(10.0.0.XX)が割り当てられていますので、同セグメントから接続できるユーザを用意します。

3. 移行先サーバから移行元サーバに対して dumpInstance() を実行

dumpInstance()コマンドで指定しているオプションは以下の通りです。

  • defaultCharacterSet : エクスポートするバックアップファイルの文字コード。原則として移行元の文字コードを指定してください。
  • consistent : エクスポートするバックアップファイルの整合性。原則として”on”を推奨。
  • chunking : バックアップを一定のチャンク(かたまり)にまとめるか否か。原則として”on”を推奨。
  • threads : エクスポートを実行する並列スレッド数。移行元サーバのスペックや負荷に応じて引き上げてください。
  • user : MySQLユーザ情報をエクスポート対象に含めるか否か。これを true にしてしまうとインポート時に以下のエラーが発生するため、falseを推奨。

【MySQL5.7サーバ】

合計72GBのデータベースのエクスポートに7分26秒かかりました。

【MySQL8.0サーバ】

4. MySQLユーザ情報のみをエクスポートする

dumpInstance()でエクスポートしなかったMySQLユーザ情報を移行したい場合、mysqldumpコマンドで同情報のみをエクスポート・インポートします。

※ dumpファイルをインポートしたあとは mysql_upgrade (8.0の場合は mysqld –upgrade=FORCE)を実行してください

※ DB単位の権限(GRANT … ON “DB名”.xxx)を付与しているユーザがいる場合、mysql.dbデータベースも移行する必要があります

5. 移行先サーバに移行元サーバのデータをインポートする

インポートにはloadDump()コマンドを使用します。指定しているオプションは以下の通りです。

  • loadDdl : エクスポートされたDDLを実行します。今回は移行先MySQLが空なので、”true”で問題ありません。
  • ignoreVersion : エクスポート元のMySQLとインポート先のMySQLのバージョンが異なるため、このオプションは”true”にします。
  • threads : エクスポートを実行する並列スレッド数。移行先サーバのスペックや負荷に応じて引き上げてください。

【MySQL5.7サーバ】

合計72GBのデータベースのインポートに51分34秒かかりました。

※ インポート時に”row size too large”エラーが発生した場合、innodb_strict_mode変数が原因の可能性があります(5.6ではデフォルトOFF、5.7~はデフォルトON)

【MySQL8.0サーバ】

移行元の文字コードはutf8(utf8mb3)ですが、MySQL8.0では新しくデフォルトになった utf8mb4 を利用したい場合は、エクスポートされたDDL(CREATE TABLE)の “DEFAULT CHARSET=utf8” の箇所を utf8mb4 に変更します。

DDLは以下のように DB名@TABLE名.sql ファイルにまとめられていますので、これらの該当部分をまとめて置換してしまいましょう。

文字コードの変更が完了したら、インポートを実行しましょう。

これでアプリケーションの向き先を移行先に切り替えてしまえば、バージョンアップは完了です。

6. 移行先サーバと移行元サーバの間でレプリケーションを設定する

MySQL5.6 と MySQL5.7 の間であればレプリケーションが利用できます。もし設定したい場合は、エクスポートしたフォルダに含まれる「@.json」ファイルに記録されたバイナリログポジション(or GTIDポジション)をもとに、「移行先 → 移行元」のレプリケーションを設定してください。

なお、MySQL5.6とMySQL8.0のレプリケーションはサポート外のためご注意ください。

おわりに

以上、MySQL Shellの dumpInstance による論理バックアップを使ってMySQL5.6をバージョンアップする手順について紹介しました。

この手法は単に論理バックアップによるインポート・エクスポートを高速化するだけでなく、新環境でDDLの変更(文字コード変更、インデックス追加など)を手軽に実施することができることもメリットの一つです。

もし、MySQL5.6のサポート切れに伴いバージョンアップを検討している方がいたら、その手助けとなれば幸いです。
また、環境によっては上記のような手順でスムーズに移行できない、もしくは心配な点があるというケースもあるかと思います。そうした場合は、ぜひ以下の問い合わせフォームより弊社までご相談ください。

Return Top