Aurora(PostgreSQL) 13→16 Blue/Green アップグレード(staging 実DB 直接適用版 / Clone なし)
本書について
staging の既存 Aurora クラスタ本体を Clone せず、直接 Blue/Green でアップグレードするためのドライラン手順。 本番(procedure-production.md)と DB レベルの手順(CPG 付け替え+再起動・Blue/Green 作成・Green 検証・Switchover・拡張更新・後始末)は完全に同一。違いは「環境(staging)」「周知・メンテ枠・監視の厳密さ」「Terraform の apply 先」だけ。
drift 防止のため、手順コマンドは本書に重複させない。 実コマンドは procedure-production.md のフェーズ A〜E をそのまま参照し、本書は staging 固有の差分 と 本書だけで行うライブ複製検証 を記載する。
⚠️ 開始前チェック(staging 取り違え防止・最重要)
本書は production 版のコマンドを見ながら作業するため、production 値を staging に読み替え忘れる事故が起こり得る。作業開始前に以下を必ず確認する:
- [ ] AWS account が staging(例: 301608970378)であること
- [ ] profile が staging 用(
staging-admin/staging-terraform等)であること - [ ]
SOURCE_CLが staging 対象クラスタであること - [ ]
BG_NAMEが staging 用であること - [ ] CPG / PG16 CPG が staging 用であること
- [ ] Terraform workspace / state が staging(
fd-tfstate-staging)であること
aws sts get-caller-identity --profile <staging-profile> # Account が staging か
aws rds describe-db-clusters --db-cluster-identifier <staging-cluster> \
--profile <staging-profile> --region ap-northeast-1 \
--query "DBClusters[0].[DBClusterIdentifier,EngineVersion,Status]" --output text1つでも production を指していたら直ちに中止。production 版コマンドの
$SOURCE_CL/$BG_NAME/$P等を staging 値に必ず置換する。
production 版コマンドを参照する前に、staging 用の変数ブロックを先に設定しておく(具体値は services/<service>.md):
P=staging-admin # staging 用プロファイル(書き込み権限が要る作業は staging-terraform 等)
R=ap-northeast-1
SOURCE_CL=<staging-cluster-id> # 例: eligibility-verification / online-karte-service
CL=$SOURCE_CL # 本番版コマンドの $CL 別名を揃える
BG_NAME=<staging-bg-name> # 例: eligibility-verification-bgtest
TARGET_CPG=<service>-pg16 # cluster PG(例: eligibility-verification-pg16)
TARGET_PG=<service>-pg16 # instance PG位置づけ(3 段階の真ん中)
| 段階 | 手順書 | 対象 | 目的 |
|---|---|---|---|
| ① 素振り | procedure-clone-rehearsal.md | staging を Clone(破棄可能) | 仕組み・所要時間・PG16化の素振り。失敗しても無影響 |
| ② 本書 | procedure-staging-direct.md | staging 実DB 本体 | 本番と同一手順を「実DB・実アプリ接続」で通すドレスリハーサル(アプリ再接続・Terraform 整合まで) |
| ③ 本番 | procedure-production.md | 本番実クラスタ | 周知・メンテ枠・監視・ロールバック待機まで含めて本実施 |
① はクラスタを壊さないが、② は staging 実DB を実際に PG16 へ上げる(staging アプリも新エンドポイント=PG16 に向く)。本番の「フェーズB 瞬断」「フェーズD Switchover」を実アプリ込みで体験できるのが価値。
本番版(procedure-production.md)との差分
| 観点 | 本番(③) | 本書(② staging 実DB) |
|---|---|---|
| 対象 | 本番クラスタ | staging 実クラスタ本体(Clone なし) |
| 手順(DBレベル) | フェーズ A〜E | 同一(③を参照して実施) |
| custom CPG / PG16 CPG | 本番アカウントに Terraform で追加 | staging に Terraform で追加・apply(tfstate=staging)。online-karte は online-karte-service-pg16(#13923 / terraform_for_aws #2217)、eligibility は eligibility-verification-pg16(#2164・作成済み) |
| 周知 | Feature チーム・関係者へ必須 | staging 利用者(QA 等)へ #on本部_プロダクト部 で周知(文言テンプレは下記) |
| 外部DBクライアント棚卸し(A-0) | 本番版 A-4 で必須(SG inbound / Secrets・IaC / 各ツール管理画面の突合まで) | 同様に実施するが軽め。最低限 DB SG inbound のソース確認+pg_stat_activity の点検(外部ツールが向いていないか)。管理画面突合は任意。Switchover 後の旧 Blue(-old1)残接続確認は本番同様に練習する |
| メンテ枠 | 2枠確保・低トラフィック帯 | staging 都合でよい(瞬断は同様に発生する点は理解しておく) |
| 監視 mute | 必須 | staging 監視があれば mute |
| Terraform 整合 | 本番 tfstate を 16 系へ | staging tfstate を 16 系へ(rds_engine_version・family)。やらないと次回 apply で drift |
| ロールバック | 切り戻し困難=fix-forward 優先 | staging なので緩め。失敗時は snapshot 復元 or 作り直しで可 |
| 後始末 | 新PG16 を残し旧PG13 を数日後削除 | 同様。staging を PG16 のまま運用継続(戻す場合は別途) |
| ライブ複製検証 | 非侵襲のみ(実トラフィック追従+CloudWatch ラグ) | 非侵襲+(任意)専用テストテーブルでの能動確認(下記) |
手順
DB レベルの実コマンドは procedure-production.md のフェーズ A〜E をそのまま staging に対して実施する。 以下は staging 固有の補足のみ。
- フェーズA(事前準備): staging 用 PG16 ターゲット CPG/source custom CPG が Terraform に入っているか確認(無ければ staging tfstate に apply)。ベースライン(pg_stat_statements / EXPLAIN)は staging の実トラフィックで取得。
- フェーズB(CPG 付け替え+再起動=瞬断): staging 実DB に実際に瞬断が発生する。staging アプリ・QA 作業への影響を
#on本部_プロダクト部に周知しておく。タイミングは初回告知 2〜3営業日前+(任意)前日+当日(作業前)、完了後に「完了しました」と報告(文言は下記テンプレ)。 - フェーズC(Green 準備・Blue 無停止): Blue/Green 作成 → Green 検証 → ANALYZE。ここで本書独自のライブ複製検証を行う(下記)。
- フェーズD(Switchover): staging アプリが新エンドポイント(PG16)に再接続することを実機で確認できる。書き込み断は数秒。
- フェーズE(事後): staging tfstate を 16 系へ整合。旧 PG13(
-old1)は確認後に削除。 - 外部CDC(Datastream 等)連携サービスは追加で: BG 作成前の slot/publication の扱い、Switchover 後の再作成・再開、バックフィルの有無・所要時間の実測、監視(GCP/Slack)を サービス固有手順
services/<service>.md(例: online-karte-service §5)に沿って実施する。この staging リハーサルが本番の枠設計の実測根拠になる(事前判定は プレフライト A-2)。
周知文言テンプレ(
#on本部_プロダクト部・staging) — 作業前に投稿し、完了後に「完了しました」と返信: 【staging メンテ作業のお知らせ】 Aurora(eligibility-verification / staging)に PG16 アップグレードの作業を行うため、MM/DD(曜) HH:MM〜 約〇〇分ほどお時間をいただきます。 作業中は一時的な接続断・書込断が発生します。その間は DDL(migration など)に関するデプロイを行わないでください。 完了後に本チャンネルで報告します。連絡先: @担当
フェーズC 追加: ライブ複製検証(同期中に Blue→Green が流れているか)
Clone 版(①)は破棄可能なので自由に注入してよいが、staging 実DB は実アプリが使うため、原則は 非侵襲。能動テストを行う場合も専用テストテーブルに限定し、終了後に削除する。
(a) 非侵襲(推奨・実トラフィック追従で確認)
-- (Blue=staging実DB / Green それぞれで) 高頻度書込テーブルの最新値(読むだけ)
SELECT <確認式> FROM "<high_write_table>";→ Green が Blue の最新値に追従していれば複製は生きている。差分=ラグ。CloudWatch AuroraReplicaLag / OldestReplicationSlotLag も併せて確認。
⚠️
max(id)が常に使えるとは限らない(id が UUID/単調増加でない/UPDATE 中心で INSERT が少ない/soft delete 中心 等)。確認テーブルと確認式はservices/<service>.mdに定義する。候補:max(id)/max(created_at)/max(updated_at)/count(*)/ 特定テストレコードの値。(例: online-karte=max(id) FROM "EventLog"、eligibility=max(id) FROM ocr_results等を services に明記)
(b) 能動(任意・専用テストテーブルのみ)
⚠️ この専用テストテーブル方式は staging-direct(②)/ Clone(①)専用。本番(③)では実施しない(本番DBへのテスト DDL/書込はしない)。 ⚠️ 論理レプリケーションは DDL を複製しない。テスト用テーブルは BG 作成前(フェーズB 後〜C 前・Blue が writable なうち)に作成しておく(初期コピーで Green にも入る)。同期開始後に作っても Green に出ない。
-- フェーズC の前(Blue): 専用テストテーブルを用意
CREATE TABLE public._bg_repltest (id int PRIMARY KEY, note text, ts timestamptz DEFAULT now());
-- 同期中(Blue): 書込
INSERT INTO public._bg_repltest VALUES (1, 'live-insert');
UPDATE public._bg_repltest SET note='live-update' WHERE id=1;
-- 同期中(Green・read-only): 反映確認
SELECT * FROM public._bg_repltest; -- 数秒以内に反映されるはず
-- 検証後(Switchover 後の新PG16 = writable): 後始末
DROP TABLE public._bg_repltest;アプリ経由のライブ検証(推奨・end-to-end)
psql の直接確認だけでなく、実アプリ経由の書込/読取で「同期・Switchover・再接続」を end-to-end 検証する。staging は実アプリが繋がっているので、本番同等の挙動を安全に体験できる(本番でアプリ駆動の書込テストはしない)。
アプリ経由の具体的な操作(エンドポイント/テスト入力/確認方法/後始末)はサービス固有なので
services/<service>.mdに記載する。本書は流れのみ。 ⚠️ テストデータの後始末: staging とはいえアプリ経由で実書込が入る。アプリ経由で作成したテストデータは、サービス固有手順に従って削除する/テストデータとして識別可能な状態にする(services/<service>.mdにテスト入力・確認方法・cleanup を定義)。
- フェーズC(同期中・Blue 無停止)
- アプリ経由で書込操作を実行(Blue へ INSERT/UPDATE が入る)。
- その行が Green に複製されることを psql(Green=read-only)で確認。
- アプリのレスポンス/エラーログが正常であること。
- フェーズD(Switchover 前後)
- Switchover 直前にアプリ経由で1件書込 → 直後にも書込。
- 書込断(数秒)の間のアプリ挙動(リトライ/エラー/タイムアウト)を観察=本番でのユーザー影響の予行。
- Switchover 後、アプリが据え置きエンドポイントで新 PG16 に正常に読み書きできること(自動再接続)を確認。
- Switchover 前にアプリで書いたデータが新 PG16 に存在することを確認(データ欠落なし)。
- フェーズE(事後)
- アプリのエラーログを一定時間監視。主要機能の疎通(read/write 両方)を確認。
PKなしテーブルの事前チェック(複製の落とし穴)
論理レプリケーションは PK / replica identity の無いテーブルの UPDATE/DELETE を安全に複製できない(INSERT は複製される)。publication が UPDATE/DELETE を対象にしている場合、エラー・同期停止・Replication degraded(StatusDetails≠null)の原因になり得る。
- BG 実施前に「アプリが PKなしテーブルへ UPDATE/DELETE を行うか」を確認する。行う場合、同期中にその変更が複製できずデータ分岐や同期劣化を起こすため、PK 追加 or
REPLICA IDENTITY FULLを事前に適用する。 - 例: online-karte-service の
mastra_evals/mastra_workflow_snapshot(PKなし・mental-online-karte #13732)。 - 能動確認するなら Clone 版(①) で no-PK テーブルへ UPDATE/DELETE した場合にエラーまたは伝播不可になることを実機確認しておく(staging 実DB では UPDATE/DELETE しない)。
性能影響の確認(ベースライン / Optimizer / 実行計画)
PG12→16 は Optimizer 改善で実行計画が変わり得るため、アップグレード前にベースラインを取り、事後に突き合わせる。staging は実トラフィック(または OCR アプリ駆動)で取得する。
⚠️ カラム名はバージョンで異なる: Aurora PG13(source)は
total_exec_time/mean_exec_time。RDS PG12(例:fastdoctor-manager-db*)はtotal_time/mean_timeに読み替える(PG13 で改名)。
事前(枠前・Blue=PG13): ベースライン取得
-- Top SQL(現DB限定)
SELECT queryid, LEFT(query,100) AS query_preview, calls,
round(total_exec_time::numeric,2) AS total_ms, round(mean_exec_time::numeric,2) AS mean_ms, rows
FROM pg_stat_statements
WHERE dbid=(SELECT oid FROM pg_database WHERE datname=current_database())
ORDER BY total_exec_time DESC LIMIT 50;
-- CSV
\copy (SELECT queryid, query, calls, total_exec_time, mean_exec_time, rows FROM pg_stat_statements WHERE dbid=(SELECT oid FROM pg_database WHERE datname=current_database()) ORDER BY total_exec_time DESC LIMIT 50) TO '/tmp/pg_stat_baseline.csv' CSV HEADER;
-- 主要クエリの実行計画も保存(更新系は BEGIN; ... ROLLBACK; で囲む)
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT ... ;事後(Switchover 後・PG16): 突き合わせ
SELECT LEFT(query,100) AS query_preview, calls,
round(mean_exec_time::numeric,2) AS mean_ms, round(total_exec_time::numeric,2) AS total_ms, rows
FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 20;
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT ... ; -- 事前と同一クエリ比較ポイント: Seq Scan↔Index Scan / Nested Loop↔Hash Join↔Merge Join / actual time / rows 乖離。queryid は変わるのでクエリ本文・mean/totalで比較。
メジャーバージョン間の主な Optimizer 変更:
| バージョン | 主な変更 | 影響 |
|---|---|---|
| PG13 | インクリメンタルソート / B-tree 重複排除 | ソートを含むクエリ |
| PG14 | Memoize 結合戦略 | Nested Loop 結合 |
| PG15 | hash_mem_multiplier 既定 2.0 | ハッシュ結合のメモリ増 |
| PG16 | ウィンドウ関数最適化 | ウィンドウ関数クエリ |
任意の上級策: Aurora の apg_plan_mgmt(Aurora Query Plan Management) でプランベースラインをキャプチャし事後の安定性を確保(運用オーバーヘッドあり)。参考: Aurora PostgreSQL Query Plan Management
メンテ枠の時間設計(1時間枠前提)
本番(③)と同じ1時間枠設計を staging 実DBで予行する。詳細・実測根拠は procedure-production.md「メンテ枠の時間設計」。要点:
- 枠までに完了(無停止/別枠): Terraform CPG → logical 有効化の CPG 付け替え+再起動(=Aurora 瞬断。1時間枠に収めるため Switchover 枠とは別枠を強く推奨。長い枠を取れば同日連続実施も可能だが、本番想定の1時間枠リハーサルでは分離する) → Blue/Green 作成 約31分+Green 検証+ANALYZE(枠前に AVAILABLE 必須) → ベースライン / DDL 凍結 / 周知 / DNS TTL≤5s。
- ⚠️ 再起動(フェーズB)が不要になる条件: source が「logical replication 前提の custom CPG で in-sync 済み」の場合のみ。具体的には
rds.logical_replication=on/wal_level=logical/wal_sender_timeout=0/ CPG が全メンバー in-sync / preload library 互換 / replication 関連パラメータ(max_replication_slots・max_wal_senders 等)が確認済みであること(onだけでは不十分)。eligibility は default CPG(logical off)なので再起動必要、online-karte は Datastream で上記が揃っていれば不要。
- ⚠️ 再起動(フェーズB)が不要になる条件: source が「logical replication 前提の custom CPG で in-sync 済み」の場合のみ。具体的には
- 枠の直前(T-15〜T0・無停止・枠には含めない): 最終ゲート(BG AVAILABLE / StatusDetails=null)+レプリラグ≒0 確認 → PG13 スナップショット取得→available(実測ベースの目安で約2〜3分。DBサイズ・更新量・AWS側状態で変動するため available を確認してから進む) → DDL 凍結/周知の最終確認・GO/NO-GO。NG なら枠を開かず延期。
- 1時間枠の中身(T0=Switchover):
T+0〜+2 : Switchover(書込断 数秒)
T+2〜+20 : PG16 疎通 / アプリ経由確認(サービス固有の主要 write/read 1件・具体は services/<service>.md。例: eligibility は OCR 1件)/ ALTER EXTENSION UPDATE / slot 確認
T+20〜+60 : 監視バッファ(40分)snapshot・ゲート確認は無停止なので枠直前に出し、1時間枠には含めない(枠は Switchover 以降に集中)。
- staging 特有: 周知・監視 mute は軽め、再起動の瞬断は staging 利用者(QA 等)に通知すれば可。「31分の Green 作成を枠に入れない」「ラグ≒0 の低トラフィック帯」は本番と同じく死守(ここが staging で確かめたい肝)。
サービス固有の値・実施記録
クラスタ識別子・使用拡張・target version・確認テーブル名・実施日時・結果は services/<service>.md に記録する(本書は手順のみ)。staging 実DB 実施の結果も同ファイルに「② staging 実DB」行として残す。
位置づけの限界(性能・負荷)
本書は 手順・アプリ再接続・Switchover 挙動・ライブ複製の検証には有効だが、staging の実トラフィックは本番より少ない可能性がある。よって 本番同等の書き込み量・replication lag・性能影響は完全には再現しない。性能/lag の最終判断は本番実施時(③ フェーズE)の監視で行う。
完了条件
- staging の実 Aurora が PG16 で稼働し、staging アプリが新エンドポイント(据え置き名)で正常接続。
- フェーズB の瞬断・フェーズD の Switchover を実アプリ込みで体験し、本番手順(③)の妥当性を確認できた。
- staging tfstate が 16 系に整合(drift なし)。
- 旧 PG13(
-old1)は確認後に削除(課金停止)。