本文是跨 vendor migration playbook、cross-link 到 PostgreSQL(source)跟 Aurora(DSQL 也屬 Aurora family、但 paradigm 不同)。跟 migrate-to-aurora(PG → Aurora PG、protocol drop-in + operational redesign)跟 migrate-to-cockroachdb(PG → CRDB、Type E paradigm shift)對照、本篇是 Aurora 內 PG → DSQL 的 paradigm shift。每階段切換用 migration gate 把關。

時間錨點:Aurora DSQL 在 2024-12 re:Invent preview、2025-05-27 GA。本文 vendor claim 以 2025-2026 公開狀態為準、實際 migration 前請以 AWS docs 為準(feature 持續演進中)。

為什麼遷:Global Write / Operational Zero-touch / Region Resiliency 三條 driver

PG → DSQL 不是「自然演進」、是 application 需求超出 single-primary 模型 時的 paradigm 換軌。三條典型 driver 各自對應一種 application 約束、不是「三選一」、而是「至少其中一條剛性、其他兩條是 bonus」:

Driver觸發場景
Global writeApplication 需要多 region active-active write(不是 Aurora PG 的 single-writer + read replica)
Operational zero-touch不想管 Patroni / PgBouncer / autovacuum / failover / backup retention、Aurora PG 已代管其中的 failover 與 backup、DSQL 進一步零接觸
Region resiliency整 region 失效時應用無感切換(Aurora PG 是 cross-region replica 異步、DSQL 是 strong consistency 多 region)

反向 driver(DSQL → Aurora PG)也存在:

  • 需要 PG extension(pgvector / TimescaleDB / PostGIS / pg_repack)— DSQL 不支援
  • Cost:DSQL 比 Aurora PG 貴 2-5x(依 region 數量)
  • Single-region OLTP 不需 distributed transaction 的 overhead

結構:Protocol Drop-in + Paradigm Shift

DSQL 是 PG wire-compatible(用 psql 連得上)、但內部是 distributed SQL engine:

維度self-managed PGAurora PGAurora DSQL
Wire protocolPGPGPG(subset)
ArchitectureSingle primarySingle primary + shared storageActive-active distributed
Multi-region write不支援(async replica)不支援(async replica)Strong consistency 多 region
Transaction modelMVCC + snapshot isolationMVCC + snapshot isolationOCC + strong snapshot isolation
Extension任意AWS whitelist無 extension 支援
Operational全部自管AWS 管 storage / failoverAWS 管全部、零接觸
FailoverPatroni 15-60sAurora 30sN/A(永遠 active-active、無 failover 概念)
Cost modelSelf-managed instanceInstance hour + storagePer-DPU + multi-AZ replication

Paradigm shift 的核心:

  1. Transaction semantic:DSQL 用 OCC(Optimistic Concurrency Control)+ strong snapshot isolation、跟 PG 預設 read committed / repeatable read snapshot 不同 — 同 row 有 concurrent write 時、commit 階段才偵測衝突 + abort、application 要 handle 40001 serialization_failure
  2. No extension:PostGIS / pgvector / TimescaleDB / pg_partman 都不能用、依賴這些 feature 的 application 要拆出去
  3. No connection pool stateful:DSQL 內建 connection pool、application 不能依賴 session state(temp table / prepared statement / advisory lock)

Schema gap:PG 對 DSQL 限制

DSQL 是 PG-compatible subset、有幾類功能不支援:

類別PG 支援DSQL 支援
Extension是否(沒 CREATE EXTENSION)
Foreign key constraint是是(截至 2026-09 的官方遷移指南:建表時宣告,DSQL 會檢查關聯列存在)
View / Materialized view是View 部分 / Materialized view 否
JSON / JSONB是部分(無 GIN index 加速)
Foreign data wrapper是否
Stored procedure(PL/pgSQL)是部分(限制多)
Trigger是部分
LISTEN / NOTIFY是否
SELECT ... FOR UPDATE是部分(DSQL OCC semantic)
Sequence(serial / identity)是支援 CREATE SEQUENCE 與 identity column(截至 2026-09 的官方文件:限 bigint、CACHE 必須明寫為 1 或 ≥ 65536);CACHE 1 在高併發下 coordination overhead 高
Table partition是部分
Logical replication slot是否

Migration 必做 schema audit:

 1-- 找所有 extension 依賴
 2SELECT * FROM pg_extension;
 3
 4-- 找 materialized view
 5SELECT schemaname, matviewname FROM pg_matviews;
 6
 7-- 找 sequence
 8SELECT * FROM pg_sequences;
 9
10-- 找 FDW
11SELECT * FROM pg_foreign_server;
12
13-- 找 trigger
14SELECT * FROM pg_trigger WHERE NOT tgisinternal;

extension、materialized view、FDW 命中是 migration blocker(schema gap 表中 DSQL 不支援);trigger 與 sequence 在同一張表屬部分支援或有吞吐限制,命中後逐一確認,sequence 的判斷見〈Sequence 高吞吐撞 Coordination Overhead〉。

Operational Redesign

跟 self-managed PG 或 Aurora PG 比、DSQL operational model 大幅簡化但語意不同:

Operational conceptself-managed PGAurora PGAurora DSQL
StorageLocal / EBSShared 6 副本Distributed log + replicated state
HAPatroniAurora failover永遠 HA(無 failover 概念)
BackuppgBackRest / WAL-G內建 continuous內建 continuous(更深整合)
Connection poolPgBouncer / PgCatRDS Proxy 推薦內建(無需配置)
Major version upgrade手動 + 停機Aurora blue/green完全 transparent(AWS 升)
Read replicaStreaming replicationReader endpoint無分(每 region 都讀寫)
MonitoringPrometheus / pg_stat_*CloudWatch + Performance InsightsCloudWatch(簡化)
預期 SRE FTE0.5-20.2-0.5< 0.1

Migration 流程:Paradigm Shift 的分階段計畫

Paradigm shift 的分階段計畫、跟 migrate-to-cockroachdb 結構類似:

Schema / Application Audit

  • 跑 schema audit(extension / MV / FDW / sequence / trigger)
  • 識別 application 哪些 query / transaction pattern 需重設計
  • 估算 能直接遷的 % vs 需重寫的 %、典型 60-80% / 20-40%

Application 改造(不上 DSQL、先在 PG 跑)

  • 加 transaction retry middleware(攔截 40001、exponential backoff)
  • 用 UUID 替代 serial / bigserial
  • 移除依賴 LISTEN/NOTIFY 的功能(改 SQS / EventBridge)
  • 移除 materialized view(改 application-side cache 或 incremental ETL)
  • Stored procedure 改 application code
  • 在 PG 上跑 staging、確認新 application code 還對

DSQL Cluster 建立 + Schema 遷

  • DSQL cluster create
  • DDL apply(subset of PG schema、無 extension)
  • DMS(Database Migration Service)initial load + ongoing replication
  • PG 與 DSQL 同時接 shadow traffic、比對兩者的 query 結果

Cutover

  • Application 切 connection string 到 DSQL
  • 保留 PG read-only 一週、出狀況 rollback
  • Monitor 40001 retry rate、scaling event 行為

多 region 拓展(如適用)

  • 加第二 region endpoint
  • Application 改 multi-region routing(latency-based)
  • Test region failure / network partition 行為

Production 踩雷

Transaction Retry 沒處理

情境:PG 上「兩個 transaction 都 update 同 row」走 lock + wait;DSQL 同情境一個會收 40001 serialization_failure、application 沒 catch、user 看到 500 error。

修法:

  • DAO 層加 retry middleware:catch 40001 + exponential backoff(jitter)
  • Retry 上限 3-5 次、超過回 4xx 給 user
  • Transaction 內不要做 side effect(API call / message send)、retry 會重做
1def with_retry(fn, max_attempts=5):
2    for attempt in range(max_attempts):
3        try:
4            return fn()
5        except SerializationError:
6            if attempt == max_attempts - 1:
7                raise
8            time.sleep((2 ** attempt) * 0.05 + random.random() * 0.05)

Extension 缺位、Feature 整段掉

情境:production PG 用 pgvector 做 RAG search、PostGIS 做 store locator、TimescaleDB 做 metrics — 切 DSQL 後三 feature 全沒。

修法:

  • 不要直接遷、評估 which extension is load-bearing
  • pgvector → 外掛 Pinecone / Weaviate 或保留 PG 跑 vector workload
  • PostGIS → 保留 PG 跑 GIS workload
  • TimescaleDB → 切 Amazon Timestream 或保留 PG
  • DSQL 只放 不依賴 extension 的 transactional core

實務常見拓撲:DSQL 跑 transactional core、附 PG(vector) + PG(GIS) + Timestream(metrics)。

Sequence 高吞吐撞 Coordination Overhead

情境:SERIAL / GENERATED AS IDENTITY PK 在 DSQL 用、insert 量 1000+/s 時 sequence nextval 變成 bottleneck、insert latency 從 5ms 跳到 80-100ms+。

DSQL 有支援 sequence,而 sequence 操作需要 coordination。截至 2026-09 的官方文件要求建立 sequence 時明寫 CACHE、只接受 CACHE = 1 或 CACHE >= 65536:CACHE = 1 時每次 nextval 都走 coordination,併發一高就成為瓶頸;CACHE >= 65536 時每個 session 從本地預先配置的區段取值,吞吐較高,代價是值會有空洞、跨 session 不保證嚴格遞增。

修法:

  • 高吞吐表 PK 換 UUID(無 coordination):gen_random_uuid() 產生的是 random 的 UUID v4;要 time-sortable 就在 application 端用 UUID v7 library
  • 或 application-side ULID(time-sortable、128-bit,與 UUID 同長度)
  • 完全避免依賴「連續 integer PK」的 application 邏輯(reporting / paging 改用 ORDER BY created_at, id)
1-- 換 UUID PK
2CREATE TABLE orders (
3    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
4    ...
5);

低吞吐表(settings / config)保留 sequence OK;high-volume transactional 表(orders / events)建議 UUID。

Aurora PG 直升 DSQL 想當 in-place

情境:team 以為「Aurora PG 跟 Aurora DSQL 都是 Aurora、應該能直升」、申請 cluster modify、發現完全是兩個 service。

修法:

  • 這是 full migration(DMS + cutover),而不是 in-place upgrade
  • 把 DSQL 當完全新的 cluster type、走從 schema / application audit 到 cutover 的完整流程
  • Aurora PG → Aurora DSQL 不比 PG → CRDB 容易、wire-compatible 只解 application connect 問題、不解 schema / paradigm 差異

Region Failover Semantic

情境:team 以為「DSQL multi-region 等於高可用」、設計時假設「整 region 掛還是能寫」、實測發現「網絡分割時 DSQL 走 quorum、可能 reject write」。

DSQL 是 strong consistency 多 region、CAP 取 CP(不是 AP)— network partition 時部分 region 會拒絕 write、不是「永遠可寫」。

修法:

  • 設計 application 要 handle write reject(partition recovery 後 retry)
  • 不要把 DSQL 當「永遠可寫」的 cache 或 queue 用
  • 真要 AP 行為、用 DynamoDB(global table)

Capacity 規劃

DSQL 計費跟 Aurora PG 差很多:

計費項目Aurora PGAurora DSQL
InstancePer-instance hour無(serverless)
StoragePer-GB-monthPer-GB-month(多副本價)
IOPer-million IO每 transaction 計費
BackupPer-GB-month內建(無額外)
Multi-regionCross-region replica(額外)每 region 全費 × N

實務 cost:Aurora PG db.r6g.4xlarge multi-AZ 月 ~$2000 → DSQL 同 workload ~$5000-10000(依 region 數)。

何時 DSQL cost 划算:

  • 多 region active-active 需求剛性(不是 nice-to-have)
  • Operational FTE 節省超過 cost 差
  • Burst workload(DSQL 自動 scale、Aurora PG 預配置 idle 期浪費)

跟既有 Migration Playbook 對比

MigrationType主結構
→ Aurora PGCProtocol drop-in + operational redesign
→ CockroachDBEParadigm shift(distributed SQL)
→ Aurora DSQL(本篇)EParadigm shift(PG-compatible distributed)

Aurora DSQL vs CockroachDB 選擇:

維度Aurora DSQLCockroachDB
PG compatibilityWire-compatible 較完整高、但有差異
Vendor lock-inAWS only跨雲 / on-prem
CostAWS pricing自管或 CockroachDB Cloud
Multi-region 模型Strong consistency 內建可配置(regional / global table)
Extension完全沒部分(CDC / changefeed)
OperationalZero-touch自管或 managed

選 DSQL:已綁 AWS、不想管基礎設施、需 PG semantic。 選 CRDB:跨雲、有自管 SRE、需要 fine-grained control。

相關連結

下一步