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.
| Host | Role | IP | Port |
|---|---|---|---|
pg-primary-01 | PostgreSQL Primary (R/W) | 192.168.10.10 | 5432 |
pg-replica-01 | Read Replica | 192.168.10.11 | 5432 |
pg-replica-02 | Read Replica | 192.168.10.12 | 5432 |
pgbouncer-01 | Connection Pooler | 192.168.10.5 | 6432 |
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_activitycount ≥max_connections(mặc định 200). - Maintenance có lịch: Restart theo kế hoạch sau khi apply OS/PostgreSQL patch.
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ầu | Chi tiết |
|---|---|
| Quyền SSH | ssh sre@pg-primary-01 với key đã được approve trong Vault |
| Quyền sudo | Cần sudo systemctl — kiểm tra với sudo -l trước |
| PgBouncer admin | psql -h 192.168.10.5 -p 6432 -U pgbouncer pgbouncer |
| Incident open | PagerDuty incident phải đang active trước khi bắt đầu |
| Monitoring tab | Mở 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"
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