PostgreSQL local lab quickstart 的核心責任是建立後續 connection、migration、backup 與 failover 演練共用的本地環境。這個 lab 提供一個可重建的 PostgreSQL instance、app-facing user、baseline schema、seed data 與 basic evidence。

本文的驗收標準是:你能啟動本地 PostgreSQL,套用 schema,跑 sample workload,取得 pg_stat_activity / pg_stat_database snapshot,最後 teardown 並重建。

Docker Compose

Docker Compose 的核心責任是讓 lab 環境可重建。建立 docker-compose.yml

 1services:
 2  postgres:
 3    image: postgres:16
 4    environment:
 5      POSTGRES_USER: lab_admin
 6      POSTGRES_PASSWORD: lab_admin_pw
 7      POSTGRES_DB: appdb
 8    ports:
 9      - "54329:5432"
10    command:
11      - "postgres"
12      - "-c"
13      - "log_min_duration_statement=100"
14      - "-c"
15      - "shared_preload_libraries=pg_stat_statements"

啟動:

1docker compose up -d
2export DATABASE_URL="postgres://lab_admin:lab_admin_pw@localhost:54329/appdb?sslmode=disable"

Baseline Schema

Baseline schema 的核心責任是建立可測 transaction、index、lock 與 migration 的資料模型。

 1psql "$DATABASE_URL" <<'SQL'
 2CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
 3
 4CREATE TABLE accounts (
 5  id bigserial PRIMARY KEY,
 6  tenant_id uuid NOT NULL,
 7  owner_name text NOT NULL,
 8  status text NOT NULL CHECK (status IN ('active', 'closed')),
 9  created_at timestamptz NOT NULL DEFAULT now()
10);
11
12CREATE TABLE ledger_entries (
13  id bigserial PRIMARY KEY,
14  account_id bigint NOT NULL REFERENCES accounts(id),
15  amount_cents bigint NOT NULL CHECK (amount_cents <> 0),
16  idempotency_key text NOT NULL UNIQUE,
17  created_at timestamptz NOT NULL DEFAULT now()
18);
19
20CREATE INDEX idx_ledger_entries_account_created
21ON ledger_entries(account_id, created_at DESC);
22SQL

這組 schema 後續可用於 migration、lock、PITR 與 pool lab。

Seed and Workload

Seed and workload 的核心責任是產生可觀察的資料與查詢。

 1psql "$DATABASE_URL" <<'SQL'
 2INSERT INTO accounts(tenant_id, owner_name, status)
 3VALUES
 4  ('00000000-0000-0000-0000-000000000001', 'Ada', 'active'),
 5  ('00000000-0000-0000-0000-000000000002', 'Lin', 'active');
 6
 7INSERT INTO ledger_entries(account_id, amount_cents, idempotency_key)
 8SELECT 1, 100, 'seed-ada-' || g
 9FROM generate_series(1, 100) AS g;
10
11SELECT a.owner_name, SUM(l.amount_cents) AS balance_cents
12FROM accounts a
13JOIN ledger_entries l ON l.account_id = a.id
14GROUP BY a.owner_name;
15SQL

Sample workload 要保留 SQL 與輸出,作為後續 migration / restore validation 的 baseline。

Basic Evidence

Basic evidence 的核心責任是把 lab 狀態保存成可比較 snapshot。

 1psql "$DATABASE_URL" <<'SQL'
 2SELECT current_database(), current_user, version();
 3SELECT relname, n_live_tup FROM pg_stat_user_tables ORDER BY relname;
 4SELECT datname, numbackends, xact_commit, xact_rollback
 5FROM pg_stat_database
 6WHERE datname = current_database();
 7SELECT pid, state, wait_event_type, query
 8FROM pg_stat_activity
 9WHERE datname = current_database();
10SQL

這些查詢是 PostgreSQL lab 的最小 evidence。正式服務要再加入 slow query、lock wait、replica lag、backup status 與 pooler metrics。

Teardown

Teardown 的核心責任是讓 lab 可重跑。

1docker compose down -v

重建後應能重新套用 schema 與 seed。若 lab 需要跨章節沿用資料,先用 pg_dump 保存 fixture,再 teardown。

下一步路由

完成本篇後,連線壓力進入 Connection Pool Lab;migration evidence 進入 Schema Migration Evidence Lab;backup / PITR 進入 PITR Restore Drill