这是《PostgreSQL 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 物理复制传输 WAL,使备库拥有与主库一致的物理数据块。它是高可用、读写分离和灾备的基础。
21.1 架构
Primary
walsender -> WAL stream
|
Standby
walreceiver -> write / flush / replay
备库回放 WAL,达到物理一致。
21.2 基础配置
主库:
listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
创建复制用户:
CREATE ROLE replicator WITH REPLICATION PASSWORD 'strong-password';
pg_hba.conf:
hostssl replication replicator 10.0.0.0/8 scram-sha-256
21.3 初始化备库
使用 pg_basebackup:
pg_basebackup \
-h primary.internal \
-U replicator \
-D /var/lib/postgresql/16/standby \
-Fp -Xs -P -R
-R 会写入 standby.signal 和连接信息。
21.4 复制状态
SELECT
pid,
application_name,
client_addr,
state,
sync_state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn,
write_lag,
flush_lag,
replay_lag
FROM pg_stat_replication;
备库:
SELECT status, sender_host, received_lsn, latest_end_lsn
FROM pg_stat_wal_receiver;
21.5 同步复制
synchronous_standby_names = 'FIRST 1 (standby01)'
模式:
| synchronous_commit | 等待点 |
|---|---|
| remote_write | 备库写入 |
| remote_flush | 备库刷盘 |
| remote_apply | 备库回放 |
同步复制降低失败丢数据风险,但增加提交延迟。
21.6 延迟复制
recovery_min_apply_delay = 5min
适合防误删和保留恢复窗口,但备库持续延迟,不适合常备读一致性查询。
21.7 复制槽
SELECT pg_create_physical_replication_slot('standby01');
复制槽保留 WAL,防止备库需要的历史日志被删除。必须监控:
SELECT slot_name, active, restart_lsn,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained
FROM pg_replication_slots;
21.8 级联复制
Primary -> Standby01 -> Standby02
下游备库从 Standby01 接收 WAL,减少主库 walsender 压力。注意整体拓扑和延迟监控。
21.9 故障切换
切换要做:
- 确认主库状态;
- 停止应用写入;
- 等待或评估 LSN 差异;
- 提升备库;
- 修改连接入口;
- 重建旧主库;
- 验证数据和复制。
提升备库:
SELECT pg_promote();
本章小结
物理复制基于 WAL,数据一致性强,适合 HA 和灾备。生产必须监控 LSN 延迟、复制槽保留和切换流程。同步策略要在性能与可靠性之间明确取舍。
思考题
- 流复制的延迟如何计算?
- 同步和异步复制的差异是什么?
- 复制槽有哪些风险?
- 延迟复制适合什么场景?
- 故障切换前应确认哪些信息?