AWSのDB、Auroraを使っているみなさま元気でしょうか。Auroraに限らずSaaS的なサービスを使っていると"このバージョンはEOLだ"と言ってバージョンアップが必要になる場合があります。みなさまも覚えがあるのではないでしょうか。
問題はどのようにバージョンアップを行うかです。
今回は、Aurora MySQL (not serverless)でマイナーバージョンアップを行う際にどういう手法があるかを、AWSのドキュメントや実際にやってみた経験をもとに考えたいと思います。Aurora PostgreSQLも同様かもしれませんがそちらは調べていません。
目次
考えられる方法2つ
大まかに、以下2つの方法があるかなと思います。
- RDSに最近出たブルーグリーンデプロイメント機能を使ってバージョンアップ
- インプレースアップグレードを行う(DBのバージョンをそのまま上げる)
- ゼロダウンタイムパッチ適用が効いて接続が切断されずにupgradeが完了する場合もある
他にも手動でブルーグリーンデプロイと似たようなことを行う手法などもあるかと思いますが、RDSのブルーグリーンデプロイメント機能を使う場合と特にメリットデメリットなど変わらないかと思うので今回は割愛します。
そもそもRDSのブルーグリーンデプロイメント機能とは?
AWSが提供するRDSの機能で、既存のDBのデータをコピーした環境が新たに作成されてそちらで動作確認などができ、その後切替をするとDBのDNS名が新旧で切り替わり、アプリケーション側の変更なしでDBが切り替わる機能。
なお、"ブルーグリーン"と聞くと切り戻しも簡単にできそうに思えてしまうが、切り戻しはできない(切替後は新しい方にデータが書き込まれるのでナイーブに考えると"そうだね"、とはなる。新しい方から古い方へデータの反映が必要な場合は自前で頑張ってね、ということである)
それぞれの嬉しい点、使いづらい点
インプレースアップグレード(ゼロダウンタイムパッチ適用を狙いつつ)
嬉しい点
- 非常に気軽。webコンソールで実施しても"ぽちぽちぽち"くらいで完結する
- ゼロダウンタイムパッチ適用 が効いた場合、それまではられていたコネクションの切断すら発生しないで切り替わる
- もしゼロダウンタイムにならない場合でも、20~30秒くらいのダウンタイムで完了する
- Amazon Aurora MySQL のデータベースエンジンの更新 - Amazon Aurora によれば、
更新では、DB クラスター内のすべてのインスタンスでデータベースを再起動する必要があるため、20 ~ 30 秒のダウンタイムが発生します
とある - 実際自分で何度かやった感じ、10秒程度のダウンタイムしか発生していない
- Amazon Aurora MySQL のデータベースエンジンの更新 - Amazon Aurora によれば、
使いづらい点
- 厳密に切り替えの時間が制御しづらい。"大体15分以内には完了するかな"くらい
- 時間がデータ量に関連するかは不明(マイナーバージョンアップでは多分データ量は関係しないが裏は取っていない)
- ゼロダウンタイムパッチ適用が効くかどうかは最後は運(ベストエフォート)。以下を見れば確率を上げることはできるが、確実にゼロダウンタイムパッチ適用が効くとは言えない
- Aurora MySQL DB クラスターのマイナーバージョンまたはパッチレベルのアップグレード - Amazon Aurora
- 実際に12DBやった事例を聞いたが、5/12でゼロダウンタイムパッチ適用が効かなかった。5割以上は効くが、9割効くとは言えない、くらいのイメージでいるといいか。
- ゼロダウンタイムパッチ適用時の性能への影響がよくわかってない。mysqladmin pingを毎秒飛ばしてアップグレードを試していたら、connect-timeoutを1にしている場合は何度か接続が失敗した
- 使ってるバージョンとインスタンスタイプの組によってゼロダウンタイムパッチ適用がそもそも動かない場合がある
ブルーグリーンデプロイメント
嬉しい点
- そこそこ気軽。binlogさえ出力していれば、ポチとしてから1時間くらい待って新しい環境が構築されてから再度ポチとすれば切り替わる
- インプレースよりは手軽さはない
- 切り替え対象の新しいDBができてそれに対して検証を行うことができるため、事前の検証が楽。切り替え時にも"まさに検証を行ったDBをそのまま本番環境に使う"というのはだいぶ気持ちの面で気楽であろう
- 切り替えの時間制御がそこそこできる。大体"ポチッとしてから数分以内に完了するであろう"という確信が持てる(一定時間を過ぎたらロールバックする機能もある)
- ダウンタイムが短いはず。どれくらい短いかはパッと見ドキュメントがなかったが、適当に試したら30秒以内には切り替わった
- ログを見た感じ実際に内部でやっているのは、クラスタの名前の付け替えくらいっぽい?
- デフォルトで切り替え後に旧マスタDBが残っているので、切り替え直後に何かあった際の調査や最悪の場合の切り戻し(切り替えてからの更新内容の反映方法は考える必要があるが)が楽
使いづらい点
- binlog出力が事前に必要。binlogの出力設定を変更するためには再起動が必要
- 最近はbinlogを出力しても性能劣化はあまりないという話(参照: https://developers.cyberagent.co.jp/blog/archives/29925/ の"ベンチマーク"部分)もあったので、基本的にbinlog出力しておくと良いだろうとは思っているしあまりデメリットにはなりづらいと思う
- インプレースアップグレードと比べると全体のプロセスにちょっと時間がかかる
- データの少ないDBでもブルーグリーン作成をポチしてから1時間ほどで準備が整い、それから切り替えボタンをポチすると5分くらいで切り替わる、という世界
- 遅延読み込みの対処が必要
- 以下の"ブルー/グリーンデプロイを作成する際の遅延読み込みの処理"にある通り、新環境が構築されたすぐにはデータ読み込みのペナルティが存在し、暖機運転などが必要になる
- ブルー/グリーンデプロイの作成 - Amazon Relational Database Service
筆者はどうしている?
- インプレースアップグレードのゼロダウンタイムパッチ適用が強力かつダウンタイムが発生した際のペナルティも少ないので、マイナーバージョンアップの際は基本的にそちらを狙っていけばいいんじゃないかなと思っていてインプレースアップグレードをしている
- 常にbinlogを出しておいて、どのバージョンどのインスタンスタイプでも、メジャーバージョンアップの場合でも同じ手順を使うためにブルーグリーンデプロイメントを常に採用するという判断もよさそうに感じる
- メジャーバージョンアップの際は事前に動作確認できるという面でもブルーグリーンデプロイメントは非常に便利