本番稼働中のDBをAurora MySQL バージョン2からAurora MySQL バージョン3へアップグレードしました!
インフラチームのtakaseです。
弊社サービスであるLinyではDBとしてAurora MySQLを使用しています。
今回、Aurora MySQL バージョン2からAurora MySQL バージョン3にアップグレードするにあたって起こったことなどをまとめていこうと思います。
始めに
2023年1月にサービス停止を伴うメンテナンスの一環としてAurora MySQL バージョン1からAurora MySQLバージョン2へのアップグレードを行いました。
この際に自分を含めた作業にあっていたエンジニアは
今回Aurora バージョン2にバージョンアップしたし、2年ぐらいはDB周りでダウンタイムが発生するメンテナンスはしなくてもよさそうだな
と思っていました...、そうあの時までは...
唐突にやってくるEoLのお知らせ
Aurora バージョン2へのアップグレードから8ヶ月が経過した2023年9月、AuroraではないマネージドなDBサービスであるRDS for MySQL 5.7の標準サポートが2024年2月29日をもって終了することが発表されました。
Aurora バージョン2はMySQL 5.7互換のサービスのため、そのうちAurora バージョン2のEoLも発表されてもおかしくないということでDBアップグレードに向けて情報収集から動き出しました。
そして2023年11月始め...、奴がやってきます。そう、Aurora バージョン2のEoLのお知らせです。
幸いにもEoLまで1年前のお知らせでしたが、アップグレードに向けての準備を少しずつですが開始していたのとAurora バージョン3で追加される機能を使って性能向上を図りたいというエンジニアの声を受けて、1月末頃にアップグレード作業を行えるように準備を本格化していきました。
この時の私
年の始めに「2年ぐらいはダウンタイムが発生するメンテナンスしなくてもよさそうだ」と思ってたんだけどな...
DBアップグレードに向けてやったこと
MySQL 8.0のリリースノートを確認
Aurora バージョン3はMySQL 8.0互換のため、MySQL8.0による変更を最初に確認しました。
主に以下のことに注目しながらリリースノートの中身を確認していきました。
- MySQL 8.0にて廃止になるもの
- MySQL 8.0にて非推奨になるもの
- デフォルトの設定値が変わるもの
特にMySQL 8.0にて廃止になるものを使っていた場合はこの時点で使わないようにプログラム側やAurora側のパラメーターグループに変更を加えます。
このタイミングでは廃止になるものをLinyで使っているところは見つかりませんでした。
開発環境のアップグレード
Linyの開発ではdockerを使って開発をしています。LAMP環境をdocker上で再現して開発するというよくあるパターンかなと思います。
(Linyの場合はバックグラウンドで処理を行うworkerが数える気も失せるぐらいたくさんいますが...)
そのため開発環境のDBもMySQL 5.7からMySQL 8.0へアップグレードしていきます。
基本的にはdocker-compose.ymlに書かれたDBのイメージをMySQL 8.0のイメージに書き換えるだけです。
しかし、レプリケーションを組んでいる場合は要注意です!!
本番DBの構成に近づけるべくLinyの開発環境ではレプリケーションを組んでいます。
MySQLのドキュメント にもある通り、masterをアップグレードする前に全てのslaveをアップグレードする必要があります。
そのため、具体的に以下の手順でアップグレードします。
- DBも含めた全コンテナを停止する
- slaveのmysqldコマンドに
--skip-slave-start
オプションをつけMySQLのイメージを変更しslaveのみ起動させる -
[Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.xx' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
のログが出るまで放置
(マシンスペックによるが約1分程度待つ。(アップグレード用の)Temporary Serverのログが最初に出るが、その後に[Server]から始まるログまで待つ) - slaveのmysqldコマンドに付けた
--skip-slave-start
オプションを消し、slaveを再起動する - masterのMySQLのイメージをMySQL 8.0のイメージに変更して、起動する
(マシンスペックによるが約1分程度待つとアップグレードされる。コンテナのログに(アップグレード用の)Temporary Serverのログが最初に出るが、その後に[Server]から始まるログまで待つ)
開発環境での総合的なテスト
MySQL8.0にアップグレードした開発環境とQAチームが作成したテストケースを使いデグレーションが発生していないかの検証します。
ここでデグレーションが発生している場合はプログラムのコードに変更を加えます。
このタイミングではデグレーションしている箇所の発見できませんでした。
クローンを用いての各種時間計測と作業手順書の作成
今回、アップグレード方法にインプレースアップグレードを選択しました。(Blue/Greenアップグレードでアップグレードするにはダウンタイムを発生させてバイナリログを有効する必要があったため)
DBアップグレード作業によってダウンタイムが発生しサービス停止するので、停止時間帯の告知のため作業にかかるおおよその時間を知る必要がありました。
また、アップグレードついでにやっておきたいことというのがインフラチームへの要望として上がって来たので、アップグレード当日のサービス停止に実施するかどうかの判断のためにクローンでの時間計測をしました。
ステージング環境のDBのアップグレード
本番DBアップグレードのリハーサルを兼ねて作成した作業手順書の手順通りにステージング環境のDBをアップグレードしました。
この際にもQAチームの手によって主要機能に異常が無いかの確認やエラー監視の際に新しいエラーが出ていないか確認をしました。
この時に以下のようなエラーを確認しました。
- パラメーターグループで変更してたDBのタイムゾーンがDB上で確認された値と異なる
- DBを再起動することでパラメーターグループとDB上で一致しているのを確認
- 作業手順書にDBアップグレード後に一度再起動させることを追記
- alpine linuxのパッケージ管理システムであるapkを使ってインストールできるmysqldumpを使ってAuroraなDBに対してdumpをしようとした場合にSQLモードの互換性がなくエラーでdumpできない
- apkでインストールできるmysqldumpがMySQL 8.0で削除されたSQLモードが現役であるMariaDBのコードでビルドされたもので、MySQL 8.0互換のDBとしては使えないSQLモードを指定したクライアントが接続してくるので、エラーを返すという感じでした
- Dockerfileで指定するベースイメージをalpine linuxベースからdebianベースのものにし、MySQL公式イメージからコピーする形に変更して、エラーを修正しました
本番アップグレード前後に起こったこと
メンテナンスに向けてサービスを停止し始めている最中にterraform cloudが障害を起こす
terraform cloudでECS上のコンテナ群やALBを管理していたため、障害を発生を受けて予備日に延期することにしました。
障害発生時に停止していた部分はコンソール上から再開させました。
予備日に大雪が降る
2024年2月初めの関東でも大雪が降った日に予備日を設定してました。
そのため、弊社オフィスで集まって行う予定だったアップグレード作業を急遽リモートで行うように切り替えました。
DBアップデート後のウォームアップクエリが終わらない
20億レコード向けてテーブルに対してウォームアップ用のクエリを流したところ実行時間が2時間を超えるクエリが複数発生しました。
そのままではメンテナンス終了時刻を過ぎてもDBに負荷をかけ続けることになるため、クエリの実行をキャンセルしました。
そのため、実行をキャンセルした直後は一部ページで表示に時間がかかるなどの悪影響がでていました。
最後に
この記事にたどり着いたAurora バージョン2からAurora バージョン3へのアップグレード作業担当者の皆さんに少しでも有益な情報を与えることができていたらとても嬉しいです。
最後までご覧いただきありがとうございました。
Discussion