PostgreSQL 复制实战:从流复制、逻辑复制到故障转移的完整指南
【免费下载链接】claude-skills67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.项目地址: https://gitcode.com/GitHub_Trending/claud/claude-skills
导读
本文以 claude-skills 仓库中 Postgres Pro 技能 的复制主题参考文档 references/replication.md 为主体,系统讲解 PostgreSQL 复制体系——从物理流复制的搭建、同步提交策略,到逻辑复制、级联与延迟复制、故障转移高可用方案,再到基于 WAL 归档的备份与时间点恢复(PITR)。读完本文,你将掌握一套可直接落地的主从复制部署命令、监控与告警 SQL、故障排查步骤,并理解各方案背后的数据一致性与可用性取舍。该文档是仓库 67 个专用技能之一 "postgres-pro"(PostgreSQL 专家技能)的核心参考,适用于数据库管理员与后端工程师在生产环境构建读写分离与高可用架构。
一、PostgreSQL 复制体系总览
PostgreSQL 的复制能力分为两大类,两者都建立在预写日志(WAL)机制之上,但在实现粒度与适用场景上截然不同:
| 维度 | 物理流复制(Streaming Replication) | 逻辑复制(Logical Replication) |
|---|---|---|
| 复制单位 | 整个实例的 WAL(块级物理变更) | 行级数据变更(INSERT/UPDATE/DELETE) |
| 粒度 | 整实例复制 | 可指定表、schema、行过滤器 |
| 版本要求 | 主备版本需一致 | 主备版本可跨大版本(向下兼容) |
| 典型场景 | 高可用、读写分离、热备份 | 数据分发、部分表同步、升级迁移 |
| 复制内容 | 全部对象(含 DDL、索引) | 仅表数据的 DML(PG 15 后可含部分 DDL) |
postgres-pro技能的 SKILL.md 将"Setup replication — Streaming or logical based on requirements; monitor lag continuously"列为核心工作流的第 4 步,并将"Monitor replication lag viapg_stat_replication"列入强制约束(MUST DO)。这意味着复制方案选型与持续监控是本技能处理数据库问题时的标准动作,本文接下来的内容正是该流程的完整实操展开。
适用版本说明:本文参数与语法以 PostgreSQL 12~16 为主(这也是 SKILL.md 中 Knowledge Reference 声明的目标版本范围)。其中
wal_keep_size为 PG 13 起替代wal_keep_segments的参数;FOR TABLES IN SCHEMA与WHERE行过滤器为 PG 15+ 特性;pg_promote()函数自 PG 12 起可用。低版本环境需按官方对应参数调整。
二、物理流复制(Streaming Replication)搭建
物理流复制是 PostgreSQL 高可用的基石:主库持续把 WAL 记录传输给备库,备库按序重放,形成与主库块级一致的数据副本。
2.1 主库配置
第一步:编辑postgresql.conf
-- postgresql.conf wal_level = replica max_wal_senders = 10 max_replication_slots = 10 wal_keep_size = 1GB # Or 1024MB for older versions hot_standby = on archive_mode = on archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f'各参数的作用与调优要点:
wal_level = replica:WAL 中写入足够信息以支持复制与归档,是流复制的最低要求;max_wal_senders:允许同时存在的 WAL 发送进程上限,至少应大于备库数量 + 基础备份连接数,默认 10 对小型集群通常够用;max_replication_slots:复制槽上限,逻辑复制与物理复制槽共用此额度;wal_keep_size = 1GB:在主库 pg_wal 目录中保留的额外 WAL 量,用于备库暂时断开后的追赶,旧版本使用wal_keep_segments(以段数计);hot_standby = on:允许备库接受只读查询,这是读写分离的基础,对大部分工作负载建议开启;archive_mode = on与archive_command:启用 WAL 归档,与流复制互补,既作为备份基础,也能在备库长期掉线时补送缺失 WAL。
第二步:配置pg_hba.conf允许复制连接
-- pg_hba.conf (allow replication connections) host replication replicator 10.0.0.0/24 scram-sha-256复制连接使用replication数据库名,与普通连接分离授权。scram-sha-256是目前推荐的强认证方式(PG 10+ 支持)。
第三步:创建复制角色与复制槽
-- Create replication user CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'secure_password'; -- Create replication slot (prevents WAL deletion) SELECT * FROM pg_create_physical_replication_slot('replica_1');复制槽(replication slot)的作用是防止主库在备库未消费 WAL 之前就将其清理:槽位记录了备库的消费位点,主库会因此保留对应的 WAL。代价是如果备库长期离线,主库磁盘会被持续增长且未被消费的 WAL 撑满,监控中必须关注槽位保留量(详见"复制槽监控"小节)。
2.2 备库搭建
# Stop PostgreSQL on standby systemctl stop postgresql # Remove data directory rm -rf /var/lib/postgresql/14/main/* # Base backup from primary pg_basebackup -h primary-host -D /var/lib/postgresql/14/main \ -U replicator -P -v -R -X stream -S replica_1 # -R creates standby.signal and recovery config # -X stream: stream WAL during backup # -S replica_1: use replication slotpg_basebackup是从主库拉取一致性基础备份的标准工具,参数含义:
-h primary-host -U replicator:连接主库与复制用户;-P -v:显示进度与详细信息,便于确认备份过程;-R:自动写入standby.signal(PG 12+ 标识备库的信号文件)并把恢复参数写入postgresql.auto.conf,免去手工创建;-X stream:在备份进行期间以流式方式接收新增 WAL,使备份集完整可用;-S replica_1:在备份过程中绑定第 2.1 节创建的主库复制槽,防止备份期间 WAL 被回收。
备份完成后,备库的恢复配置如下(-R自动生成,也可以手工维护):
-- standby.signal file created by pg_basebackup -R -- recovery parameters in postgresql.auto.conf: primary_conninfo = 'host=primary-host port=5432 user=replicator password=secure_password' primary_slot_name = 'replica_1'primary_conninfo指定连接主库的信息;primary_slot_name关联第 2.1 节创建的物理复制槽,确保备库在长时间重放延迟或断线后仍能追赶到最新 WAL,而不是依赖wal_keep_size的容量上限。生产环境强烈建议两者配合使用:槽位兜底保序,wal_keep_size提供短期冗余。
2.3 复制状态监控
在主库查看复制健康度:
-- On primary: Check replication status SELECT client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn, pg_wal_lsn_diff(sent_lsn, replay_lsn) as lag_bytes FROM pg_stat_replication;字段解读:
state:streaming表示正在正常流式接收,catchup表示正在追赶;sync_state:sync(同步)、async(异步)、potential(同步候选,详见同步复制一节);sent_lsn / write_lsn / flush_lsn / replay_lsn:分别表示 WAL 已发送、已写入备库内核、已刷新到磁盘、已重放到数据页的位点;replay_lsn是备库真正对外可见数据的位置;pg_wal_lsn_diff(sent_lsn, replay_lsn):主备之间的字节级滞后,是判断"备库落后多少"最直接的口径。
在备库查看重放滞后:
-- On standby: Check replay lag SELECT now() - pg_last_xact_replay_timestamp() AS replication_lag;该查询返回最近一次已重放事务距现在的时间间隔,是"时间滞后"视角的度量。若备库处于空闲(无新写入),此值自然增长,需结合 LSN 差值一起判断,避免误报。
检查复制槽占用:
-- Check replication slots SELECT slot_name, slot_type, active, restart_lsn, pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) as retained_bytes FROM pg_replication_slots;restart_lsn是槽位允许的最早可重放位点;retained_bytes表示该槽强制保留的 WAL 字节数。若某个槽长期active = false且保留量持续增长,说明对应备库已断开但槽位仍占着主库磁盘,需要及时处理(删除槽或重建备库)。
2.4 同步复制:在性能与可靠性之间取平衡
默认的流复制是异步的:主库提交事务后不必等待备库确认。同步复制则让每个事务在备库确认写入/落盘/重放后才返回成功,从而做到"主库故障不丢已提交事务"(Zero Data Loss)。
-- postgresql.conf on primary synchronous_commit = on synchronous_standby_names = 'FIRST 1 (replica_1, replica_2)' # Waits for 1 standby to confirm before commit # Options: # FIRST n (names): Wait for n standbys # ANY n (names): Wait for any n standbys # name: Wait for specific standbysynchronous_commit = on:事务提交时等待备库确认;synchronous_standby_names = 'FIRST 1 (replica_1, replica_2)':从列表中按顺序取前 1 个备库作为同步目标。FIRST n适合固定主备拓扑,ANY n适合多备库、要求更松的场景(如 3 备库中任意 2 个确认),也可以直接写单个备库名强制等待指定节点。
确认当前谁是同步节点:
-- Query to check sync status SELECT application_name, sync_state, state FROM pg_stat_replication; -- sync_state: sync (synchronous), async, potential其中sync表示当前同步目标(事务提交需其确认),potential表示若当前同步节点失效将被提升为同步目标,async为普通异步备库。
权衡提醒:同步复制会放大主备网络延迟对写入性能的影响——每次提交都要等待远程确认。若同步备库宕机,主库会阻塞所有提交(这正是保证不丢数据的代价)。常见的生产策略是"1 个同步备 + 1 个异步备"或使用ANY n,既获得强一致保证,又保留容错余地。
三、逻辑复制(Logical Replication):行级数据分发
逻辑复制面向行级变更,天然适合异构版本同步、局部数据分发、迁移与微服务解耦等场景,也是跨 PostgreSQL 大版本升级的主流路径(PG 11 起由内置 publish/subscribe 机制提供)。
3.1 发布端(Publisher)配置
-- postgresql.conf wal_level = logical max_replication_slots = 10 max_wal_senders = 10注意:wal_level = logical是逻辑复制的前提,它的 WAL 信息量大于replica。修改后需要重启实例才能生效。
创建发布(Publication)的四种方式:
-- Create publication (all tables) CREATE PUBLICATION my_publication FOR ALL TABLES; -- Or specific tables CREATE PUBLICATION my_publication FOR TABLE users, orders; -- Or tables matching pattern (PG15+) CREATE PUBLICATION my_publication FOR TABLES IN SCHEMA public; -- With row filters (PG15+) CREATE PUBLICATION active_users FOR TABLE users WHERE (active = true);FOR ALL TABLES:复制全库所有表,最简单,但未来新增表也会被自动纳入;FOR TABLE ...:精确控制复制的表清单,适合只同步核心业务表的场景;FOR TABLES IN SCHEMA public(PG 15+):按 schema 批量纳入,兼顾控制力与扩展性;WHERE行过滤器(PG 15+):只发布满足条件的行,适合"仅同步活跃用户"这类数据子集需求。
查看发布定义:
-- View publications SELECT * FROM pg_publication; SELECT * FROM pg_publication_tables;3.2 订阅端(Subscriber)配置
-- Create subscription (creates replication slot on publisher) CREATE SUBSCRIPTION my_subscription CONNECTION 'host=publisher-host port=5432 dbname=mydb user=replicator password=pass' PUBLICATION my_publication;创建订阅的完整选项:
-- Subscription options CREATE SUBSCRIPTION my_subscription CONNECTION 'host=publisher-host dbname=mydb user=replicator' PUBLICATION my_publication WITH ( copy_data = true, -- Initial data copy create_slot = true, -- Create replication slot enabled = true, -- Start immediately slot_name = 'my_sub_slot', synchronous_commit = 'off' -- Performance vs durability );copy_data = true:订阅创建时先执行一次初始全量数据拷贝(表结构需预先在订阅端建好);create_slot = true:在发布端自动创建逻辑复制槽,可指定slot_name手动命名便于管理;enabled = true:创建后立即启动复制;synchronous_commit:订阅端的提交级联控制,off提升性能(订阅端允许落后),追求订阅端数据即时可用时可调高。
订阅管理命令:
-- View subscriptions SELECT * FROM pg_subscription; SELECT * FROM pg_stat_subscription; -- Manage subscription ALTER SUBSCRIPTION my_subscription DISABLE; ALTER SUBSCRIPTION my_subscription ENABLE; ALTER SUBSCRIPTION my_subscription REFRESH PUBLICATION; DROP SUBSCRIPTION my_subscription;REFRESH PUBLICATION用于在发布端表清单变化后同步订阅端的复制关系(重新扫描发布端表的元数据);DROP SUBSCRIPTION会默认清理发布端对应的逻辑复制槽。
3.3 逻辑复制监控
发布端:查看逻辑复制槽的消费进度
-- On publisher: Check replication slots SELECT slot_name, plugin, slot_type, active, pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn) as lag_bytes FROM pg_replication_slots WHERE slot_type = 'logical';逻辑复制使用confirmed_flush_lsn(订阅端已确认消费并落盘的位点)而非物理复制槽的restart_lsn来衡量进度;plugin字段通常为pgoutput(内置输出插件)。同样需要警惕订阅端长期离线导致 WAL 积压。
订阅端:查看订阅接收状态
-- On subscriber: Check subscription status SELECT subname, pid, received_lsn, latest_end_lsn, last_msg_send_time, last_msg_receipt_time, latest_end_time FROM pg_stat_subscription;received_lsn:订阅端已接收的 LSN;latest_end_lsn:订阅端期望的下一接收位点;last_msg_send_time:发布端最近一次发送消息的时间;last_msg_receipt_time:订阅端最近一次确认接收的时间。两者差距拉大说明网络或应用层消费出现瓶颈。
四、级联复制(Cascading Replication)
级联复制允许备库再充当其他备库的"上游",形成链式拓扑,减少主库直接承载的 WAL 发送压力,适合多机房、多备库的大规模场景。
Primary -> Standby1 -> Standby2-- On Standby1 (acts as relay) -- postgresql.conf hot_standby = on max_wal_senders = 10 wal_keep_size = 1GB -- Standby2 connects to Standby1 -- Same setup as regular standby, but primary_conninfo points to Standby1 primary_conninfo = 'host=standby1-host user=replicator...'要点:
- 充当转发节点的 Standby1 必须开启
hot_standby并配置max_wal_senders(它需要向 Standby2 发送 WAL),同时最好设置wal_keep_size或复制槽以兜底下游追赶; - Standby2 的搭建流程与普通备库完全一致,唯一区别是
primary_conninfo指向 Standby1 而不是主库; - 注意数据延迟会沿链路累积:Standby2 的重放位点天然落后于 Standby1,监控滞后时需分别按链路层级评估。
五、延迟复制(Delayed Standby)
延迟备库通过人为延迟重放,为数据误删、错误批量更新等事故保留一扇"后悔之窗"。
-- On standby: postgresql.conf recovery_min_apply_delay = '4h' -- Useful for: -- - Protection against accidental data deletion -- - Rolling back to specific point in time -- - Can promote delayed standby to recover dropped tablerecovery_min_apply_delay = '4h':备库收到 WAL 后延迟 4 小时再重放;- 典型用途:主库发生误删或错误更新时,延迟备库中仍保留事故前 4 小时内的完整数据,可将其提升(promote)为临时主库,导出被误删的表后回灌;
- 注意该参数只延迟重放,不延迟接收——WAL 仍会持续传输,因此延迟备库需要与普通备库相同的网络与磁盘带宽。
检查当前实际延迟量:
-- Check delay SELECT now() - pg_last_xact_replay_timestamp() AS current_delay;六、故障转移与提升(Failover & Promotion)
当主库不可用时,需要把某个备库提升为新主库。提升后旧主库应降级为备库或被隔离,拓扑即完成切换。
6.1 手工故障转移
# On standby server # Promote standby to primary pg_ctl promote -D /var/lib/postgresql/14/main # Or use SQL SELECT pg_promote();验证提升结果:
-- Verify promotion SELECT pg_is_in_recovery(); -- Should return falsepg_is_in_recovery()返回false表示已脱离恢复模式成为主库。手工提升的缺点是 RTO 依赖人工响应,且提升后如何让原主库安全回归需要额外编排(如使用pg_rewind让旧主追平新主)。
6.2 自动故障转移:pg_auto_failover
pg_auto_failover(Citus 团队开源)通过独立的 monitor 节点仲裁,自动完成主备提升与回归:
# Install pg_auto_failover apt-get install pg-auto-failover # Setup monitor node pg_autoctl create monitor --hostname monitor-host --pgdata /var/lib/monitor # Setup primary pg_autoctl create postgres \ --hostname primary-host \ --pgdata /var/lib/postgresql/14/main \ --monitor postgres://monitor-host/pg_auto_failover # Setup standby pg_autoctl create postgres \ --hostname standby-host \ --pgdata /var/lib/postgresql/14/main \ --monitor postgres://monitor-host/pg_auto_failover # Check status pg_autoctl show state工作原理:所有节点向 monitor 汇报心跳与状态,monitor 基于多数派决策维护当前主库身份;当主库失联超过阈值时,monitor 选择数据最新的备库提升,旧主恢复后以pg_rewind方式自动重新加入集群。
6.3 Patroni:生产级 HA 方案
Patroni 是生产环境更主流的 HA 管理层,它依赖分布式配置存储(etcd / Consul / ZooKeeper)做选主仲裁,并通过 REST API(默认 8008 端口)对外暴露集群状态,可配合 HAProxy 自动摘除故障节点。
# patroni.yml scope: postgres-cluster name: node1 restapi: listen: 0.0.0.0:8008 connect_address: node1:8008 etcd: hosts: etcd1:2379,etcd2:2379,etcd3:2379 bootstrap: dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true parameters: max_connections: 100 max_wal_senders: 10 wal_level: replica postgresql: listen: 0.0.0.0:5432 connect_address: node1:5432 data_dir: /var/lib/postgresql/14/main authentication: replication: username: replicator password: repl_password superuser: username: postgres password: postgres_password关键配置含义:
scope/name:集群标识与节点名,etcd 中的所有节点必须使用相同scope;etcd.hosts:配置存储集群地址,选主与元数据存储依赖它;bootstrap.dcs.ttl = 30:leader 租约 TTL(秒),节点失联超过 TTL 即触发重新选举;loop_wait = 10与retry_timeout = 10:Patroni 主循环间隔与单次操作超时;maximum_lag_on_failover:允许被提升备库的最大 WAL 滞后字节数(这里 1048576 即 1MB),避免提升一个落后过多的节点丢失太多数据;use_pg_rewind: true:故障切换后旧主回归时用pg_rewind对齐新主,避免全量重建;bootstrap.dcs.postgresql.parameters:由 Patroni 统一下发的 PostgreSQL 参数,保证集群内配置一致;postgresql.authentication:replication 与 superuser 两套认证凭据。
七、高可用下的连接池与负载均衡
7.1 PgBouncer:事务级连接池
数据库连接是昂贵的资源,PgBouncer 通过复用连接显著降低并发开销,这也是 SKILL.md 中"Use connection pooling (pgBouncer, pgPool)"的强制项。
# pgbouncer.ini [databases] mydb = host=primary-host port=5432 dbname=mydb [pgbouncer] listen_addr = * listen_port = 6432 auth_type = scram-sha-256 auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 1000 default_pool_size = 25 reserve_pool_size = 5[databases]:把应用访问的逻辑库名映射到真实 PostgreSQL 节点;pool_mode = transaction:事务级复用,应用事务结束后连接即归还池中,是高并发 Web 场景的推荐模式;max_client_conn = 1000:PgBouncer 可接纳的最大客户端连接数;default_pool_size = 25:每个数据库到后端的常规连接数,reserve_pool_size = 5:高峰期可临时启用的额外连接数,形成弹性缓冲。
7.2 HAProxy:负载均衡与自动摘除
HAProxy 以 TCP 四层代理将客户端流量分发到集群节点,并利用 PostgreSQL 的pg_is_in_recovery健康检查自动区分主备:
# haproxy.cfg frontend postgres_frontend bind *:5432 mode tcp default_backend postgres_backend backend postgres_backend mode tcp option tcp-check tcp-check expect string is_master:true server primary primary-host:5432 check server standby1 standby1-host:5432 check backup server standby2 standby2-host:5432 check backuptcp-check expect string is_master:true:执行SELECT pg_is_in_recovery()并期望返回false,只有当前主库通过健康检查;server ... check标记为可参与负载均衡的节点,backup标记的备库仅在主库不可用时才被启用;- 当 Patroni 或 pg_auto_failover 完成切换后,HAProxy 的检查会自动把流量导向新主库,实现读写入口的自动化收敛。
八、备份与时间点恢复(PITR)
复制不是备份:误删、逻辑损坏、多节点同时故障等场景仍依赖可靠的备份体系。最佳实践是"复制 + WAL 归档"双保险。
8.1 WAL 归档配置
-- postgresql.conf wal_level = replica archive_mode = on archive_command = 'test ! -f /backup/wal/%f && cp %p /backup/wal/%f' archive_timeout = 300 # Force archive every 5 minutes -- Or use pg_archivecleanup archive_command = 'pgbackrest --stanza=main archive-push %p'archive_command在每次 WAL 段切换后执行,%p为源 WAL 路径,%f为文件名;test ! -f防止重复归档同名文件;archive_timeout = 300:即使低写入负载也每 5 分钟强制切换一次 WAL,保证归档时间线的连续性(PITR 目标时间的精度即受此影响);- 生产环境更推荐专用工具归档(如示例中的 pgBackRest),自带校验、压缩与并行传输。
8.2 使用 pg_basebackup 做基础备份
# Full backup pg_basebackup -h localhost -U postgres \ -D /backup/base/$(date +%Y%m%d) \ -Ft -z -P -X fetch # -Ft: tar format # -z: gzip compression # -P: progress # -X fetch: include WAL files-Ft -z:以 tar 格式输出并 gzip 压缩,适合统一备份目录归档;-X fetch:把备份过程中产生的 WAL 一并纳入备份集,保证基础备份的一致性。
8.3 时间点恢复(PITR)完整流程
# Stop PostgreSQL systemctl stop postgresql # Restore base backup rm -rf /var/lib/postgresql/14/main/* tar -xzf /backup/base/20241201/base.tar.gz -C /var/lib/postgresql/14/main # Create recovery.signal touch /var/lib/postgresql/14/main/recovery.signal # Configure recovery # postgresql.conf or postgresql.auto.conf: restore_command = 'cp /backup/wal/%f %p' recovery_target_time = '2024-12-01 14:30:00' # Or: recovery_target_xid, recovery_target_name, recovery_target_lsn # Start PostgreSQL (will recover to target) systemctl start postgresql # After recovery, check SELECT pg_is_in_recovery(); # Should be false after recovery completesrecovery.signal:PG 12+ 标识实例进入恢复模式的信号文件(PG 12 前为recovery.conf);restore_command:从 WAL 归档目录按序取回 WAL 段;- 恢复目标可指定时间(
recovery_target_time)、事务 ID(recovery_target_xid)、还原点(recovery_target_name)或 LSN(recovery_target_lsn); - 恢复完成后
pg_is_in_recovery()返回false,且该实例此后应作为独立节点使用(恢复目标时间线已与生产分叉)。
归档频率与
archive_timeout、备份频率共同决定了 RPO(最多丢失数据量);恢复演练则应定期进行——这也是 maintenance.md 中维护清单"Quarterly: Test backup restoration"的要求。
九、复制监控最佳实践
将常用监控查询固化为视图,是持续观察复制健康度的标准做法:
-- Create monitoring view CREATE VIEW replication_status AS SELECT client_addr, application_name, state, sync_state, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) / 1024 / 1024 AS lag_mb, (pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)::float / (1024 * 1024 * 16))::int AS estimated_wal_segments_behind FROM pg_stat_replication; -- Alert if lag > 100MB SELECT * FROM replication_status WHERE lag_mb > 100; -- Check replication slot disk usage SELECT slot_name, pg_size_pretty( pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) ) as retained_wal FROM pg_replication_slots;要点:
- 视图把 LSN 差值换算为直观的
lag_mb,并估算落后的 WAL 段数(按默认 16MB 段大小推算),可直接对接告警系统; lag_mb > 100可作为初始告警阈值,生产环境中按业务容忍度与网络质量进一步校准;- 复制槽磁盘占用必须纳入常规巡检:槽位保留的 WAL 若不清理,可能耗尽主库磁盘。这与 maintenance.md 中"Daily: Verify replication lag (if applicable)"的维护清单相互印证,复制监控本就是数据库日常维护的一环。
十、故障排查:复制中断与备库滞后
10.1 复制中断的排查步骤
-- Replication broken? -- 1. Check pg_stat_replication on primary SELECT * FROM pg_stat_replication; -- 2. Check logs on standby -- tail -f /var/log/postgresql/postgresql-14-main.log -- 3. Check replication slot exists SELECT * FROM pg_replication_slots WHERE slot_name = 'replica_1'; -- 4. Recreate slot if missing SELECT pg_create_physical_replication_slot('replica_1'); -- 5. Check WAL files available -- ls -lh /var/lib/postgresql/14/main/pg_wal/排查路径:先在主库确认备库是否仍处于streaming状态;再看备库日志获取具体的连接失败原因(认证、网络、磁盘满等);随后核对复制槽是否存在——若槽位丢失(例如被误删),备库重连后将无法确定消费位点;最后确认主库pg_wal/中是否还保留着备库所需的 WAL 段(否则即使重连也会因缺段而失败)。
10.2 备库严重滞后的三种处置
-- Standby too far behind? -- Option 1: Increase wal_keep_size -- Option 2: Use replication slots -- Option 3: Re-run pg_basebackup- 增大
wal_keep_size:给备库更多的追赶缓冲窗口,适合滞后时间不长的场景; - 使用复制槽:从根本上保证主库不提前回收 WAL,但需配套槽位保留量监控,防止主库磁盘被撑爆;
- 重新执行
pg_basebackup:滞后过大(主库 WAL 已被回收、槽位丢失)时,重建备库通常比尝试追赶更快更可靠。日常运维中应遵循 SKILL.md 的约束——"Ignore replication lag alerts"属于 MUST NOT DO,滞后告警出现后应立即介入处理。
总结
PostgreSQL 的复制体系覆盖了从"数据冗余与读写分离"(物理流复制)到"灵活数据分发与迁移"(逻辑复制)、再到"极端场景保护"(延迟备库)与"自动故障转移"(Patroni / pg_auto_failover)的完整需求光谱。落地时把握三个核心原则:
- 先选型再动手:同版本全量高可用选物理流复制,跨版本/局部同步选逻辑复制,事故防护加一台延迟备库;
- 监控先行:把
pg_stat_replication、pg_replication_slots的滞后与 WAL 保留量监控纳入日常巡检(参考 maintenance.md 的维护清单),复制槽是"最容易埋雷"的隐性风险点; - 复制不等于备份:同步复制 + PgBouncer/HAProxy 提供的是可用性,WAL 归档 +
pg_basebackup+ PITR 才是可恢复性的最终保障,两者缺一不可。
如需进一步了解与复制配套的数据库性能调优、JSONB 使用与日常维护,可继续阅读同技能下的 performance.md、jsonb.md、extensions.md 与 maintenance.md;该技能的使用边界与完整工作流可参见 postgres-pro/SKILL.md。本主题属于仓库基础设施类技能之一,与 database-optimizer、devops-engineer、sre-engineer 等技能配合,可组成完整的数据库高可用工程方案。
【免费下载链接】claude-skills67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.项目地址: https://gitcode.com/GitHub_Trending/claud/claude-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考