外观
PostgreSQL 复制延迟
复制延迟监控
1. 物理复制延迟监控
sql
-- 在主库上查看复制状态
SELECT
usename,
application_name,
client_addr,
state,
sync_state,
write_lag,
flush_lag,
replay_lag,
write_location,
flush_location,
replay_location
FROM
pg_stat_replication;
-- 在从库上查看复制延迟
SELECT
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_delay_bytes,
pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn) AS write_delay_bytes,
pg_wal_lsn_diff(pg_current_wal_lsn(), flush_lsn) AS flush_delay_bytes,
replay_lag,
write_lag,
flush_lag
FROM
pg_stat_wal_receiver;
-- 查看从库的恢复状态
SELECT
status,
last_replay_location,
last_replay_time,
replay_lag
FROM
pg_stat_wal_receiver;2. 逻辑复制延迟监控
sql
-- 查看逻辑复制订阅状态
SELECT
subname,
subenabled,
subconninfo,
subslotname,
subsynccommit
FROM
pg_subscription;
-- 查看逻辑复制槽状态
SELECT
slot_name,
plugin,
slot_type,
active,
restart_lsn,
confirmed_flush_lsn,
pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn) AS lag_bytes
FROM
pg_replication_slots
WHERE
slot_type = 'logical';
-- 查看逻辑复制应用状态
SELECT
application_name,
state,
sync_state,
write_lag,
flush_lag,
replay_lag
FROM
pg_stat_replication
WHERE
application_name LIKE 'pg_%';3. 使用 Prometheus 监控
yaml
# 复制延迟告警规则
- alert: PostgreSQLReplicationLag
expr: pg_stat_replication_replay_lag > 60
for: 5m
labels:
severity: warning
annotations:
summary: "PostgreSQL 复制延迟过高"
description: "从库 {{ $labels.instance }} 复制延迟超过 60 秒,当前值: {{ $value }} 秒"
- alert: PostgreSQLLogicalReplicationLag
expr: pg_replication_slots_confirmed_flush_lsn > 0 and pg_wal_lsn_diff(pg_current_wal_lsn(), pg_replication_slots_confirmed_flush_lsn) / 1024 / 1024 > 100
for: 5m
labels:
severity: warning
annotations:
summary: "PostgreSQL 逻辑复制延迟过高"
description: "逻辑复制槽 {{ $labels.slot_name }} 延迟超过 100MB,当前值: {{ $value }} MB"复制延迟诊断
1. 识别复制延迟原因
sql
-- 检查主库 WAL 生成速率
SELECT
pg_wal_lsn_diff(pg_current_wal_lsn(), pg_stat_file('pg_wal/000000010000000000000001')) AS wal_generated,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), pg_stat_file('pg_wal/000000010000000000000001'))) AS wal_size;
-- 检查从库网络连接
SELECT
client_addr,
state,
sync_state,
write_lag,
flush_lag,
replay_lag
FROM
pg_stat_replication;
-- 检查从库资源使用情况
-- 在从库上执行
SELECT
usename,
datname,
application_name,
state,
query,
now() - query_start AS duration
FROM
pg_stat_activity
WHERE
state != 'idle'
ORDER BY
duration DESC;2. 分析复制延迟类型
- 写入延迟(write_lag):主库到从库的网络延迟
- 刷新延迟(flush_lag):WAL 写入从库磁盘的延迟
- 回放延迟(replay_lag):从库应用 WAL 日志的延迟
复制延迟处理
1. 网络相关优化
sql
-- 调整 WAL 发送缓冲区大小
ALTER SYSTEM SET wal_sender_buffer_size = '16MB';
-- 调整从库接收缓冲区大小
ALTER SYSTEM SET wal_receiver_buffer_size = '16MB';
-- 启用 WAL 压缩
ALTER SYSTEM SET wal_compression = 'on';
-- 重新加载配置
SELECT pg_reload_conf();2. WAL 相关优化
sql
-- 调整 WAL 日志大小
ALTER SYSTEM SET wal_segment_size = '64MB';
-- 调整检查点参数
ALTER SYSTEM SET checkpoint_completion_target = '0.9';
ALTER SYSTEM SET max_wal_size = '2GB';
-- 启用并行 WAL 回放(PostgreSQL 14+)
ALTER SYSTEM SET wal_receiver_create_temp_slot = 'on';
ALTER SYSTEM SET max_worker_processes = '16';
ALTER SYSTEM SET max_parallel_workers = '12';
-- 重新加载配置
SELECT pg_reload_conf();3. 从库性能优化
sql
-- 调整从库共享缓冲区
ALTER SYSTEM SET shared_buffers = '8GB';
-- 调整从库维护工作内存
ALTER SYSTEM SET maintenance_work_mem = '2GB';
-- 调整从库检查点参数
ALTER SYSTEM SET checkpoint_completion_target = '0.9';
-- 启用从库热备反馈
ALTER SYSTEM SET hot_standby_feedback = 'on';
-- 重新加载配置
SELECT pg_reload_conf();4. 同步复制调整
sql
-- 查看当前同步复制配置
SHOW synchronous_commit;
SHOW synchronous_standby_names;
-- 调整同步复制模式
-- 选项:off, local, remote_write, remote_apply, on
ALTER SYSTEM SET synchronous_commit = 'remote_write';
-- 调整同步备库数量
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (standby1, standby2)';
-- 重新加载配置
SELECT pg_reload_conf();复制延迟恢复
1. 重建从库
bash
# 在从库上停止 PostgreSQL
systemctl stop postgresql-15
# 清理从库数据目录
rm -rf /var/lib/postgresql/15/main/*
# 使用 pg_basebackup 重新构建从库
pg_basebackup -h primary_host -U replication_user -D /var/lib/postgresql/15/main -F p -X stream -R -P
# 启动从库
systemctl start postgresql-152. 修复逻辑复制延迟
sql
-- 检查逻辑复制订阅状态
SELECT
subname,
subenabled,
subconninfo,
subslotname
FROM
pg_subscription;
-- 重启逻辑复制订阅
ALTER SUBSCRIPTION my_subscription DISABLE;
ALTER SUBSCRIPTION my_subscription ENABLE;
-- 重新同步逻辑复制数据
ALTER SUBSCRIPTION my_subscription REFRESH PUBLICATION;
-- 检查逻辑复制槽状态
SELECT
slot_name,
plugin,
slot_type,
active,
restart_lsn,
confirmed_flush_lsn
FROM
pg_replication_slots
WHERE
slot_type = 'logical';最佳实践
1. 监控与告警
- 设置合理的告警阈值:根据业务需求设置复制延迟告警阈值
- 多维度监控:同时监控 write_lag、flush_lag 和 replay_lag
- 监控 WAL 生成速率:了解主库 WAL 生成情况
- 监控从库资源:监控从库 CPU、内存和磁盘 IO
2. 配置优化
- 合理设置同步复制级别:根据业务可用性要求选择同步级别
- 优化 WAL 参数:调整 WAL 大小、检查点参数
- 优化从库性能:确保从库硬件配置足够
- 启用并行 WAL 回放:对于高并发场景,启用并行回放
3. 定期维护
- 定期检查复制状态:每周至少检查一次复制状态
- 定期重建从库:对于长期运行的从库,定期重建以避免累积延迟
- 测试故障切换:定期测试主从切换,确保复制正常
- 监控复制槽:定期清理不再使用的复制槽
常见问题(FAQ)
Q1:如何快速判断复制延迟的原因?
A1:可以通过以下步骤判断:
- 查看
pg_stat_replication中的write_lag、flush_lag和replay_lag - 如果
write_lag大,说明网络延迟高 - 如果
flush_lag大,说明从库磁盘 IO 慢 - 如果
replay_lag大,说明从库应用 WAL 慢 - 检查从库的 CPU、内存和磁盘 IO 情况
Q2:复制延迟会导致数据丢失吗?
A2:这取决于复制模式:
- 异步复制:可能会导致数据丢失,因为主库提交后不等从库确认
- 同步复制:不会丢失数据,主库会等待从库确认后再提交
- 半同步复制:只等待一个从库确认,提供一定的数据安全性
Q3:如何降低复制延迟?
A3:降低复制延迟的方法:
- 优化网络连接,减少网络延迟
- 优化主库 WAL 生成,调整检查点参数
- 优化从库性能,确保硬件配置足够
- 启用并行 WAL 回放
- 合理设置同步复制级别
Q4:从库复制延迟越来越大怎么办?
A4:处理方法:
- 检查主库 WAL 生成速率是否过高
- 检查从库资源使用情况
- 检查网络连接是否稳定
- 考虑重建从库
- 调整复制配置,如降低同步级别
Q5:逻辑复制延迟与物理复制延迟有什么区别?
A5:主要区别:
- 物理复制:基于 WAL 日志,延迟通常较低
- 逻辑复制:基于逻辑变更,需要解析和应用变更,延迟通常较高
- 物理复制:适用于高可用性场景
- 逻辑复制:适用于数据同步和迁移场景
Q6:如何监控多个从库的复制延迟?
A6:监控多个从库的方法:
- 使用 Prometheus + Grafana 集中监控
- 创建监控脚本,定期检查所有从库
- 使用 PostgreSQL 监控工具,如 pgAdmin、pgBadger
- 配置统一的告警机制,确保及时收到通知
