先日から MySQLサーバー 5.7 を 8.0 に更新するために苦戦していますが、ようやく目処が立ちました。
過去何度も書いていることですが、MySQLバージョンに関して、WordPress を使うために必要だからインストールしているだけであって、特にMySQLに関して xx バージョンを使いたいとか、MySQL のXXという機能を使いたいというような思い入れはありません。単に安全で安定しているMySQLバージョンを使いたいだけ。
現在は、一台のサーバーハードウェア上に、Apache 2.4 とMySQL 5.7 が稼働していて、MySQL 5.7 がサポート終了間際にの状況。
利用者は私だけなので、サポート切れしても管理は続けられるので放置してもいいのですが、WordPress側に何か脆弱性が見つかった時に、その影響でMySQL側のデータベースが壊される可能性があるので、サポートバージョンの最新に保っておくのが、安心運用するための第一歩。
まず、Web検索して、WordPress 運用している人が、MySQLデータベースを5.7系から8.0系に上げた事例を検索したのですが、具体例が全然見つからない。参考にしたいのですけどね。
5.6系→5.7系 のような5系列のバージョンアップじゃないので、サイトを動かしたまま、いきなりMySQL5.7を削除して、8.0をインストールするようなやり方は怖くてできません。
なので、動作と引っ越し手順を確認するため、次の手順を試してみます。
- Raspberry Pi 2 V1.1 上で FreeBSD 13.2 を動かして、
- この FreeBSD/Arm7(32bit) 上に MySQL 5.7をインストール、
- 本番サーバーのMySQL5.7 から mysqldump でデータベースをダンプ
- FreeBSD/arm7 にsql dumpデータをコピーし、MySQL5.7 でリストア
- FreeBSD/arm7/MySQL5.7 の設定変更と、Webサーバー側の wp-config.php の記述を変更し、WordPressが外部データベースを利用するようにして動作確認。(データベースはそのままで、HTTPとSQLを分離しただけ)
- 動作確認後、FreeBSD/arm7からMySQL5.7を抜き、MySQL8.0をインストール
- MySQL5.7データベースをMySQL8.0形式に変換する ← 作業前はこの方法がわからん
恐らくこうやったらできるんじゃない?と考える方法は、WordPress のエクスポートとインポートを使う以下の手順で、MySQL内で更新できなかった場合はこの方法を使う予定。
- WordPress サイト全体を、エクスポート
- サイトを停止する(外からアクセスできないようにファイヤーウォールで停止させる)
- MySQL5.7サーバーだけ削除し(データベースファイルはバックアップのため残す)リネーム。
- MySQL8.0 をインストールし、稼働させ、5.7と同じアカウントとデータベーステーブルを作る。
- 空っぽのWordPress サイトのコントロールパネルからアクセスして、上記1でエクスポートしておいたデータをインポートする。
- サイトの数だけ繰り返す
- サイトを外部からアクセスできるように、元に戻す
この手順なら、MySQL8.0とWordPressの接続さえできればサイトは動くはず。
問題は、記事ではない統計情報まで退避、復元可能かどうかということ。エクスポートしたデータを見てみないと判断できませんが、プラグインが管理している統計情報までは退避できないのではないかと思います。
以下テスト内容。
FreeBSD/arm7+MySQL5.7でデータベースを起動
前のメモで構成したARM7 FreeBSD13.2 に pkg install で mysql57-server をインストール。
- rc.conf に 「mysql_enable=”yes”」と書いて、service コマンドで、MySQLを起動。
- mysql の初期 root パスワードは、rootディレクトリの隠しファイルに入っている。
本番サーバーの MySQL5.7 のデータベースをダンプ
mysqldump コマンドを使ってダンプ。必要なコマンドオプションを付け忘れると、リストア時に途中で止まる。
このページの情報を参考にして、全データベースバックアップを行いました。
"mysqldump --single-transaction -u root -p -A > wordpress.sql"
を、試したところ、レストア時に、
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don’t want to restore GTIDs, pass –set-gtid-purged=OFF. To make a complete dump, pass –all-databases –triggers –routines –events.
と出て、最後の最後でリストアが失敗する。メッセージにあるとおり、–set-gtid-purged=OFF を付けて、ダンプをやり直す。
"mysqldump --single-transaction --set-gtid-purged=OFF -u root -p -A > wordpress.sql"
追記:引っ越し先データベースが空っぽの場合は、上記のコマンドでいいのですが、引っ越し元より古いデータが残っている場合は、既存データベースを事前に消す必要があるため、mysqldumpコマンドのオプションを追加します。
"mysqldump --single-transaction --set-gtid-purged=OFF --add-drop-table -u root -p -A > wordpress.sql"
–add-drop-table オプションは、dump 内に含まれる create table コマンドの前に、drop table を実行する 古いデータベースを上書きするためのオプション。
引っ越し先MySQL5.7サーバーでの作業
まずは、ftp でダンプファイルを引っ越し先に持ってきます。ダンプの内容はsqlコマンドの羅列なので、バイナリ転送でもASCII転送で構わない。
続いてリストア。コマンドは簡単。
"mysql -u root -p < wordpress.sql"
ただし、root パスワードが必要。5.7の場合、初期パスワードは、/root/.mysql_secret にある。
リストアが成功した後は、ダンプファイル中にある root パスワードが有効になる。
本番WordPressから、FreeBSD/arm7 + MySQL5.7 に接続
MySQL側の作業
- my.cnf 中の「bind-address = 127.0.0.1」を削除か、コメント。ローカルアクセス使わないなら、リモートIPにすればいいだけかも。(まだ、やってないけど)
- WordPress 用アカウントを複製して、リモートアクセス用mysqlアカウントを追加する(phpMyAdminを使った)
WordPress側の作業
- wp-config.php 内のmysql用記述を 「localhost」 から FreeBSD/arm7 ホスト名に書き換える
問題は、この MySQO 5.7 データベースを、どうやって 8.0 データベースにするのか?
成功するまでに試したのが、MySQL8.0 をインストールした直後の、空データベースにダンプファイルを読み込ませる。→ 途中でエラーになって終了。
Web検索するものの、WordPress 利用者が MySQL5.7データベースをどうやって8.0 データベースに変換したか、記事が見つからないのよ。
検索し続けていたら、本家Oracle の MySQLバージョンアップセミナービデオが見つかりました。
長い、意味のない、バージョンアップのメリットやら、バックアップの話を過ぎ、29:30 あたりからようやく目的のバージョンアップ方法の説明が始まりましたが、内容は期待外れ。方法は二つで、
- MySQL5.7の稼働を止めて、MySQL8.0をインストールするか
- 新しい環境に、MySQL8.0を入れ、データベースを丸々バイナリーコピーし
- mysql_upgrade コマンドでアップグレード
するしかないみたい。検索したのがばかばかしくなるほど基本的な情報でした。しかし、本家の案内で自信をもって作業できます。
MySQL5.7データベースを8.0に変換する
なせ情報を探し回ったかというと、ここ数日、ダンプファイル リストア作業をテストするため、MySQLを5.7にしたり8.0 にしたりする作業を繰り返し、エラーと解決を繰り返してきました。SQLコマンドを楽に発行するために phpMyAdmin を使おうとして Apacheを新規に起動させるのに苦労したり、phpMyAdmin のエラー表示問題まで加わって、すごく時間を消費してしまいました。
特に、MySQL5.7を抜いて8.0を入れようとすると、「WARNING: failed precmd routine for mysql」」が出てmysql起動失敗してしまったり、バージョン毎で管理者パスワードの扱いが異なっていたりで、MySQL自体を触りたくなくなってきます。MySQL5.7 に本番サーバーのデータを読み込ませることには成功したけど、8.0に上げたら、また mysql が起動しなくなるんじゃないかとすごく不安。できることならここで放置したい。
けど、進めるしかない。まあ、テストサーバーだし、壊れても何も失うものはないし。いやいや、もう一回テストサーバーを作る時間を失うでしょう。SDメモリやSSDも少し摩耗したはずだし。と自己格闘。
MySQL5.7を止めた後、アンインストールし、etc/mysql下の my.cnf を消す。5.7のmy.cnf が残っていると、WARNING: failed precmd routine for mysql になる(と思う)。
MySQL8.0サーバーを入れる。
/var/db/mysql ディレクトリーは全部 5.7のものなので、ファイルが存在するのが影響して failed precmd になる不安はあるものの、
service mysql-server start
で MySQL8.0サーバーを起動させる。
2,3秒でエラーが返ってくるかと思いきや、30秒くらいでプロンプトが戻ってきた。
動いたよ~。
では、次に何をする?プロセスを見てみたところ、たくさんのmysql が動いていて、中には mysql_upgrade も見えたので、自動でデータベースをコンバートしてくれている模様。
本当に動いているのか?mysqlは、今、再起動できないので、mysql の動作確認ができるのは phpMyAdmin だけ。phpMyAdmin を立ち上げてみると、、、、、つながらない。。。。。
プロセスでは見えるし、ログファイルを見てみると、初期化しているっぽい。ログを転記すると、
2023-10-19T18:40:53.786016Z 0 [System] [MY-010116] [Server] /usr/local/libexec/mysqld (mysqld 8.0.33) starting as process 4448 2023-10-19T18:40:54.117255Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started. 2023-10-19T18:42:25.572128Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended. 2023-10-19T18:43:25.214750Z 2 [System] [MY-011003] [Server] Finished populating Data Dictionary tables with data. 2023-10-19T18:43:50.757595Z 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80033' started. 2023-10-19T18:45:54.846213Z 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80033' completed. 2023-10-19T18:47:23.507328Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. 2023-10-19T18:47:23.520994Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel. 2023-10-19T18:47:23.687685Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/tmp' in the path is accessible to all OS users. Consider choosing a different directory.
自動でデータベース形式が変換されました。手動で mysql_upgrade コマンドを使う必要なし。
また、データベース変換中は、ユーザーアクセスを禁止していたみたいで、(SDメモリだったので)5分くらい待つと phpMyAdminが使えるようになり、my.cnf の bind-address を編集して、外部アクセスも可能になりました。
テスト完了。MySQLサーバーを 5.7 から 8.0 に上げる手順を最低限理解できました。
このまま本番に移行するなら、ファイヤーウォール、アクセスコントロール、ロギング強化など対策が必要になります。
うまく動いたのでこのまま使えばいいじゃん。ってところですが、データベースがちょっとテストするつもりでインストールした TLC SDメモリの上にあるっていうのは、いつデータにアクセスできなくなるかと不安すぎる。せめて高耐久SDかMLC、SSD上に置きたいので、今後、別サーバーか別のストレージを立ててやり直す予定です。Raspbery Pi 2 だと主記憶が1GBなのでスワップしちゃうんですよ。1枚のSDメモリをスワップデバイスと同時にデータ領域として使いたくはない。スワップ領域の摩耗でデータ領域を壊されたくない。
私の WordPress データベース アップグレードに関しては目処が立ちました。私の場合は単一データベース、単一アカウントを使っているので、一つ引っ越せば作業は終わり。しかし、複数サイトを複数データベースに分けていたらどうなったんだろう?また、同時に引っ越し作業が出来ず、分けて行わなきゃいけない場合は?
オリジナルサーバー上で直接本番作業を行わなきゃいけない状況だったら、どうしたらよいかわからないところでした。テストサーバーって重要。予定していた Raspberry Pi 4 で MySQL8.0 が動かなかったのが時間を浪費した原因かも。