Skip to content

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_CLstaging 対象クラスタであること
  • [ ] BG_NAMEstaging 用であること
  • [ ] CPG / PG16 CPG が staging 用であること
  • [ ] Terraform workspace / state が stagingfd-tfstate-staging)であること
bash
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 text

1つでも production を指していたら直ちに中止。production 版コマンドの $SOURCE_CL / $BG_NAME / $P 等を staging 値に必ず置換する。

production 版コマンドを参照する前に、staging 用の変数ブロックを先に設定しておく(具体値は services/<service>.md):

bash
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.mdstaging を Clone(破棄可能)仕組み・所要時間・PG16化の素振り。失敗しても無影響
本書procedure-staging-direct.mdstaging 実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) 非侵襲(推奨・実トラフィック追従で確認)

sql
-- (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 に出ない。

sql
-- フェーズ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 無停止)
    1. アプリ経由で書込操作を実行(Blue へ INSERT/UPDATE が入る)。
    2. その行が Green に複製されることを psql(Green=read-only)で確認。
    3. アプリのレスポンス/エラーログが正常であること。
  • フェーズD(Switchover 前後)
    1. Switchover 直前にアプリ経由で1件書込 → 直後にも書込。
    2. 書込断(数秒)の間のアプリ挙動(リトライ/エラー/タイムアウト)を観察=本番でのユーザー影響の予行。
    3. Switchover 後、アプリが据え置きエンドポイントで新 PG16 に正常に読み書きできること(自動再接続)を確認。
    4. 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): ベースライン取得

sql
-- 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): 突き合わせ

sql
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 重複排除ソートを含むクエリ
PG14Memoize 結合戦略Nested Loop 結合
PG15hash_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 で上記が揃っていれば不要。
  • 枠の直前(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)は確認後に削除(課金停止)。