はじめて Aurora PostgreSQL v11.18 から v14.6 にメジャーバージョンのアップグレードをしたときに準備したこと

:::note
この記事は Ateam Tech Blog の2024年3月22日の記事を再編集したものです
:::

こんにちは！最近は「そこの穴、埋めますよ」という気持ちでエンジニアとして活動しています。

# はじめに
2024年2月29日、Aurora PostgreSQL v11が標準サポートを終了するタイミングで、初めてメジャーバージョンのアップグレードを実施することになりました。この経験を記録しておきたいと思います。

# 準備
初めての取り組みなので、右も左も分からない状態からスタートしました。

「とりあえず最新バージョンに上げればいいのかな？」と思ったのですが、そんな簡単なものではありませんでした。

## アップグレードの方針決定

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/f0a6b9c9-1a8f-47ee-908d-cafa53dbee3f.png)

最初は定期的なアップグレードの計画がありませんでしたが、この機会にしっかり方針を定めることにしました。作業時点での最新バージョンは v16.1 でしたが、社内の有識者たちと相談した結果、**最新の長期サポート（LTS）バージョンに合わせる**ことに決めました。

LTSバージョンの特徴は以下の通りです。

- 非LTSバージョンに比べて、長期間の使用が可能で、アップグレードサイクルが少ない
- セキュリティパッチやバグ修正が長期間提供され、システムの安定性が高まる

ただし、LTSバージョンには新機能が利用できないという制約があります。私たちのサービスには最新機能を使う予定がなかったため、問題にはなりませんでした。

もし常に最新バージョンを追い続ける方針だったら、専任のエンジニアが必要になるでしょう。私たちのチームリソースが限られているため、**LTSバージョンに合わせることで保守コストを低く抑え、ユーザー価値のある開発にリソースを集中させたい**と思いました。

その結果、AWSが公開していた最新のLTSバージョンであるPostgreSQL 14.6にアップグレードすることにしました。

## 調査
アップグレード対象バージョンが決まったものの、メンバーの入れ替わりがあって情報が不足している状態でした。そこで、まずは現行のデータベースの設定を確認しました。

### パラメータグループで変更している項目の探し方
データベースには、動作やパフォーマンスを調整するための「DBパラメータグループ」があります。即時反映される項目と、再起動が必要な項目があるので、事前に調査しておくことが重要です。

もしTerraformなどのInfrastructure as Code（IaC）を使用している場合、そちらを確認するのが簡単ですが、AWSコンソールではDBクラスターやインスタンスに設定されているパラメータグループを開き、「ソース」でソートし、「Modified」と表示されている項目を探すのが分かりやすい方法です。以下のサンプル画像では、`timezone`が`Asia/Tokyo`に変更されていることが分かります。

![DBパラメータグループの変更したソース項目がModifyedと表示されている画面キャプチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/ae802383-d40a-4fdb-bba3-97d2742cdf4a.png)


### パラメータグループの比較
アップグレード対象バージョンのパラメータグループを作成し、現在のバージョンと比較することで、廃止された項目や新しく追加された項目が確認できます。また、そのデフォルト値も把握できます。

![DBパラメータグループの比較アクションの画面キャプチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/5c3dbb1a-e41a-4435-bac5-ded3a03295f3.png)

左側がv11、右側がv14のDBクラスターのパラメータグループの画像を見て、リリースノートを確認し、アプリケーションへの影響を調べました。特に影響を受けそうなのが、`password_encryption`の暗号化方式が`MD5`からデフォルト値の`scram-sha-256`に変更された点です。クライアントのバージョンによっては`scram-sha-256`に対応していないこともあるため、注意が必要です。

![DBパラメータグループの比較で項目のバージョン差異を確認している画面キャプチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/d1a60fc5-5e51-4859-b22b-2acafded1472.png)

### 使っている拡張機能
リリースノートには拡張機能の修正や機能追加が記載されていますので、該当の拡張機能を使用している場合は設定を見直すことが推奨されます。有効な拡張機能は以下のSQLコマンドで確認できます。

```sql
SELECT * FROM pg_extension;
```

### アップグレード後の切り戻し方法の検討
アップグレード前の動作検証はもちろんやりますが、万が一、数日後に元のバージョンに切り戻すことになったらどうしましょう。バージョンアップから切り戻しまでに発生したトランザクションデータを維持する必要があります。

今回は、これを解決するために論理レプリケーションを使いました。論理レプリケーションは、データベース間でデータの複製を行う手法の一つです。通常、一方のデータベース（パブリッシャー）がデータの変更を送信し、それを受け取る別のデータベース（サブスクライバー）が変更を再現する仕組みになっています。

![論理レプリケーションでデータ同期する図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/951eb20e-c72a-433f-af52-bf93c35fccf2.png)

これにより、もし元のバージョンに切り戻す際は、アプリケーションのDBホストをサブスクライバーに変更することで実現できます。

![DNSからサブスクライバーに向け先を切り替える](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/1db59806-1bf9-418f-a45c-862225ce1436.png)

### 論理レプリケーションするときの注意点2つ
1つ目は、サブスクライバー側のIDなどのシーケンスが更新されないことです。事前に下記のようなクエリを用意しておき、シーケンスを設定しました。

```sql
SELECT SETVAL('hoge_id_seq',(SELECT MAX(id) FROM hoge));
```

2つ目は、プライマリーキーが存在しないテーブルでは論理レプリケーションができません。事前にプライマリーキーを設定するか、同期が不要であれば対象テーブルから除外することも検討してください。プライマリーキーがない状態で論理レプリケーションを行うと、エラーが発生し、全てのレプリケーションが停止する可能性があります。

### 手順書を書く
頭の中にある手順をドキュメントとしてまとめました。おおまかな流れは以下の通りです。

```md
# 正常系（v11 から v14 にあげる手順）
1. アプリケーションをメンテナンス画面に切り替える
2. メジャーバージョンのアップグレード（自動的にスナップショットが作成される）
3. スナップショットから切り戻し用のDBクラスターを作成
4. アップグレードしたDBの統計情報の更新
5. 論理レプリケーションの設定
6. 動作確認
7. メンテナンス画面を解除

# 異常系（v14に上げた後に問題があり戻す手順）
1. アプリケーションをメンテナンス画面に切り替える
2. 論理レプリケーションを停止
3. サブスクライバーDBのシーケンスを更新
4. アプリケーションのDBホストの向け先を変更
5. 動作確認
6. メンテナンス画面を解除
```

手順を文書化することで、具体的な作業時間や実行コマンドの詳細も考えることができました。また、有識者からのフィードバックによってさらに精度を高めることができました。

### ステージングでの動作確認
手順書に基づいて、本番環境を想定したアップグレード作業を行い、その結果を手順書に反映させました。

- アップグレードやDBクラスターの新規作成にかかる時間
- 実行コマンドとその期待される結果
- 設定値（パラメータグループ名やDBインスタンス名など）

動作確認を進める中で、手順書がどんどん洗練されていくのを楽しみながら作業しました。

# さいごに
初めての Aurora PostgreSQL メジャーバージョンのアップグレード作業は、ヒントをもらえる有識者たちのサポートが非常に心強かったです！親切かつ丁寧な解説を受けることで、エイチームの良さを改めて感じました。

今回、詳細な手順書を作成できたことで、今後アップグレードに関わる方もスムーズに作業を進められると思います。そのころにはもっと簡単な方法が出ているかもしれませんが。

この記事が誰かの参考になれば幸いです！