こんにちは。エイチームライフデザインデザイン開発本部の加藤(@mkin)です。最近は "そこの穴、埋めますよ" の精神でエンジニアやってます。
はじめに
2024年2月29日、Aurora PostgreSQL v11の標準サポート終了日に向けて、初めてメジャーバージョンのアップグレードをする機会が得られたので、記録しておきたいと思います。
準備
初めてのことなので、右も左も分からない状態から始まりました。
「よく分からないけど、最新バージョンに上げておけばいいんでしょ?」
というものではなかったのです...
どのバージョンまで上げるか方針を決める
当初は定期的なバージョンアップの計画がありませんでした。せっかくなので、これを機にどういう方針でバージョンアップしていくかを決めることにしました。
作業時点の最新バージョンは v16.1 でしたが、社内の有識者の方々がアドバイスをくださり、最新の長期サポート(LTS)バージョンに追従することにしました。
LTS バージョンの特徴は以下の通りです。
- 非 LTS バージョンと比べて、長く使用することが可能で、アップグレードサイクルが少ない
- セキュリティのパッチやバグ修正が長期間提供されるため、システムの安定性と信頼性を確保できる
LTS バージョンの制約の一つに、最新バージョンの新規機能を使えないことが挙げられます。なのでサービスの特性も判断軸になりますね。今のサービスは最新機能を使う予定はなかったので問題なかったです。
もし、常に最新バージョンに追従する方針にしていたら、インフラ専任のエンジニアが必要になることでしょう。 私たちのチームリソースが潤沢にあるわけではないので、LTS バージョンに追従することで、保守コストを小さく抑え、ユーザー価値に繋がる開発にリソースを割きたいな〜と思います。
というわけで、当時 AWS が公開していた 最新の LTS バージョン PostgreSQL 14.6 まで上げることにしました。
調査
対象バージョンが決まったものの、メンバーの入れ替えで聞けなかったり、ドキュメントも残されていない状態でした。 そこで、まずは現状の把握! ということで、現行のデータベースの設定を確認していきました。
パラメータグループで変更している項目の探し方
データベースには挙動やパフォーマンスを調整するための DB パラメータグループという設定があります。また、設定項目には即時反映されるものと再起動が必要になるものもあるので最初に調査しておく必要があります。
Terraform などの IaC を導入していたらそちらを確認すればOKですし、AWSコンソール上で私が分かりやすかった方法は、DB クラスターやインスタンスに設定しているパラメータグループを開いて「ソース」でソートをかけて「Modified」になっている項目を探すことでした。 以下のサンプル画像のパラメータグループでは、timezone が Asia/Tokyo に変更されていることが分かります。
パラメータグループの比較
アップグレード対象バージョンのパラメータグループを作成し、項目の比較をすることで、廃止になった項目や追加項目とそのデフォルト値が何か?といった更に突っ込んだ調査ができるようになります。
下の画像では、左側が v11、右側が v14 のDBクラスターのパラメータグループです。ここで表示された項目については、リリースノートなどを読んでアプリケーションへの影響を調べました。どのサービスでも大きく影響がありそうな項目を紹介すると、password_encryption
というパスワードの暗号化方式が、MD5 から デフォルト値の scram-sha-256 に変更されたことでしょうか。クライアントのバージョンによっては scram-sha-256 に対応していないこともあるようなので気をつけた方が良さそうです。
使っている拡張機能
リリースノートを読んでいると、拡張機能の修正や機能追加があるので、該当の拡張機能を使っている場合、設定を見直したほうが良いなと思います。
有効にしている拡張機能は以下のコマンドで調べることができました。
SELECT * FROM pg_extension;
アップグレード後の切り戻し方法を検討
アップグレード前の動作検証はもちろんやりますが、万が一、数日後に元のバージョンに切り戻すことになったらどうしましょう。バージョンアップから切り戻しまでに発生したトランザクションデータを維持する必要があります。
今回は、これを解決するために論理レプリケーションを使いました。論理レプリケーションは、データベース間でデータの複製を行う手法の一つです。通常、一方のデータベース(パブリッシャー)がデータの変更を送信し、それを受け取る別のデータベース(サブスクライバー)が変更を再現する仕組みになっています。
これにより、もし元のバージョンに切り戻す際は、アプリケーションのDBホストをサブスクライバーに変更することで実現できます。
論理レプリケーションするときの注意点2つ
1つ目は、サブスクライバー側のid等のシーケンスは更新されないことです。なので、下記のような id の MAX 値をシーケンスにセットするクエリを事前に用意しておきました。
SELECT SETVAL('hoge_id_seq',(SELECT MAX(id) FROM hoge));
2つ目は、プライマリーキーが存在しないテーブルがある場合、論理レプリケーションができません。事前にプライマリーキーを設定しておくか、同期が不要なら論理レプリケーション対象テーブルから除外することも検討してください。 プライマリーキーがない状態で論理レプリケーションを動かすと、エラーが発生して全ての論理レプリケーションが停止することを確認しました。おそろしや〜。
手順書を書く
頭の中にある手順をドキュメントに書きました。ざっくりと以下の流れです。
# 正常系(v11 から v14 にあげる手順) 1. アプリケーションをメンテナンス画面に切り替える 2. メジャーバージョンのアップグレード(自動的にスナップショットが作成される) 3. スナップショットから切り戻し用のDBクラスターを作成 4. アップグレードしたDBの統計情報の更新 5. 論理レプリケーションの設定 6. 動作確認 7. メンテナンス画面を解除 # 異常系(v14に上げた後に問題があり戻す手順) 1. アプリケーションをメンテナンス画面に切り替える 2. 論理レプリケーションを停止 3. サブスクライバーDBのシーケンスを更新 4. アプリケーションのDBホストの向け先を変更 5. 動作確認 6. メンテナンス画面を解除
書き出してみて分かったこともありますし、有識者の方からのフィードバックも得られました。
- それぞれの作業時間=アプリケーションの停止時間ってどれくらい?
- サンプルの設定コマンドは分かるけど、実際のコマンドはどうなるの?
- 異常系の判断基準はあるの?(逆に変化があっても異常じゃないと判断するもの)
- etc...
ステージングでの動作確認
手順書に従って本番を想定したアップグレード作業を行い、分かったことを手順書に反映していきました。
- アップグレードやDBクラスターの新規作成、統計情報の更新などに要する時間
- 実行コマンドと期待する結果
- 設定値(パラメータグループやDB インスタンスの名前など)
動作確認をするにつれて、手順書がブラッシュアップされていくのが楽しかったです。
さいごに
初めての Aurora PostgreSQL メジャーバージョンのアップグレード作業だったので、とにかく有識者の方のアドバイスがありがたかったです!親切・丁寧に説明いただけてエイチームで働く人の良さを改めて感じました。
今回、詳細に手順書を残せたので、今後アップグレードを任された方でも、内容を把握できる状態になったんじゃないかなと思います。その頃にはもっと簡単な方法が出てるかもしれませんけどね!
この記事が誰かの参考になったら幸いです。