分享实战心得PostgreSQL 主从复制:告别单点故障,附主从切换与延迟监控命令

张开发
2026/4/17 1:24:26 15 分钟阅读

分享文章

分享实战心得PostgreSQL 主从复制:告别单点故障,附主从切换与延迟监控命令
一、为什么 PostgreSQL 需要主从复制先从业务价值说起。主从复制至少能解决以下几个问题1. 避免单点故障如果只有一个主库那么数据库就是全系统的核心单点。一旦这台机器宕机整个应用基本瘫痪。部署从库后主库出问题时可以把从库提升为新主库从而恢复服务。2. 提高恢复能力主从复制意味着数据会持续同步到另一台机器。相比只有逻辑备份复制能提供更快的恢复路径尤其适合对 RTO恢复时间目标有要求的系统。3. 支持读写分离虽然本文重点是高可用但从库还可以承担读请求例如报表查询、统计分析、后台管理等从而减轻主库压力。4. 支持备份与运维操作卸载很多备份、校验、只读分析任务都可以放在从库执行减少对主库的干扰。二、PostgreSQL 主从复制的基本原理理解原理后配置过程会清晰很多。PostgreSQL 的主从复制主要依赖WALWrite-Ahead Log预写式日志。主库在处理事务时会先把数据变更写入 WAL从库则通过流复制Streaming Replication接收这些 WAL 记录并在本地回放从而让数据保持一致。整体过程可以概括为主库产生 WALWAL Sender 进程把日志流发送给从库从库 WAL Receiver 接收日志从库回放 WAL更新数据文件从库持续追赶主库保持同步或准同步状态异步复制与同步复制异步复制主库提交事务时不等待从库确认性能更高但主库突然故障时可能丢少量尚未同步的数据。同步复制主库提交事务时要等待从库确认数据安全性更高但写性能会下降。生产中很多团队先用异步复制在更高安全要求场景再评估同步复制。三、实验环境规划为了便于说明假设我们使用两台 Linux 服务器主库192.168.1.10从库192.168.1.11PostgreSQL 版本PostgreSQL 14/15/16 均可本文命令尽量采用通用写法操作系统CentOS / Rocky / Ubuntu 思路一致数据目录假设为/var/lib/pgsql/16/data复制用户设为用户名replicator密码replica123请注意实际生产中密码要更复杂网络策略也应限制来源 IP。四、主库配置步骤第一步安装 PostgreSQL不同发行版安装略有差异这里不展开软件源细节。安装完成后确认服务已启动bashsystemctl status postgresql或版本化服务名bashsystemctl status postgresql-16第二步修改 postgresql.conf找到主库配置文件通常在数据目录中bashvi /var/lib/pgsql/16/data/postgresql.conf重点修改以下参数listen_addresses * wal_level replica max_wal_senders 10 max_replication_slots 10 wal_keep_size 1024MB hot_standby on参数解释listen_addresses*允许远程连接wal_levelreplica开启复制所需的 WAL 级别max_wal_senders10允许多少个 WAL 发送进程max_replication_slots10复制槽数量上限wal_keep_size1024MB保留一定 WAL避免从库短暂中断后缺日志hot_standbyon允许从库以只读方式提供查询主要从库生效第三步配置 pg_hba.conf编辑主库访问控制文件bashvi /var/lib/pgsql/16/data/pg_hba.conf增加如下内容host replication replicator 192.168.1.11/32 md5 host all all 192.168.1.0/24 md5第一行允许从库使用 replicator 用户进行复制连接。第二行是普通客户端访问规则可按需调整。第四步创建复制用户登录 PostgreSQLbashpsql -U postgres执行sqlCREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD replica123;第五步重启主库bashsystemctl restart postgresql-16然后检查是否生效bashpsql -U postgres -c SHOW wal_level; psql -U postgres -c SHOW max_wal_senders;五、从库配置步骤从库的核心思路是先通过主库做一次基准备份然后让从库持续追主。第一步停止从库 PostgreSQL 服务bashsystemctl stop postgresql-16第二步清空旧数据目录如果从库已经初始化过需要先清理旧数据bashrm -rf /var/lib/pgsql/16/data/*请务必确认当前机器是从库避免误删主库数据。第三步使用 pg_basebackup 拉取主库基准备份bashpg_basebackup -h 192.168.1.10 -p 5432 -U replicator \ -D /var/lib/pgsql/16/data -Fp -Xs -P -R输入密码后开始备份。参数说明-h主库地址-U replicator复制用户-D从库数据目录-Fpplain 格式-Xs同时拉取 WAL-P显进度-R自动写入复制配置非常重要执行完成后从库数据目录里会生成必要文件。在较新版本 PostgreSQL 中-R 会生成 standby.signal 并写入 postgresql.auto.conf 中的主库连接信息。第四步检查从库自动生成的连接参数可查看bashcat /var/lib/pgsql/16/data/postgresql.auto.conf通常会看到类似内容primary_conninfo userreplicator passwordreplica123 host192.168.1.10 port5432 sslmodeprefer sslcompression0同时还会有bashls /var/lib/pgsql/16/data/standby.signal只要 standby.signal 存在实例启动后就会以从库身份运行。第五步启动从库bashsystemctl start postgresql-16六、验证主从复制是否成功1. 在主库查看复制连接状态执行bashpsql -U postgres -c SELECT pid, usename, application_name, client_addr, state, sync_state, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;如果能看到从库连接信息说明主库已经在向从库发送 WAL。常见字段说明state通常为 streamingsync_stateasync 表示异步复制sync 表示同步复制client_addr从库 IP2. 在从库判断自己是否为恢复模式执行bashpsql -U postgres -c SELECT pg_is_in_recovery();返回 t 说明当前是从库返回 f 说明当前是主库。3. 在主库建表验证同步主库执行sqlCREATE TABLE repl_test ( id serial primary key, name text, created_at timestamp default now() ); INSERT INTO repl_test(name) VALUES (hello replication);然后在从库查询sqlSELECT * FROM repl_test;若能查到数据说明复制工作正常。七、主从切换实战主库故障后如何提升从库主从复制真正的价值在于故障时能切换。这里先讲最基本的手工切换这是理解高可用的基础。场景主库已经不可用从库需要提升为新主库在从库执行bashpg_ctl promote -D /var/lib/pgsql/16/data如果环境中 pg_ctl 不在 PATH可使用完整路径。也可以在 SQL 中确认状态变化bashpsql -U postgres -c SELECT pg_is_in_recovery();如果返回 f说明从库已经提升为主库。提升后需要做什么应用连接地址切到新主库原主库修复后不能直接重新加入必须重新初始化为从库检查业务写入是否恢复正常八、原主恢复后如何重新加入集群假设原主库修好后要变成新主库的从库通常做法是重新基准备份停止原主库服务清空原主库旧数据目录从当前新主库执行 pg_basebackup 拉取数据以从库身份启动命令思路与前面的从库初始化完全类似只是主从角色已经变化。如果你追求更高级的“时间线追赶”和最小化重建可以进一步研究 pg_rewind但对初学者来说先掌握“重建从库”是最稳妥的实践路径。九、延迟监控命令判断从库是否追上主库主从复制不是“连上就万事大吉”还必须监控延迟。延迟大了会影响读一致性和故障恢复能力。1. 主库查看复制发送状态bashpsql -U postgres -c SELECT application_name, client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn, pg_size_pretty(pg_wal_lsn_diff(sent_lsn, replay_lsn)) AS replay_delay_bytes FROM pg_stat_replication;这个命令可以看到主库发送位置与从库回放位置之间的字节差异。2. 从库查看 WAL 接收与回放情况bashpsql -U postgres -c SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())) AS replay_gap;如果 replay_gap 很大说明从库接收了 WAL但回放速度跟不上。3. 从库查看回放时间延迟bashpsql -U postgres -c SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;这个命令非常常用。如果返回几毫秒、几秒通常可接受如果达到几十秒甚至几分钟就要排查了。注意如果从库暂时没有新事务回放结果可能为 NULL这是正常现象。4. 查看从库接收进程状态bashpsql -U postgres -c SELECT status, receive_start_lsn, receive_start_tli, written_lsn, flushed_lsn, latest_end_lsn, latest_end_time, slot_name, conninfo FROM pg_stat_wal_receiver;这个视图可以帮助你判断从库是否还在正常接收主库 WAL。十、常用主从切换与排障命令汇总为了方便实战这里整理一组高频命令。主库查看复制状态bashpsql -U postgres -c SELECT * FROM pg_stat_replication;从库判断角色bashpsql -U postgres -c SELECT pg_is_in_recovery();从库查看回放延迟bashpsql -U postgres -c SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;从库查看 WAL 接收器状态bashpsql -U postgres -c SELECT * FROM pg_stat_wal_receiver;提升从库为主库bashpg_ctl promote -D /var/lib/pgsql/16/data重新基准备份构建从库bashpg_basebackup -h 192.168.1.10 -p 5432 -U replicator -D /var/lib/pgsql/16/data -Fp -Xs -P -R查看当前 WAL 位置主库bashpsql -U postgres -c SELECT pg_current_wal_lsn();从库bashpsql -U postgres -c SELECT pg_last_wal_replay_lsn();十一、生产环境中的几个关键建议1. 复制槽建议合理使用可通过物理复制槽避免从库断开期间主库过早删除 WAL主库创建复制槽sqlSELECT * FROM pg_create_physical_replication_slot(standby1_slot);然后在从库 primary_conninfo 配套使用 primary_slot_name。但要注意如果从库长期离线复制槽会导致主库 WAL 积压占满磁盘所以监控必须跟上。2. WAL 保留与磁盘监控必不可少主从复制最怕的不是一时延迟而是从库追不上主库又把旧 WAL 删掉导致必须全量重建。因此监控 WAL 目录增长监控复制延迟合理配置 wal_keep_size对复制槽积压设置告警3. 切换必须演练很多团队配置了主从却从未做过切换演练。真正故障时才发现应用连接没切、连接池缓存旧地址、只读节点误接写流量。建议定期在测试或预发环境进行手工切换演练。4. 高可用不等于自动切换主从复制本身只解决“数据同步”并不自动完成故障检测和 VIP/路由漂移。如果想实现真正自动化高可用还需要结合PatronirepmgrPacemakerkeepalived或云厂商提供的高可用组件本文重点是打牢主从复制基础理解这些后再看自动化方案会更轻松。十二、结语PostgreSQL 主从复制是数据库高可用体系里最值得优先掌握的一项能力。它不仅能帮助你摆脱单点故障还能为读写分离、备份卸载、容灾恢复、运维演练打下基础。从技术实现上看它并不神秘核心就是主库输出 WAL从库持续接收并回放。真正决定成败的不只是“能配起来”而是是否做好了完整闭环——配置正确、验证有效、延迟可监控、切换可执行、故障后可恢复。如果你只是刚开始接触 PostgreSQL建议你先亲手完成一遍本文中的实验搭一个主库、搭一个从库、插入一条数据、看它同步、再手工 promote 一次。只要这个流程真正跑通你对 PostgreSQL 高可用的理解就会立刻从“概念”进入“实战”。

更多文章