Chuyển tới nội dung chính

Restart Payment Gateway Database (PostgreSQL Primary)

AI-Generated Content — Tài liệu này được tạo tự động. SRE on-call phải review và xác nhận trước khi áp dụng vào production.

Kiến trúc hệ thống (System Architecture)

Sơ đồ bên dưới mô tả topology của database cluster cho service payment-gateway. Mọi write traffic đi qua PostgreSQL Primary; read traffic được phân phối tới các Read Replica thông qua PgBouncer connection pooler.

Database Topology — Payment Gateway

HostRoleIPPort
pg-primary-01PostgreSQL Primary (R/W)192.168.10.105432
pg-replica-01Read Replica192.168.10.115432
pg-replica-02Read Replica192.168.10.125432
pgbouncer-01Connection Pooler192.168.10.56432

1. Điều kiện sử dụng (When to use)

Áp dụng runbook này khi gặp một trong các điều kiện sau:

  • DB không phản hồi: Query timeout > 30s liên tục, metric pg_up{instance="pg-primary"} = 0.
  • Memory exhaustion: RAM usage > 95%, OOM killer đã tắt worker process.
  • Connection exhaustion: pg_stat_activity count ≥ max_connections (mặc định 200).
  • Maintenance có lịch: Restart theo kế hoạch sau khi apply OS/PostgreSQL patch.
Không áp dụng khi

Khi nguyên nhân là data corruption hoặc disk failure — escalate ngay lên Database Lead thay vì tự restart.


2. Yêu cầu trước khi thực hiện (Prerequisites)

Yêu cầuChi tiết
Quyền SSHssh sre@pg-primary-01 với key đã được approve trong Vault
Quyền sudoCần sudo systemctl — kiểm tra với sudo -l trước
PgBouncer adminpsql -h 192.168.10.5 -p 6432 -U pgbouncer pgbouncer
Incident openPagerDuty incident phải đang active trước khi bắt đầu
Monitoring tabMở sẵn Grafana PostgreSQL dashboard

3. Quy trình thực hiện (Execution Steps)

Sequence diagram — tương tác giữa các thành phần trong quá trình restart:

Process flow — sơ đồ quyết định chi tiết (interactive, có thể zoom và pan):

loading...

Bước 1 — Xác nhận alert và tình trạng replica

Kiểm tra cả hai replica đang lag < 5MB trước khi tiến hành — đây là safety net nếu restart thất bại:

# Từ pg-primary-01
psql -U postgres -c "
SELECT client_addr,
state,
pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) AS lag_bytes
FROM pg_stat_replication;
"

Tiêu chí tiếp tục: cả hai replica phải có lag_bytes < 5242880 (5 MB) và state = 'streaming'. Nếu một replica đang lag cao hoặc down — dừng lại và escalate tới L3 SRE.

Bước 2 — Drain connections qua PgBouncer

Chuyển PgBouncer sang trạng thái pause để ngừng nhận connection mới, đợi các transaction đang chạy kết thúc:

psql -h 192.168.10.5 -p 6432 -U pgbouncer pgbouncer \
-c "PAUSE pgbouncer;"

Kiểm tra không còn active connection:

psql -h 192.168.10.5 -p 6432 -U pgbouncer pgbouncer \
-c "SHOW POOLS;" | grep -v "^$\|cl_active"
thông tin

Nếu cl_active không về 0 sau 60 giây, kiểm tra transaction dài bất thường:

psql -U postgres -c "SELECT pid, query, now() - query_start AS duration FROM pg_stat_activity WHERE state = 'active' ORDER BY duration DESC LIMIT 5;"

Bước 3 — Thông báo stakeholders

Post lên Slack #sre-incidents trước khi thực hiện bất kỳ thao tác nào trên DB:

🔴 [DB MAINTENANCE] Đang khởi động lại PostgreSQL Primary cho payment-gateway.
Ước tính downtime: ~2 phút. Replica vẫn phục vụ read traffic.
Incident: <link PagerDuty>

Bước 4 — Stop PostgreSQL service

ssh sre@pg-primary-01
sudo systemctl stop postgresql@16-main

Xác nhận process đã dừng hoàn toàn:

sudo systemctl is-active postgresql@16-main # phải trả về: inactive
ps aux | grep postgres # không còn process nào

Bước 5 — Chờ graceful shutdown (30 giây)

sleep 30

Bước này đảm bảo shared memory và WAL buffer được flush sạch trước khi start lại, tránh recovery time dài.

Bước 6 — Start PostgreSQL service

sudo systemctl start postgresql@16-main

Theo dõi startup log ngay lập tức:

sudo journalctl -u postgresql@16-main -f --since "1 minute ago"

Dấu hiệu startup thành công (phải xuất hiện trong vòng 30 giây):

LOG: database system is ready to accept connections
LOG: replication slot "replica_01" restored successfully

Nếu log báo lỗi (ví dụ FATAL: could not write lock file) — xem Phương án Rollback.

Bước 7 — Resume PgBouncer

psql -h 192.168.10.5 -p 6432 -U pgbouncer pgbouncer \
-c "RESUME pgbouncer;"

4. Quy trình xác minh (Verification Steps)

Thực hiện tất cả các kiểm tra sau trước khi đóng incident:

# 1. PostgreSQL Primary nhận connection bình thường
psql -h 192.168.10.10 -U postgres -c "SELECT version();"

# 2. Replication đã tự kết nối lại và lag trở về 0
psql -U postgres -c "SELECT client_addr, state, lag_bytes FROM pg_stat_replication_detail();"

# 3. PgBouncer pool healthy
psql -h 192.168.10.5 -p 6432 -U pgbouncer pgbouncer -c "SHOW STATS;"

Trên Grafana dashboard:

  • pg_up{instance="pg-primary"} = 1
  • pg_stat_replication_lag_bytes < 1 MB và giảm dần về 0
  • pgbouncer_pools_sv_active > 0 (connection pool đang phục vụ)
  • Payment Gateway error rate (http_errors_total{service="payment-gateway"}) về baseline

5. Phương án rollback (Rollback Plan)

Kịch bản A — PostgreSQL không start được

Nếu systemctl start thất bại, kiểm tra WAL corruption:

sudo -u postgres /usr/lib/postgresql/16/bin/pg_resetwal --dry-run /var/lib/postgresql/16/main

Nếu cần thiết, promote Replica 1 làm primary mới:

# Trên pg-replica-01
sudo -u postgres /usr/lib/postgresql/16/bin/pg_promote

Sau đó cập nhật DNS record db-primary.internal trỏ về 192.168.10.11 và thông báo team.

Kịch bản B — Restart thành công nhưng replication lag cao

Không cần rollback — replica sẽ tự đồng bộ (physical streaming replication). Theo dõi lag_bytes giảm đều đặn. Nếu lag không giảm sau 10 phút:

# Kiểm tra replication slot
psql -U postgres -c "SELECT slot_name, active, restart_lsn FROM pg_replication_slots;"

Kịch bản C — PgBouncer không resume được

# Restart PgBouncer service
sudo systemctl restart pgbouncer

# Kiểm tra config
sudo pgbouncer -d /etc/pgbouncer/pgbouncer.ini --check-config
X

Graph View