Skip to content

PG16 アップグレード preflight・リファレンス:dr-work-record(★Global Database・本番)

📌 本書 = このサービスの preflight.md(=調査/リファレンス doc)。命名規約上 preflight.md は「各サービスの調査結果・固有値・consumer・設計判断・ゲート根拠・preflight を集約したリファレンス」を指す(手順本体は production.md/staging.md/clone-rehearsal.md)。

手順本体は Cloneリハーサル版 / 本番実施版 を参照。本書は dr-work-record 固有値+Global Database 特有の考慮+本番実施順序(§6-A)+consumer(§6-D)+ゲート(§6-E)+preflight(§7)

📚 dr-work-record 手順書セット(テストは本番とは別ファイル):

  • 🏭 本番当日の実行手順(コピペ可・自己完結)production.md — ①〜⑦ 通し+ゲート/ロールバック内蔵
  • 📖 本書(preflight.md)= リファレンス:調査結果・consumer 棚卸し(§6-D)・設計判断・§6-E ゲート根拠・§7 preflight(=なぜ)
  • 🧪 clone テストclone-rehearsal.md — 本番 Clone で「Global 削除経路」を素振り
  • 🧪 staging テストstaging.md — 非-Global staging で「PG16 アプリ互換」を検証(#12841) 【採用方針(2026-07-29)】Global Database を削除して standalone 化 → 標準(非-Global)Blue/Green で実施する。詳細は §6。 ℹ️ 前提: Aurora Global Database 自体は BG 対応(AWS 公式「Aurora Global Database limitations for blue/green deployments」)で「Global のまま直接 BG」も技術的に可能。だが本サービスは**単一リージョン(セカンダリ無し)**のため、global を外して標準 BG にする方が単純で、Global-DB BG 固有の制約(topology 凍結・BG中 global switchover 不可・secondary 同名PG)を回避できる。よって本方針を採用。

対象サービス: dr-work-record / 担当: <name> / 最終更新: 2026-07-29 関連: 実施イシュー #16266 / 汎用 stub #12729 / preflight ツール terraform_for_aws#2361 / 難易度マトリクス #13044

1. 環境・接続

項目production
AWS プロファイル(Pproduction-admin(⚠️ 書き込み権限・read-only 不可)
リージョン(Rus-east-1(※ dr-* 系の active は us-east-1。東京の同名クラスタは空の旧残骸で対象外)
Secrets Manager Secret IDdr-work-record-dd は Datadog・無関係)
DB 名(psql dbnamework_record_production
踏み台(bastion)i-09384db1d690bcfd0(fd-platform-bastion・us-east-1) ← dr-work-record SG が fd-platform SG を許可
接続方式Prisma DATABASE_URL 単一 Secret(cluster endpoint)
アプリNestJS 10 + Prisma 5.1.1(Node 20)=PG16 対応(Prisma 5.0+ で PostgreSQL 16 正式サポート)。source: fastdoctor-jp/microservice-nestjswork-record(医師系マイクロサービス monorepo)

staging クラスタは存在(実機確認 2026-08-04):dr-work-record(acct 301608970378 / ap-northeast-1・Aurora PG 13.201インスタンス非-Global)。本番(us-east-1・Global・Writer+Reader)とはリージョン/Global 有無/台数が異なる。→ staging は 非-Global なので「Global 削除」を素振りできない。そのため Global 削除→標準 BG の検証は §6-B の Clone リハーサル(本番 Clone を Global 化→detach)で担保する。driver/アプリ互換(PG16)の素振りには staging クラスタも活用可(#12841)。

2. クラスタ構成(アップグレード対象)

本 Global DB はセカンダリ無しの「単一リージョン構成」(プライマリ us-east-1 のみ・GlobalClusterMembers は writer 1件・readers:[])。クロスリージョン冗長性は現状なし。移行は us-east-1 のみが対象で、Global-DB BG の「セカンダリに同名 PG が必要」要件は N/A。 ※ 東京(ap-northeast-1)にある同名 standalone クラスタ(13.14・0インスタンス・global=null)は Global 外の空残骸で対象外。dr-work-record-0 はセカンダリではなくプライマリ us-east-1 内の Reader

項目
クラスタ識別子(SOURCE_CLdr-work-record
Global Clusterdr-work-record(メンバー=us-east-1 primary のみ・★セカンダリ無し=単一リージョン)
インスタンス構成Writer dr-work-record-1 1台 / Reader dr-work-record-0 1台(MultiAZ)
インスタンスクラスdb.r6g.large
DB Subnet Groupdr-work-record-subnet
VPC Security Groupsg-074e71eb70c8bc948
KMSarn:aws:kms:us-east-1:967691968827:key/d29c6ace-407c-42e2-94d5-93e1d1238f15
ストレージ規模約 92MB(VolumeBytesUsed・極小)
現行エンジンaurora-postgresql 13.23(★2026-08-26 実機で訂正。13.20 は 2026-07-28 preflight 時点の値で、その後 minor が上がった。ValidUpgradeTarget の範囲が 13.20 と 13.23 で異なるため要注意)
target エンジン16.14ValidUpgradeTarget に 16.11/16.13/16.14 available・2026-08-25 本番実機で確認。staging が 16.14 で移行済のため揃える。CPG は family aurora-postgresql16 で共通=変更不要)
writer endpointdr-work-record.cluster-cxmwyphil4em.us-east-1.rds.amazonaws.com

⚠️ Reader が1台あるため、CPG 付替後の再起動は Reader→Writer の順で1台ずつ(AWS推奨・安全側・generic 手順 2-3。Writer-first でも動くが、万一の計画外 failover 時に未適用 Reader 昇格の恐れがあるため Reader を先に)。

3. パラメータグループ(★未作成・要作成)

現状(実機 2026-08-04)+★pgaudit ドリフト(2026-08-06 判明):

  • 実 cluster PG=default.aurora-postgresql13(user param 0・logical=off・pgaudit 無し)。
  • ⚠️ ただし TF(fastdoctor-template/dr-work-record/production/variable.tf)は custom cluster PG dr-work-recordshared_preload_libraries=pgaudit,pg_stat_statementspgaudit.log=all を意図cluster_parameter_group_custom_enable=true)。=本番は TF からドリフトして pgaudit 未適用(staging・他サービス〔online-karte/online-ops/dr-worker-information〕は本番でも pgaudit 有効)。
  • 【方針】PG16 移行で本番にも pgaudit を適用し、staging・TF・他サービスと揃える(ドリフト是正)

BG には ①blue(PG13) 側の logical 有効化+pgaudit②green(PG16) 側の target PG(pgaudit 込み) が要る。両方 Terraform(共通モジュール aurora-bluegreen-param-groupscluster_parameters を override)で作成する(作成のみ・付替は §6-A/§6-C のとおり CLI)。

役割cluster PG 名family主 param
② target(green・PG16)dr-work-record-pg16(cluster + instance)aurora-postgresql16rds.logical_replication=1 / wal_sender_timeout=0 / shared_preload_libraries=pgaudit,pg_stat_statements / pgaudit.log=all
① source(blue・PG13)dr-work-record-pg13-bg(cluster PG)aurora-postgresql13同上(shared_preload_libraries に pgaudit を含め、付替+reboot で blue にも pgaudit を適用=ドリフト是正)

3-1. Terraform(fastdoctor-template/dr-work-record/production/pg16_param_groups.tf・凍結前に apply)

hcl
locals {
  # 本番も pgaudit を含める(TF/staging/他サービスと揃える・ドリフト是正)
  dwr_cluster_params = {
    "rds.logical_replication"  = { value = "1", apply_method = "pending-reboot" }
    "wal_sender_timeout"       = { value = "0", apply_method = "pending-reboot" }
    "shared_preload_libraries" = { value = "pgaudit,pg_stat_statements", apply_method = "pending-reboot" }
    "pgaudit.log"              = { value = "all", apply_method = "immediate" }
  }
}
# ② target(PG16): cluster PG + instance PG。cluster_parameters に pgaudit を含める
module "pg16_blue_green_param_groups" {
  source             = "../../template_modules/options/aurora-bluegreen-param-groups"
  name               = var.project            # = dr-work-record
  target_family      = "aurora-postgresql16"
  cluster_parameters = local.dwr_cluster_params   # ★pgaudit 込み(既定を override)
  # instance_parameters は空(現行 instance PG も user param 0)
}
# ① source(PG13) 用 cluster PG(logical+pgaudit)
module "pg13_source_param_group" {
  source             = "../../template_modules/options/aurora-bluegreen-param-groups"
  name               = var.project
  name_suffix        = "pg13-bg"              # → dr-work-record-pg13-bg
  target_family      = "aurora-postgresql13"
  cluster_parameters = local.dwr_cluster_params   # ★pgaudit 込み
}
  • ⚠️ この apply は「PG 作成のみ」。既存 cluster には付けない(付替は §6-A ②で CLI・db_cluster_parameter_group_nameignore_changes=ドリフトしない/§6-C)。

  • source CPG(dr-work-record-pg13-bg)を blue に付替+reboot(§6-A ②)した時点で、本番 blue に pgaudit が有効化される(現状 default PG=pgaudit 無しからの是正)。green(PG16) も target CPG で pgaudit 有効。

  • instance PG:現行 dr-work-record(user param 0)=実質デフォルト → target instance PG(dr-work-record-pg16)もモジュール既定(空)で等価。BG の --target-db-parameter-group-name に指定。

  • 本番でも pgaudit を有効化するpgaudit.log=all。他サービスは既に有効で整合的・ドリフト是正)。監査ログ量が増える点は関係者へ周知しておく。

  • [ ] dr-work-record-pg16(cluster/instance)と dr-work-record-pg13-bg(cluster)が TF apply で作成され、logical_replication=1/wal_sender_timeout=0 を持つ

4. 使用拡張・後処理(preflight 実測 → #16266)

項目該当備考
インストール拡張(\dxplpgsql のみ要対応拡張(postgis/pg_repack/pgrouting)なし=互換ブロッカーなし
pg_stat_statementspreload 済み・拡張は未作成(実機 \dx=plpgsql のみ/pg_available_extensions installed_version 空)⚠️BG 作成前に blue で CREATE EXTENSION pg_stat_statements(汎用 procedure-clone-rehearsal §3-4。Green は同期中 read-only で後から作れない)→ Switchover 後に ALTER EXTENSION pg_stat_statements UPDATE。※監視用で移行必須ではないが未作成のままだと事後 UPDATE が空振りになるため BG 前作成が正。staging 実機で作成済み(2026-08-11・1.8)
pg_cron / pg_partman / pg_repack未使用
PKなしテーブル0BG 採用でも REPLICA IDENTITY 対応不要
外部論理レプリ(publication)0Datastream/Trocco/BI 等の下流なし
Reader / AutoScalingReader ありSwitchover 後に構成確認
logical_replicationoff(要有効化・§3 の CPG)
pgaudit⚠️本番は未適用(default PG)=TF ドリフトTF は pgaudit を意図(staging・他サービスは有効)。移行で本番にも pgaudit 追加=ドリフト是正(§3・§6-E)。監査ログは CW /aws/rds/cluster/dr-work-record/postgresql(consumer バッチは無し・保全目的)

5. Blue/Green 名・Clone 名

項目
Blue/Green 名(本番 BG_NAMEdr-work-record-bg
Blue/Green 名(リハーサル)dr-work-record-bgtest
Clone 名(リハーサル CLdr-work-record-bgtest-blue
リハ用 使い捨て Global Clusterg-dr-work-record-bgtest

6. ★Global Database の Blue/Green(方針: Global 削除 → 標準 BG)

【採用方針】Global Database を削除して standalone 化 → 標準(非-Global)Blue/Green で実施する。

ℹ️ Aurora Global Database は BG 対応(AWS 公式)だが、**本サービスは単一リージョン(セカンダリ無し)**のため、global を外してから標準 BG にする方が単純。Global-DB BG 固有の制約(topology 凍結・BG中の global switchover 不可・secondary 同名PG)を回避できる。セカンダリが無いので global 削除のコストは低い。

6-A. 本番での順序(Global 削除 → 標準 BG・当日は数秒狙い)

(事前枠) ① Global 削除で standalone 化:
           remove-from-global-cluster(primary を切り離し・メタ操作/無停止想定)→ delete-global-cluster(空 global 削除)
         ② source PG13 CPG `dr-work-record-pg13-bg`(logical=1 / wal_sender_timeout=0) を blue に付替 → Reader→Writer 再起動(★瞬断 30〜60秒)
(枠前)   ③ 標準 BG 作成(非-Global・target=16.14 / cluster・instance PG=`dr-work-record-pg16`)→ AVAILABLE → Green 検証
(切替枠) ④ Switchover(★書込断 数秒・endpoint 据え置き)
(事後)   ⑤ ALTER EXTENSION pg_stat_statements UPDATE / 監視 / 旧 blue(-old1) 削除
         ⑥ tfvars の rds_engine_version を 16.x に更新(§6-C)
         ⑦ (任意) Global 復元: create-global-cluster … 単一リージョンでは通常不要。将来クロスリージョン DR が要るなら別途。
bash
export AWS_PROFILE=production-admin ; R=us-east-1
# ① Global 削除(standalone 化)
CL_ARN=arn:aws:rds:us-east-1:967691968827:cluster:dr-work-record
aws rds remove-from-global-cluster --region $R --global-cluster-identifier dr-work-record --db-cluster-identifier "$CL_ARN"
aws rds wait db-cluster-available --region $R --db-cluster-identifier dr-work-record   # 稼働継続を確認
# ★削除保護の解除が必要(★2026-08-26 実機で判明。この環境の Global Cluster は全て DeletionProtection=true)
#   解除しないと: InvalidParameterCombination: Cannot delete protected Global Cluster dr-work-record,
#                 please disable deletion protection and try again.
aws rds describe-global-clusters --region $R --global-cluster-identifier dr-work-record \
  --query 'GlobalClusters[0].{protection:DeletionProtection,members:length(GlobalClusterMembers)}' --output json  # members=0 をガード確認
aws rds modify-global-cluster --region $R --global-cluster-identifier dr-work-record --no-deletion-protection
aws rds delete-global-cluster --region $R --global-cluster-identifier dr-work-record
aws rds describe-global-clusters --region $R --global-cluster-identifier dr-work-record  # → GlobalClusterNotFoundFault が正

# ② source PG13 CPG(logical=1) を blue に付替 → Reader→Writer 再起動(★瞬断 30〜60秒・事前枠)
#   ★Reader を先に reboot(AWS推奨・安全側・generic 2-3)。計画 reboot は failover しないため
#     Writer-first でも動くが、万一の計画外 failover 時に未適用 Reader 昇格で logical=on にならない恐れ。
aws rds modify-db-cluster --region $R --db-cluster-identifier dr-work-record \
  --db-cluster-parameter-group-name dr-work-record-pg13-bg --apply-immediately
aws rds wait db-cluster-available --region $R --db-cluster-identifier dr-work-record
aws rds reboot-db-instance --region $R --db-instance-identifier dr-work-record-0   # Reader を先に
aws rds wait db-instance-available --region $R --db-instance-identifier dr-work-record-0
aws rds reboot-db-instance --region $R --db-instance-identifier dr-work-record-1   # Writer(★これが瞬断)
aws rds wait db-instance-available --region $R --db-instance-identifier dr-work-record-1
#    踏み台 psql で SHOW rds.logical_replication;=on / SHOW wal_sender_timeout;=0 を確認

# ③ 標準 BG 作成(非-Global・target=16.14・cluster/instance PG=dr-work-record-pg16)
aws rds create-blue-green-deployment --region $R \
  --blue-green-deployment-name dr-work-record-bg \
  --source "$CL_ARN" \
  --target-engine-version 16.14 \
  --target-db-cluster-parameter-group-name dr-work-record-pg16 \
  --target-db-parameter-group-name dr-work-record-pg16
# → 以降 ④ Switchover / ⑤ 事後 は generic 手順 7-8

停止は ①(無停止想定)+②の瞬断(事前枠)+④の数秒(切替枠)。①②は事前枠に置き、当日枠は Switchover の数秒のみ。

6-B. リハーサル(Clone で Global 削除経路を素振り)→ 別手順書

別手順書に分離: Clone(copy-on-write)で「Global 化 → Global 削除 → 標準 BG」を素振りするテスト手順は → clone-rehearsal.md。本体 dr-work-record は無操作。Global 削除経路の検証を担当。

6-C. Terraform 整合(重要・本番/staging 共通)

BG・CPG 付替はすべて AWS CLI で行う。Terraform では実施しない。かつ TF ドリフトは起きない——fastdoctor-template/modules/rds_auroraaws_rds_cluster.default が下記のとおり設計されているため(global_cluster_identifier も ignore なので、万一 Global 操作をしても TF は無視する):

hcl
lifecycle {
  ignore_changes = [
    db_cluster_parameter_group_name,   # CPG 付替を無視
    global_cluster_identifier,         # Global 所属を無視
    replication_source_identifier,
  ]
}
  • aws_rds_global_cluster リソースは TF に存在しない(Global Cluster は TF 管理外=CLI 運用)。
  • cluster の global_cluster_identifier / db_cluster_parameter_group_nameignore_changes → CLI で remove-from-global-cluster / CPG 付替 / create-global-cluster(復元)してもドリフトしない。
  • 同一モジュールを使う staging も同じ

⚠️ ただし engine_versionignore_changes に入っていない。BG/Switchover で実体は 16.x に上がるため、アップグレード後に tfvars の rds_engine_version を 16.x へ更新しないと、次の terraform apply で「16→13 に戻す」ドリフトが出る(必須の TF 整合作業)。

  • [ ] Switchover 後、rds_engine_version を 16.14 に更新する PR を用意(apply で no-change になることを確認)
操作方法TF ドリフト
Global 切り離し / 削除 / 復元CLIなし(ignore_changes・global リソース無し)
CPG 付替・BG・SwitchoverCLIなし(cluster PG は ignore)
engine_version(13→16)実体は CLI/BG で変化あり → tfvars を 16.x に更新して解消

6-D. エンドポイント影響・consumer 棚卸し

結論: 「Global 削除」でも「BG Switchover」でも、cluster/reader エンドポイントは据え置き(DNS 完全一致で維持)。cluster/reader エンドポイントで接続している consumer は再設定不要。 ただし instance 直指定・IP 直指定の consumer だけは要修正 → 事前棚卸し必須

現行エンドポイント(実 API 確認・2026-07-29)

  • writer: dr-work-record.cluster-cxmwyphil4em.us-east-1.rds.amazonaws.com
  • reader: dr-work-record.cluster-ro-cxmwyphil4em.us-east-1.rds.amazonaws.com
  • global 専用エンドポイントは存在しないCustomEndpoints=null / Aurora Global に managed global DNS 無し) → ★訂正(実機 2026-08-26): CustomEndpoints=null は正しいが、Global Cluster 自体には専用エンドポイントが存在した: dr-work-record.global-ggkskzd9ar7x.global.rds.amazonaws.comdescribe-global-clustersEndpoint)。 Global 削除でこのエンドポイントは消滅するため、これを使う consumer が居ないことを削除前に確認すること。 今回は consumer が cluster/reader ep のみ(DB SG は source SG 3つ・CIDR 無し)で影響なし、削除後の api-probe 200 で裏取り済み。 なお detach(remove-from-global-cluster)した時点でメンバー0になり、global エンドポイントは実質機能しなくなる(削除を待たずに影響が出る)点に注意。

据え置きの根拠

  • detach(remove-from-global-cluster: cluster 識別子は不変 → エンドポイント不変。
  • BG Switchover: green が dr-work-record へリネーム、ハッシュ cxmwyphil4emaccount+region 共通・cluster/instance で同一を実確認)を継承 → cluster/reader エンドポイントは byte 一致で維持

要修正になる例外(← ここを棚卸し)

接続方式影響対処
cluster / reader エンドポイント✅ 不変再設定不要
instance 直指定dr-work-record-1/-0...❌ BG でインスタンス名が変わる(green→本名 / 旧→-old1事前に cluster/reader エンドポイントへ移行
IP 直指定❌ Aurora は DNS 前提DNS 名へ変更
sslmode=verify-full(ホスト名 pin)✅ ホスト名不変対処不要
PG16 ドライバ互換(Prisma 等)— 別論点staging 検証(#12841)

★実測結果(2026-08-04・本番 us-east-1・SG allowlist + ECS env) DB SG sg-074e71eb70c8bc948 の 5432 inbound = source SG 3つのみ(CIDR 無し=外部 SaaS 直結なし)

#許可 SG実体接続方式(実測)判定
1sg-09132d83ca9d08143dr-work-record-sgdr-work-record-service(ECS 本体・dr-work-record-clusterDB_HOST=dr-work-record.cluster-cxmwyphil4em.us-east-1…cluster endpoint据え置き・再設定不要
2sg-09a3dec4eb92eebf0fd-platform踏み台 i-09384db1d690bcfd0(10.0.2.105)のみ(管理)psql/管理✅ consumer ではない
3sg-024766cf722c3329afd-platform-retoolRetool self-hostedfd-platform-retool-bastioni-03f5590f3dd6f7ed710.0.0.104・running)⚠️未確認(cluster ep か instance 直か)⚠️ Retool 管理画面で接続 Host を直接確認(instance 直なら BG 前に cluster/reader ep へ移行)

★SG 実アタッチ先を完全列挙(2026-08-04)=隠れ consumer なし(確定):3 source SG はそれぞれ1つにしかアタッチされていない → ① dr-work-record-sg=ECS 1本(10.0.2.208=dr-work-record-service)/② fd-platform(広域SG)は us-east-1 では踏み台 1台のみ(10.0.2.105)=別サービスがぶら下がる取りこぼし無し/③ fd-platform-retool=Retool 1台。consumer は {アプリ・踏み台・Retool} の3つで確定

再確認(2026-08-12):DB SG sg-074e71eb70c8bc948 の 5432 inbound は依然 source SG 3つのみ・CIDR/IP 直開放なし、各 SG のアタッチ先も ① dr-work-record-sg=ECS 1本 / ② fd-platform=踏み台 1台 / ③ fd-platform-retool=Retool 1台 で不変。DMS/Datastream 用の source SG は存在せず=常設 CDC 消費者は無い見込み(実体確認は §6-E(b) の pg_replication_slots)。Global にセカンダリ無しも不変のため、Global 削除はクロスリージョン読み取り/DR に無影響。 ★Aurora Auto Scaling / Serverless=無し(2026-08-04)describe-scalable-targets 空・EngineMode=provisioned・serverless 設定なし → Reader は固定2台(アップグレード中に Reader が自動増減して手順が崩れる心配なし)。

  • 本体アプリは cluster endpoint 接続= Global 削除・BG Switchover とも無影響(§6-D 結論どおり)。
  • 外部 SaaS(Trocco 等)の公開IP 許可は無し(SG に CIDR ゼロ)= fastdoctor-manager と違い外部直結なし。
  • ⚠️ 唯一の要確認は Retool。fastdoctor-manager の教訓(BI の接続先は SG/Flow Logs では cluster-ep/instance-直を判別不可)に従い、Retool の resource 設定 Host を直接確認する。

残チェック(Retool のみ実施すればクローズ)

  • [ ] Retoolfd-platform-retool10.0.0.104)の dr-work-record 向け resource の Host が cluster endpoint か instance 直指定かを管理画面で確認 → instance 直なら BG 前に cluster/reader endpoint へ移行
  • [ ] (最終確認)pg_stat_activity で実接続元 IP を突合(app=cluster ep / Retool=10.0.0.104 / 踏み台 以外が居ないか)
  • [ ] Switchover 後、全 consumer が再接続できるか(driver 再接続・#12841)

6-E. BG 前チェック / Switchover 前 GO-NO-GO(dr-work-record 固有の追加ゲート)

汎用の可否ゲート(procedure-production.md A-2 / C-1 / D-0 / D-1)を基本とし、Global DB 由来の前後チェック本 DB 固有の consumer/Reader 項目を上乗せする。

★注意(順序): 汎用 A-2 の「Global 非所属(何も出ないこと)」チェックは、dr-work-record では §6-A ① の Global 削除後に初めて満たす(初期は Global 所属)。A-2/C-1 を回す前に §6-A ① を完了しておくこと。

(a) Global 削除の前後チェック(§6-A ① 前後)

  • [ ] 削除前: GlobalClusterMemberswriter 1件のみ・secondary リージョン/reader 無し(単一リージョン)を実行直前に再確認(構成変化が無いこと)
    bash
    aws rds describe-global-clusters --region $R --global-cluster-identifier dr-work-record \
      --query "GlobalClusters[0].GlobalClusterMembers[].{arn:DBClusterArn,writer:IsWriter,readers:Readers}" --output json
  • [ ] 削除前: 直近バックアップ/スナップショットが存在(万一に備え・remove-from-global-cluster はメタ操作だが保険)
  • [ ] 削除後: クラスタが standalone(GlobalClusterIdentifier=null かつ Status=available(稼働継続)を確認 → その後 ②CPG/③BG へ
    bash
    aws rds describe-db-clusters --region $R --db-cluster-identifier dr-work-record \
      --query "DBClusters[0].{global:GlobalClusterIdentifier,status:Status}" --output json   # global=null 期待

(b) BG 作成前チェック(汎用 C-1 + 固有)

  • [ ] 汎用 C-1 実施(Status=available / Backup>0 / Global=None / custom CPG dr-work-record-pg13-bgWriter/Reader とも in-sync / PG16 CPG dr-work-record-pg16(cluster/instance) 存在 / 長時間tx 0 / logical 制限・default_transaction_read_only 監査)
  • [ ] Writer で logical 有効dr-work-record-1(Writer) が SHOW rds.logical_replication;=on / SHOW wal_level;=logical
  • [ ] ★Reader(dr-work-record-0)は logical=off / wal_level=replica が正常(★2026-08-26 実機で訂正。以前は「双方 on」と書いていたが Aurora 仕様上達成不可能
    • RDS が Reader に対して自動調整する: The parameter rds.logical_replication was set to a value incompatible with replication. It has been adjusted from 1 to 0.
    • pg_settingssource=configuration file / pending_restart=f / reset_val=off再 reboot しても on にならない。reboot 順序とも無関係(CPG 付替時と Reader reboot 時の 2 回同イベントが記録される)
    • 移行への影響なし: wal sender / replication slot は Writer 側に作られ、BG も Writer から slot を作る
    • Reader 側の適用確認は shared_preload_libraries に pgaudit が入ったことと wal_sender_timeout=0 で行う
  • [ ] 参考: reboot 時に max_wal_senders ... adjusted from 10 to 20 が両機で出るが、これも Aurora による正常な自動調整(CPG では未指定=「明示しない」方針と整合)
  • [ ] (任意・A-3)pg_stat_statements ベースラインを実トラフィックのある本番 blue で取得(Switchover 後の性能比較用。92MB と極小のため優先度低だが取得推奨)
  • [ ] ★常設の論理レプリケーション消費者が無いこと(pg_replication_slots / pg_publication 最終確認):§6-D の「外部論理レプリ=0(Datastream/Trocco/BI 下流なし)」を実行直前に本番 blue で実測確認。SG 上も DMS/Datastream 用 source SG は無い(consumer は {アプリ・踏み台・Retool} の3つのみ・2026-08-04/再確認 2026-08-12)が、DB 実体でも裏取りする。もし consumer 所有の logical slot / publication が存在したら、Global 削除・custom CPG 付替・BG が下流 CDC を壊し得るため着手前に停止/調整する。BG 作成で AWS が自前 slot を作るため、BG 前は 0 件が期待値
    bash
    # 踏み台 psql(sanctioned):
    SELECT slot_name, plugin, slot_type, active, database FROM pg_replication_slots;  -- consumer所有slotが無い(0行)こと
    SELECT pubname FROM pg_publication;                                               -- publication が無い(0行)こと

(c) Switchover 前 GO-NO-GO(汎用 D-1 の12項目 + dr-work-record 固有)

  • [ ] 汎用 D-1 の12項目を全てクリア(BG AVAILABLE / StatusDetails=null / SwitchoverDetails 全 AVAILABLE / AuroraReplicaLagOldestReplicationSlotLag≒0 / 長時間tx 0 / DDL・migration 凍結 / D-0 PG13 スナップショット available / 監視 mute / DNS TTL≤5s / default_transaction_read_only 非上書き / ロールバック担当待機 / TF PG16 整合 PR 準備済
  • [ ] ★Green 実接続検証(describe だけで済ませない): green cluster endpoint へ踏み台 psql → SHOW server_version=16.14work_records 件数が blue と一致 / green member CPG in-syncdefault_transaction_read_only=on(同期中は正常)
  • [ ] ★Retool(§6-D)が cluster/reader endpoint 接続と確認済みfd-platform-retool-bastion の resource Host が dr-work-record.cluster-……cluster-ro-…)。instance 直指定なら Switchover でインスタンス名が変わり切断 → BG 前に cluster/reader endpoint へ移行済みであること
  • [ ] ★Reader(dr-work-record-0)経由の consumer も Switchover 後に再接続(reader endpoint 据え置き。driver 再接続・#12841)
  • [ ] dr-work-record-service(cluster endpoint 接続・✅据え置き)が Switchover 後に自動再接続することを確認できる体制

(d) Switchover 後の E2E 確認(アプリ側・4層) 消費者アプリ=FastDoctor Doctor Appfastdoctor_doctor_appdr-app://jp.fastdoctor.doctorapp)。BFF=dr-app-bff(internet-facing・医師系MS集約)。dr-work-record は「勤務実績(診察数・報酬)」担当・テーブル work_records/patient_feedbacks。 E2E 経路:Doctor App → dr-app-bff(WORK_RECORD_MICROSERVICE_URL=http://dr-work-record-ms.fstdr.jp)→ dr-work-record-ms(内部ALB /healthCheck:3000)→ Prisma 5.1.1 → Aurora PG(cluster endpoint)。上流は dr-app-bff の1つのみ。API: GET /work-records?doctorId=&offset=&limit=(read)/POST /work-records/bulk(write)。

  • [ ] ①インフラ:ECS dr-work-record-service RunningCount=Desired / ALB target group dr-work-record-blue target=healthy
  • [ ] ②API/ヘルス:内部ALB http://dr-work-record-ms.fstdr.jp/healthCheck=200(浅い)+ 勤務記録 取得/登録 API が 200+データ=Prisma→PG16 read/write 疎通
  • [ ] ③APM/ログ:Datadog service:dr-work-record-ms の Errors で Prisma/PG 接続エラー(Can't reach database等)無し・レイテンシ正常(Switchover 前後比較)
  • [ ] ④ユーザー E2E医師アプリ(dr-app)で「勤務記録」を 表示(read)→ 登録/更新(write) が成功(=dr-app-bff→dr-work-record-ms→PG16 の全経路 OK)。上流 dr-app-bff の APM でも work-record 呼び出しが 2xx。実施材料は下記「④ 実施メモ」
  • [ ] (残留で不調時)aws ecs update-service --cluster dr-work-record-cluster --service dr-work-record-service --force-new-deployment で強制再接続

④ 実施メモ(Notion/Slack 調査 2026-08-06)

  • テスト医師アカウント: dr-app-test@fastdoctor.jp(PW は DM 運用・出典 Notion「医師ポータルのメンテナンスフロー」)。ログイン基盤 = Cognito dr-pool(属性 custom:doctor_id)。ログイン不可時の再作成手順は Notion「💉 医師 DA Squad 保守運用マニュアル」。
  • 本番の実機確認はストア版「ファストドクターDr」アプリ+在宅事業部の協力で行う(切替タイミングに合わせ日程調整・書込断は数秒想定)。医師アプリ管理=在宅事業部(旧 医師DA Squad)・連絡先 湯尾大祐さん/#squad-drda-dev
  • ⚠️ staging では医師アプリ実機は不可(確定・2026-08-06〜07):staging ビルドは配信されておらず TestFlight も規制でデプロイ不可・貸与/シェア端末にも動作する医師アプリ無し。staging は API 直プローブ+DB 直 psql で代替(staging §G-1)。
  • → 実機ビルドが手配できない場合は ④ を代替(DB read の担保)
    • DB 直 psql(推奨・実行可):踏み台 fd-platform から SSM port-forward → psql(踏み台 SG は DB 5432 を許可)。SELECT doctor_id,count(*),max(updated_at) FROM work_records GROUP BY 1;Switchover 前後で一致確認。手順は staging §G-1 のコマンド参照。
    • ⚠️ API 直プローブ(GET /work-records)は本番では不可:内部ALB(dr-work-record-ms) は SG が BFF系のみ許可で踏み台からは叩けず、ECS Exec も task role に ssmmessages 権限が無く未接続(要 IaC で権限追加+再デプロイ)。使うなら BFF/タスク側 SG 内から、または ssmmessages 権限付与後の ECS Exec。 ※staging のみ terraform_for_aws#2574(Issue: mental-online-karte#17017)で踏み台→ALB 許可を追加し API プローブ可能にしている(本番には入れない)。
  • ⚠️ 混同注意: online-doctor-app/doctor/me/monthly-doctor-evaluations(報酬テーブル・評価制度)は 別 web アプリ+online-doctor-servicedr-work-record とは無関係
  • 移行後の監視: Slack #fdt-dr-work-record-error-prod(勤務情報本番エラー)/#fdt-dr-app-bff-error-prod(BFF)。
  • [ ] ★pgaudit(ドリフト是正の確認):Switchover 後の新 primary(PG16) で SHOW shared_preload_libraries;pgaudit が含まれるSHOW pgaudit.log;=all・PG ログ(CloudWatch /aws/rds/cluster/dr-work-record/postgresql)に監査ログが出ること。※§B の CPG 付替時点で blue にも pgaudit が有効化される(現状 default PG=未適用からの是正)

★ staging テスト(staging.md §5)で同 E2E を本番前に先行検証しておく(#12841)。

(e) 接続残留時の復旧手順(②CPG付替reboot / ④Switchover 共通) アプリ・Retool とも cluster/reader endpoint 接続(Global 削除・BG Switchover とも DNS 据え置き)→ 基本は自動再接続で自己回復。復旧作業が要るのは、コネクションプールが切れた接続を掴んだままエラーを出し続ける残留ケースのみ(Multi-AZ/切替後に起きうる)。

  1. 検知:直後の一時的な接続エラーは数分で消えれば正常。残るかを監視。
    • Datadog service:dr-work-record-ms Error rate/Errors(Can't reach database server/server closed the connection/PG::ConnectionBad/terminating connection due to administrator command
    • /healthCheck=200 / ダッシュボード dr-work-record-aurora-pg16-bluegreenDatabaseConnections 回復
  2. アプリ復旧(残留時・ローリング=無停止):
    bash
    aws ecs update-service --region us-east-1 \
      --cluster dr-work-record-cluster --service dr-work-record-service --force-new-deployment
  3. Retool 復旧(§6-D で cluster/reader ep 接続を確認済み前提):クエリ再実行で自動再接続 → 残留なら self-hosted Retool(fd-platform-retool-bastion)のコンテナ再起動。
  4. 確認:API 直プローブ(本番は §6-D の許可経路)/踏み台 psql で疎通、Datadog Errors 解消、DatabaseConnections 平常化。

⚠️ instance 直指定の consumer(もし残っていれば)は Switchover でインスタンス名が変わり再接続では戻らない(cluster/reader ep への事前移行が前提・§6-D)。

6-F. staging テスト実施手順(アプリ互換)→ 別手順書

別手順書に分離: staging クラスタ(Aurora PG 13.23・非-Global・Writer 1台)での PG16 アプリ互換テスト(dr-work-record-service / Prisma / Retool・#12841)は → staging.md。Global 無しなので Global 削除はスキップ・reboot は Writer 1台のみ。


7. preflight 結果サマリ(2026-07-28・#16266/★2026-08-04 本番実機で再確認)

  • SUMMARY: PASS=23 WARN=4 FAIL=0 / blocker:none / risk:medium(medium 要因は Global DB+Reader+logical=off の手順面のみ
  • クリーン: PKなし0 / 拡張=plpgsql のみ / publication 0 / 長時間tx 0 / シーケンス2 / reg*型0 / matview0 / physical slot0 / FDW0 / event trigger0
  • next: reader-plan / custom-cpg / app-grep(driver 再接続確認 #12841)

★2026-08-04 本番実機(pg16-preflight-aurora.sh 読み取り専用)で再確認した追加事実

  • 接続方式=writer cluster endpointdr-work-record.cluster-cxmwyphil4em…)→ §6-D「本体アプリは cluster ep=Switchover 据え置き」を DB 側からも裏付け
  • 現行 wal_level=replica / wal_sender_timeout=1min / logical=off(→ §3 の CPG で logical=1・wal_sender_timeout=0 へ)。password_encryption=md5
  • cluster PG=default.aurora-postgresql13(logical off)/ DB数=3 / max_replication_slots=20 max_wal_senders=20
  • INFO: public スキーマに role BY0mRFqijXMwIh67 の UC 権限あり(移行ブロッカーでない・非標準ロール名・記録のみ)。
  • 2026-06-18 は staging 実機(#13044 コメント)、2026-07-28・2026-08-04 は production 実機で PASS=23/WARN=4/FAIL=0 が一致。

7-1. 移行前後の検証スクリプト(read + write/シーケンス継続性)

preflight(pg16-preflight-aurora.sh・読み取り専用)とは別に、Switchover の前後で DB 直の read/write を機械的に確認するスクリプトを用意(実装 PR: terraform_for_aws#2575 / Issue: mental-online-karte#17062)。

  • 場所: docs/sre/scripts/pg16-verify-dr-work-record.shGitHub
  • 検証: ①server_version(13→16 確認)②read プローブ(work_records 件数・医師数・最新 updated_at)③write/シーケンス継続性BEGIN; INSERT(id=DEFAULT); ROLLBACK)。
    • write は ROLLBACK で本番に test 行をコミットしないnextval は INSERT 時に評価されるため、BG/Switchover 最頻事故=シーケンスずれ(論理レプリケーションはシーケンス値を複製しない)を検出できる(read では検出不可)。
  • 使い方(切替の前後で実行し比較):
    bash
    bash pg16-verify-dr-work-record.sh --env staging    --label pre   # 切替前
    bash pg16-verify-dr-work-record.sh --env staging    --label post  # 切替後 → server_version=16.x / sequence_ok=t
    bash pg16-verify-dr-work-record.sh --env production --label pre|post
    env で profile/region/踏み台を自動切替(staging=ap-northeast-1/i-0ddd2353e102d9006・production=us-east-1/i-09384db1d690bcfd0)。secret はどちらも dr-work-record
  • 合格基準: 切替後に server_version が 16 系・read が切替前と同件数・sequence_ok=t(新 id > max・PK 衝突なし)・test 行コミット 0。
  • staging 検証済(2026-08-07): 13.23 / total=21 doctors=6 / sequence_ok=t / 未コミット

8. 実施記録

  • (リハーサル実施時にコマンド・結果・所要時間を追記)