【PostgreSQL从零到精通】第42篇:同步流复制与复制监控——确保数据零丢失
上一篇【第41篇】实战搭建流复制主备环境——从零到高可用下一篇明日更新敬请期待异步复制可能在主库崩溃时丢失最后几秒的数据。对于金融、交易等场景这是不可接受的。同步流复制确保主库的每次 COMMIT 都在备库确认后才返回成功实现真正的数据零丢失。本文详解同步复制的配置与监控。一、同步复制架构1.1 工作流程同步复制流程与异步复制对比 异步复制 客户端 → COMMIT → 主库写入WAL → 立即返回成功 → 异步发送给备库 ↑ 不等备库 同步复制 客户端 → COMMIT → 主库写入WAL → 发送给备库 → 等待备库确认 → 返回成功 ↑ 必须等 多种同步级别 ┌──────────────────┬────────────────────────────────────────────┐ │ synchronous_ │ 含义 │ │ commit │ │ ├──────────────────┼────────────────────────────────────────────┤ │ on │ 等待备库 flush写入磁盘后返回 │ ├──────────────────┼────────────────────────────────────────────┤ │ remote_apply │ 等待备库 apply应用WAL后返回 │ │ │ → 最严格延迟最大 │ ├──────────────────┼────────────────────────────────────────────┤ │ remote_flush │ 等待备库写入操作系统缓存 │ │ │ 通常与 on 等价 │ ├──────────────────┼────────────────────────────────────────────┤ │ remote_write │ 等待备库接收到WAL不要求写入磁盘 │ │ │ → 延迟较小安全性略低 │ ├──────────────────┼────────────────────────────────────────────┤ │ local │ 只等待本地WAL写入不等备库 │ │ │ → 等同于关闭同步复制 │ └──────────────────┴────────────────────────────────────────────┘1.2 多备库的同步策略-- synchronous_standby_names 的三种格式-- 1. 指定一个备库名称synchronous_standby_namesstandby1-- 只有 standby1 健康时主库才能正常 COMMIT-- 2. FIRST N (standby_name, ...)synchronous_standby_namesFIRST 1 (standby1, standby2)-- standby1 或 standby2 任一确认即可1-of-2-- 3. ANY N (standby_name, ...)synchronous_standby_namesANY 2 (standby1, standby2, standby3)-- 任意 2 个备库确认即可2-of-3二、配置同步复制2.1 主库配置-- 主库 postgresql.confALTERSYSTEMSETsynchronous_commiton;ALTERSYSTEMSETsynchronous_standby_namesstandby1;SELECTpg_reload_conf();2.2 备库配置 application_name# 备库的 postgresql.auto.conf 中设置 application_name# primary_conninfo userrepl_user passwordxxx host192.168.1.10 port5432 application_namestandby1# 或者在主库查看备库的 application_nameSELECT application_name, state, sync_state FROM pg_stat_replication;2.3 验证同步状态-- sync_state 字段说明-- sync → 同步复制中正常-- async → 异步复制中-- quorum → Quorum 同步-- potential → 备库已连接但尚未成为同步备库SELECTapplication_name,client_addr,state,sync_state,sent_lsn,replay_lsn,write_lag,flush_lag,replay_lagFROMpg_stat_replication;-- 如果看到 sync_statesync → 同步复制正常运行三、复制延迟监控3.1 pg_stat_replication 详细视图-- 完整的复制监控查询SELECTapplication_name,client_addr,state,sync_state,sent_lsn::textASsent,write_lsn::textASwritten,flush_lsn::textASflushed,replay_lsn::textASreplayed,write_lag,-- 写入延迟flush_lag,-- 刷盘延迟reply_lag-- 回复延迟FROMpg_stat_replication;-- 注意write_lag/flush_lag/replay_lag 需要 hot_standby_feedback on 才能准确3.2 备库监控-- 在备库上执行-- 查看备库状态SELECTpg_is_in_recovery();-- true 备库-- 查看备库接收到的最新 WAL 位置SELECTpg_last_wal_receive_lsn()ASreceived_lsn,pg_last_wal_replay_lsn()ASreplayed_lsn,pg_last_xact_replay_timestamp()ASlast_replayed_transaction;-- 计算延迟SELECTpg_wal_lsn_diff(pg_last_wal_receive_lsn(),pg_last_wal_replay_lsn())/1024.0/1024.0ASreplay_lag_mb,EXTRACT(EPOCHFROMnow()-pg_last_xact_replay_timestamp())ASreplay_lag_seconds;3.3 复制冲突处理Hot Standby 复制冲突 ┌─────────────────────────────────────────────────────────────┐ │ 备库上的查询可能与主库传来的 WAL 恢复操作产生冲突 │ │ │ │ 1. VACUUM 冲突主库 VACUUM 要清理的页备库正在读 │ │ 2. DROP TABLE 冲突主库 DROP 了表备库正在查 │ │ 3. 锁冲突主库获取了排他锁备库查询需要共享锁 │ │ 4. 死事务冲突主库清理死事务备库查询依赖快照 │ └─────────────────────────────────────────────────────────────┘-- 查看复制冲突统计SELECTdatname,conflicts,deadlocksFROMpg_stat_database_conflicts;-- 查看备库是否因冲突而取消查询-- 查看备库日志-- ERROR: canceling statement due to conflict with recovery-- 解决复制冲突的配置-- postgresql.conf备库上ALTERSYSTEMSETmax_standby_streaming_delay30s;-- 等待 30 秒后取消ALTERSYSTEMSETmax_standby_archive_delay30s;-- 归档恢复也等 30 秒ALTERSYSTEMSEThot_standby_feedbackon;-- 反馈查询信息给主库-- wal_receiver_status_interval 10s; -- 更频繁的状态更新SELECTpg_reload_conf();四、复制监控 Dashboard4.1 一键监控脚本-- 复制健康状态综合报告WITHrepl_infoAS(SELECTapplication_name,client_addr::textASclient_ip,state,sync_state,COALESCE(EXTRACT(EPOCHFROMwrite_lag),EXTRACT(EPOCHFROMnow()-(SELECTlast_msg_send_timeFROMpg_stat_wal_receiver)))ASlag_seconds,pg_wal_lsn_diff(sent_lsn,replay_lsn)ASlag_bytesFROMpg_stat_replication)SELECTapplication_nameASstandby,client_ip,state,sync_state,CASEWHENlag_seconds1THENOKWHENlag_seconds10THENWARNINGELSECRITICALENDAShealth,round(lag_seconds::numeric,2)ASlag_sec,pg_size_pretty(lag_bytes)ASlag_sizeFROMrepl_info;五、总结同步复制配置要点synchronous_commit on等待备库确认后才 COMMITsynchronous_standby_names指定同步备库名称监控pg_stat_replication 的 sync_state 字段冲突处理hot_standby_feedback max_standby_streaming_delay同步复制适合金融、交易等数据零丢失要求的场景。如果备库不可用主库会等待性能下降所以需要至少 2 个备库实现 1-of-2 高可用。下一篇我们学习恢复配置与流复制高级调优。标签PostgreSQL、同步复制、流复制监控、复制延迟、Hot Standby上一篇【第41篇】实战搭建流复制主备环境——从零到高可用下一篇明日更新敬请期待