MySQLのバージョンアップ(訳注 : 原文ではupgrade、以下同じ)はどこかで必要になるタスクだし、我々Percona SupportでもMySQLバージョンアップのベストプラクティスについての色々な質問を受け付けている。この記事では、色々なシナリオにおけるMySQLバージョンアップの推奨できる方法に焦点を当ててみたい。
MySQLのバージョンアップはなぜ必要になってしまうのか?その理由は色々だが、新機能が必要、パフォーマンスの改善、バグ修正などがあるだろう。しかし、アプリケーションと組み合わせた上で事前に広範囲なテストをしておかないと、リスクの大きい作業になってしまう。それは、アプリケーションが正しく動作するのを妨げて破壊してしまうこともあり得るし、バージョンアップ後にパフォーマンス問題が起きるかもしれない、といった理由からだ。私は、そういったテストに加え、MySQLやPercona Serverの新リリース情報にも注意しておくことをおすすめする。最新バージョンで何が変わったのかということだ。もしかしたら、最新リリースで、あなたが直面している問題を解決する修正があるかもしれないのだ。
SQLダンプを使ってマイナーバージョン間でバージョンアップする
MySQLやPercona Serverの5.1から5.5、あるいは5.5から5.6といった、マイナーバージョン(訳注 : 原文ではmajor versionだが意味的にマイナーバージョンのことを指しているのでこの訳。以下同じ)間でのバージョンアップのことだ。
初めに言っておくと、メジャーバージョン内だからといって、そのバージョンアップ作業は簡単でもリスクフリーでもない。まず最初に、MySQL 5.5向けやMySQL 5.6向けのような「Upgrading from Previous Series(前のマイナーバージョンからのアップグレード)」の類のドキュメントを読むべきだ。こういったドキュメントを読む際は、「Incompatible Change(互換性のない変更)」と書かれた節全てに特に注意して、それらの変更が自分の環境に影響がないかを確認しよう。ここには、変数名の変更や、古い変数の廃止、新変数の導入といった設定の変更内容が書かれているので、それにしたがってmy.cnfを書き変えよう。Percona Server特有の変更については、Percona Server 5.5向けはこちら、5.6向けはこちらを参照してほしい。
取り得るバージョンアップのアプローチはいくつかあるが、1つはレプリケーションのトポロジとデータ量を考えると一番実現性が高そうなもの、もう1つは他の方法と比べて安全なものがある。Percona Server 5.5から5.6にバージョンアップする例で手順をお見せしよう。
一般的には、MySQLのバージョンアップには2つのタイプがある。
- インプレース : 新しいMySQLのバージョンでも現行のdatadirと同じものを使い、バイナリ類をバージョンアップした後にmysql_upgradeを実行するパターン
- SQLダンプ : 古いバージョンからダンプを採り、新しいバージョンにリストアするパターン(mysqldumpや、mydumperのような代わりのツールを使う)
通常は2つ目の方法が安全だが、バージョンアップのプロセスにより時間がかかるだろう。
理論上、最も安全なシナリオはこうだ。
- 全てのユーザ権限をダンプ(pt-show-grantsを使用)
- 全てのデータ(mysqlデータベースを除く)を5.5からダンプし、5.6にリストア
- ユーザ権限をリストア
標準的な手順は以下の通り(作業前にアプリケーションからの書き込みは止めておこう)。
1. ユーザとパーミッション情報を収集する。ユーザ権限を丸ごとバックアップすればよい。
$ wget percona.com/get/pt-show-grants;
$ perl pt-show-grants --user=root --ask-pass --flush > /root/grants.sql
2. 5.5インスタンスからmysql、information_schema、performance_schemaデータベースも含む論理ダンプを生成する。
$ mysql -BNe "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mysql', 'performance_schema', 'information_schema')" | tr 'n' ' ' > /root/dbs-to-dump.sql
$ mysqldump --routines --events --single-transaction --databases $(cat /root/dbs-to-dump.sql) > /root/full-data-dump.sql
3. 5.5インスタンスを停止する。
$ service mysql stop
or
$ /etc/init.d/mysql stop
4. 旧データディレクトリをリネームする(datadirが/var/lib/mysqlの場合。環境によって読み替えよう)。
$ mv /var/lib/mysql/ /var/lib/mysql-55
5. 5.6をインストール(バージョンアップでない時と同じように)。yumやapt-getのようなパッケージマネージャを使用していないなら、mysql_install_dbやmysql_upgradeを実行する必要があるかもしれない。
6. バージョンアップされたMySQLにユーザ情報をロードする。
$ mysql -uroot < /root/grants.sql
7. データをロードする。
$ mysql -e "SET GLOBAL max_allowed_packet=1024*1024*1024";
$ mysql -uroot -p --max-allowed-packet=1G < /root/full-data-dump.sql;
この時点で全てのテーブルは作り直されて5.6にデータがロードされるので、全てのバイナリ表現も5.6のものになっている。これで、最もクリーンで安定したバージョンアップの手順が完了し、アプリケーションはサービスを開始できるだろう。その意味で、この方法は標準のMySQLからPercona Serverへのバージョンアップにも同じ方法が使えることをここで言っておく価値があるだろう。つまり、例えばOracle MySQL 5.5からPercona Server 5.6へもだ。なお、ここで書いたMySQLのバージョンアップ方法は、MySQLからすぐに乗換え可能な製品であるPercona Serverでも同じものが使える。
「SQLのダンプ」は、論理バックアップでもおなじみだ。リストアの面でもこの方が安全で、リストア時には、新しいMySQLのバイナリのフォーマットで全てのテーブルが作られるので、互換性の問題が関係なくなるのだ。ただ、ギガバイト、テラバイトといったようにデータが大きくなると、この方法は非常に時間のかかるアプローチになってしまう。一方、InnoDBの表領域がゼロから作り直されるので、そういった大きなデータセットをダンプ・リストアすることで、最適化、デフラグがされて、相当な空き容量が確保できるという利点もある。データが高頻度で更新されたり削除されたりしていた場合は、この効果はさらに大きくなる。
インプレースでのマイナーバージョン内のバージョンアップ
この方法は、同じシリーズ、つまりMySQL 5.5.35から5.5.38や、Percona Server 5.6.14から最新の5.6.20へのバージョンアップだ。
この方法はインプレースアップグレードと呼ばれ、新しいバイナリパッケージをインストールしてから、システムテーブルのチェックや更新が必要ならそれを行うmysql_upgradeスクリプトを実行する。この場合も、新機能やバグフィックスが書かれたリリースノートを確認することを強くお勧めする。Percona Server 5.5とPercona Server 5.6にそれぞれある。
Percona Serverに関しては、Percona特有の機能に焦点を当ててバージョンアップする際の詳細を書いたドキュメントが、5.5向け、5.6向けにそれぞれある。このドキュメントでは、yumやaptパッケージマネージャを使ったインプレースアップグレードの方法もカバーされている。
なお、大事を取って、上に書いてきたようなmysqldumpや、並列バックアップ・リストア・論理バックアップができるmydumperを使った論理ダンプによるバージョンアップを行うこともできる。やはりそれが最も安全なバージョンアップのアプローチだ。
マイナーバージョンをスキップした最新版へのバージョンアップ
これは、MySQL 5.1を飛ばして5.0から5.5にバージョンアップしたり、5.5を飛ばして5.1から5.6にバージョンアップするような例である。MySQL 5.0を使っているユーザは今やほとんどいないだろうが、5.0から5.6にバージョンアップすることも含まれる。これも、Percona Serverでも同じ手順になる。
この節では、Oracle MySQLあるいはPercona Server 5.1を、5.5を飛ばして5.6にバージョンアップすると仮定しよう。
まず何よりも、これは容易でないバージョンアップであり、MySQLバージョン間の大きなステップを登るものだということだ。つまり、リスクが大きい。バイナリアップデートだけを使ってバージョンアップするのはサポートされておらず、バージョンを飛ばしてやるのは安全でないので、5.0->5.5や5.1->5.6、ましてや5.0->5.6といったバージョンアップはしてはならない。問題の1つは、各MySQLバージョンに対する変更は、全てが後方互換性のあるものだとは限らないことだ。変更内容によって、どのようにデータを扱うかに対して、あるいは、SQL、MySQLサーバ、ストレージエンジンの内部に対してどう動作するかが変わる。もう1つの問題は、MySQL 5.0と5.6の間では、結果がすっかり変わってしまったり予期せぬ動作をしてしまうようなデフォルト設定値の多くに変更があることだ。例えば、MySQL 5.5からデフォルトストレージエンジンがInnoDBになっているし、5.6からはInnoDBでテーブルごとに表領域が分離され、GTIDレプリケーションが導入された。さらに、ここに挙げられないほどのたくさんの細かなことがある。これらの変更は全て、上でも挙げた「**Upgrading from Previous Series」のドキュメントに書かれている。
マイナーバージョンをスキップしてバージョンアップするのを強く非推奨とすることは、明言しておく意味がある。MySQL 5.1から5.6へのバージョンアップは、一度ではすべきでない。代わりに、5.1から5.5へバージョンアップしてから、5.5から5.6へバージョンアップし、それぞれでmysql_upgradeを実行する方法をおすすめする。上で挙げたようなフォーマットの違いを、手動で吸収してしまえるからだ。
MySQLバージョンアップの事前注意事項
事前注意と言っても、これはバージョンアップ自体の重要な一部分だ。バージョンアップの前に、バージョンアップ先のMySQLで、アプリケーションの全パーツを全体的にテストしておくのを忘れないように。これは、マイナーバージョン間でバージョンアップする場合も、バージョンを飛ばして実施する場合(例、5.1から5.6)も重要だ。
リリースノートを注意深く読み、全ての変更点を検討しよう。Oracle MySQL 5.5と5.6のリリースノートは以下で参照できる。
Percona Serverのリリースノートは、以下で参照できる。
- http://www.percona.com/doc/percona-server/5.5/release-notes/release-notes_index.html
- http://www.percona.com/doc/percona-server/5.6/release-notes/release-notes_index.html
Oracle MySQL 5.6あるいはPercona Server 5.6へのバージョンアップを考えているなら、まず最初に深刻な既知のバグを確認することをおすすめする。注意すべきバグは以下のものだ。
- http://bugs.mysql.com/bug.php?id=66546
- http://bugs.mysql.com/bug.php?id=68953
- http://bugs.mysql.com/bug.php?id=69444
- http://bugs.mysql.com/bug.php?id=70922
- http://bugs.mysql.com/bug.php?id=72794
- http://bugs.mysql.com/bug.php?id=73820
バージョンアップの階層構造
これは、MySQLのバージョンアップにおいて大切なもう1つの観点だ。階層構造に沿ってバージョンアップを行う必要がある。常に推奨されるやり方は、最初に開発・品質管理サーバをバージョンアップし、本番環境に手を付ける前にステージングサーバで実施する。実際のところ、別にバージョンアップ済みインスタンスを用意して、そこでアプリケーションを別にテストすることになるだろう。
テストサーバやステージングサーバでのバージョンアップに満足できたら、本番サーバのバージョンアップを始められる。レプリケーション環境では、スレーブをまず1台ずつバージョンアップし、最後にマスタをバージョンアップすることを強くおすすめする。実環境では、ある1台のスレーブを先にバージョンアップして、念のため数日動かして、その間パフォーマンスを注視することになるだろう。レプリケーションを使用していない場合でも、レプリカを作って新しいバージョンのMySQLをそこで先にテストするのはよいだろう。このテスト結果に満足したら、残りのスレーブ、最後にマスタをバージョンアップする。
MySQLのバージョンアップを手助けするPerconaのソフトウェア
どんなMySQLのバージョンアップでも、Percona Toolkitは救いの手を差し伸べるだろう。Percona Toolkitは、色々なことを手助けするツール群を含んでいる。
pt-upgradeは、そういったツールの1つだ。これをつかうと、新しいMySQLインスタンスが、旧バージョンと同等の速さであるクエリを実行できるかをテストできる。5.1から5.6で、クエリオプティマイザにはいくつかの大きな変更が加えられており、データ統計も刷新されているので、クエリ実行計画は変更される可能性がある。オプティマイザにどのような変更があったかはマニュアルを参照しよう。
pt-query-digestは、バージョンアップ時に役立つもう1つの素晴らしいツールだ。旧環境と新環境において、バージョンアップ前後のスロークエリログを再実行でき、クエリパフォーマンスの検証が可能だ。
あらゆるMySQLユーザにクエリパフォーマンスの統計を提供するサービスである、Percona Cloud Toolsも役に立つだろう。まだパブリックベータなので、今なら無料で登録できる。他のツールと違ってPercona Cloud Toolsでは、MySQLバージョンアップ後のクエリのパフォーマンスをビジュアルに確認できる。
MySQLバージョンアップの前に、データをバックアップしておくことを強くお勧めする。Percona XtraBackupは、(全てのPerconaソフトウェアと同じく)フリーでオープンソースだ。これは、読み書きの性能を犠牲にすることなくオンラインでデータをバックアップするホットバックアップツールで、小さいインパクトでデータをバックアップできる。
大事なことを言い忘れていたが、「Upgrading MySQL」という記事もやや古いが役に立つだろう。また、「Upgrading to MySQL 5.6: Best Practices」というwebinarも得る所が多いだろう。どちらもPercona CEOのPeter Zaitevのものだ。
まとめ
MySQLのバージョンアップはシンプルなタスクなように見えて、そうではない。この記事では、あり得るであろうMySQLのバージョンアップシナリオのほとんどをカバーしたつもりだ。もう一度、新バージョンを「動かす」前にアプリケーションをテストしておくことをおすすめする。さもないと、アプリケーションは壊れてしまう、あるいはパフォーマンスを改善するどころか悪化させることになるだろう。最後に、バージョンアップが何らかの原因でうまく行かなかったときにダウングレードする方法を用意しておくこともおすすめしたい。正しいダウングレード手順を用意しておくことで、問題が発生した時のダウンタイムを最小化出来る。あなたのコメントや質問をお待ちしている。