外观
PostgreSQL 同步复制与异步复制
核心概念
1. 异步复制
异步复制是PostgreSQL默认的复制模式,主库在将WAL日志写入本地磁盘后立即向客户端返回成功,不需要等待从库确认接收或应用WAL日志。
异步复制的特点:
- 主库性能高,写入延迟低
- 存在数据丢失风险:如果主库崩溃,尚未同步到从库的WAL日志会丢失
- 从库可能存在复制延迟
- 配置简单,无需额外设置
2. 同步复制
同步复制要求主库在将WAL日志写入本地磁盘后,必须等待至少一个从库确认已接收并写入磁盘,才向客户端返回成功。
同步复制的特点:
- 数据安全性高,无数据丢失风险
- 主库写入延迟增加,性能可能下降
- 从库复制延迟极小
- 需要额外配置,指定同步从库
3. 关键区别
| 特性 | 异步复制 | 同步复制 |
|---|---|---|
| 数据安全性 | 较低(可能丢失数据) | 极高(无数据丢失) |
| 主库性能 | 高(写入延迟低) | 较低(写入延迟高) |
| 从库一致性 | 最终一致 | 强一致 |
| 配置复杂度 | 简单 | 复杂 |
| 适用场景 | 对性能要求高,可接受少量数据丢失 | 对数据安全性要求极高,可接受一定性能损失 |
异步复制配置
1. 基础配置
异步复制是PostgreSQL的默认复制模式,无需特殊配置,只需按照物理复制的基础配置即可实现。
bash
# 主库配置文件postgresql.conf中的默认设置
# 无需额外配置,异步复制默认启用2. 验证异步复制状态
sql
-- 在主库上查看复制状态
SELECT
application_name,
state,
sync_state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn
FROM pg_stat_replication;
-- sync_state字段为async表示异步复制同步复制配置
1. 配置步骤
1.1 主库配置
bash
# 修改主库postgresql.conf
cat >> /var/lib/postgresql/15/main/postgresql.conf << EOF
# 启用同步复制
# 设置同步从库名称,可以是具体的从库名称或表达式
# FIRST 1表示至少1个从库确认,ANY 2表示任意2个从库确认
synchronous_standby_names = 'FIRST 1 ("standby1", "standby2")'
EOF
# 重启主库使配置生效
pg_ctl restart -D /var/lib/postgresql/15/main1.2 从库配置
bash
# 在recovery.signal或postgresql.auto.conf中设置从库应用名称
# 确保应用名称与主库的synchronous_standby_names配置匹配
cat >> /var/lib/postgresql/15/main/postgresql.auto.conf << EOF
# 设置从库应用名称
primary_conninfo = 'host=主库IP port=5432 user=replication_user password=replication_pass application_name=standby1'
EOF
# 重启从库使配置生效
pg_ctl restart -D /var/lib/postgresql/15/main2. 验证同步复制状态
sql
-- 在主库上查看复制状态
SELECT
application_name,
state,
sync_state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn
FROM pg_stat_replication;
-- sync_state字段为sync表示同步复制
-- sync_priority字段显示同步优先级
-- sync_state为potential表示备选同步从库高级配置选项
1. 同步复制模式
PostgreSQL支持多种同步复制模式,通过synchronous_standby_names参数配置:
sql
-- 模式1:指定具体从库,至少1个确认
ALTER SYSTEM SET synchronous_standby_names = '"standby1", "standby2"';
-- 模式2:FIRST N表示前N个从库确认
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 2 ("standby1", "standby2", "standby3")';
-- 模式3:ANY N表示任意N个从库确认
ALTER SYSTEM SET synchronous_standby_names = 'ANY 2 ("standby1", "standby2", "standby3")';
-- 模式4:使用通配符匹配从库名称
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 ("standby*")';
-- 应用配置
SELECT pg_reload_conf();2. 同步提交级别
sql
-- 设置同步提交级别
-- on:完全同步,等待WAL写入从库磁盘
-- remote_write:等待WAL写入从库操作系统缓冲区
-- off:异步复制
ALTER SYSTEM SET synchronous_commit = 'on';
-- 应用配置
SELECT pg_reload_conf();性能优化
1. 异步复制优化
bash
# 主库配置优化
cat >> /var/lib/postgresql/15/main/postgresql.conf << EOF
# 异步复制性能优化
wal_compression = on
checkpoint_timeout = 30min
max_wal_size = 4GB
checkpoint_completion_target = 0.9
EOF
# 从库配置优化
cat >> /var/lib/postgresql/15/main/postgresql.conf << EOF
# 异步复制从库优化
hot_standby = on
hot_standby_feedback = on
max_standby_streaming_delay = 30s
EOF2. 同步复制优化
bash
# 同步复制性能优化
cat >> /var/lib/postgresql/15/main/postgresql.conf << EOF
# 减少同步复制延迟
wal_writer_delay = 20ms
commit_delay = 10
commit_siblings = 5
# 优化WAL发送
max_wal_senders = 10
wal_keep_size = 2GB
EOF3. 网络优化
- 使用专用网络连接主从库
- 增加网络带宽
- 优化网络路由,减少网络延迟
- 考虑使用压缩传输(适用于远距离复制)
监控与管理
1. 复制状态监控
sql
-- 监控复制状态
SELECT
application_name,
state,
sync_state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn,
(sent_lsn - replay_lsn) AS replay_lag
FROM pg_stat_replication;
-- 监控同步复制等待时间
SELECT
pid,
state,
wait_event,
wait_event_type,
query
FROM pg_stat_activity
WHERE wait_event_type = 'Replication';2. 复制延迟监控
sql
-- 在从库上查看复制延迟
SELECT
now() - pg_last_xact_replay_timestamp() AS replication_delay;
-- 监控WAL生成和应用速率
SELECT
pg_current_wal_lsn(),
pg_last_wal_receive_lsn(),
pg_last_wal_replay_lsn();3. 同步复制故障处理
3.1 同步从库不可用
sql
-- 当同步从库不可用时,主库会等待超时
-- 可以临时切换到异步复制模式
ALTER SYSTEM SET synchronous_standby_names = '';
SELECT pg_reload_conf();
-- 当从库恢复后,重新启用同步复制
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 ("standby1", "standby2")';
SELECT pg_reload_conf();3.2 同步复制延迟过高
bash
# 1. 检查网络状态
ping 主库IP
netstat -s
# 2. 检查从库负载
top
psql -h 从库IP -U postgres -c "SELECT * FROM pg_stat_activity;"
# 3. 优化从库配置
# 增加从库的CPU和内存资源
# 优化从库的WAL应用配置最佳实践
1. 复制模式选择建议
| 业务场景 | 推荐复制模式 | 配置建议 |
|---|---|---|
| 电商交易系统 | 同步复制 | FIRST 1 ("standby1", "standby2") |
| 内容管理系统 | 异步复制 | 默认配置 |
| 金融核心系统 | 同步复制 | ANY 2 ("standby1", "standby2", "standby3") |
| 日志分析系统 | 异步复制 | 默认配置,增加wal_keep_size |
| 混合业务系统 | 半同步复制(后续文档介绍) | - |
2. 配置最佳实践
- 使用多个从库:配置2-3个从库,提高系统可用性
- 合理设置同步条件:根据业务需求选择FIRST或ANY模式,以及合适的从库数量
- 配置复制槽:防止WAL日志丢失,尤其是异步复制
- 监控复制状态:定期检查复制状态和延迟,设置告警阈值
- 测试故障切换:定期测试故障切换流程,确保在主库故障时能够快速恢复
3. 运维最佳实践
- 文档化配置:详细记录复制配置和管理流程
- 定期备份:无论使用哪种复制模式,都要定期进行数据库备份
- 培训团队:确保运维团队熟悉复制管理和故障处理
- 版本兼容性:确保主从库版本一致,或在支持的版本范围内
常见问题(FAQ)
Q1:同步复制和异步复制如何选择?
A1:选择复制模式主要取决于业务对数据安全性和性能的要求:
- 如果业务对数据安全性要求极高(如金融、交易系统),应选择同步复制
- 如果业务对性能要求较高,可接受少量数据丢失(如内容管理、日志系统),应选择异步复制
- 对于混合业务场景,可以考虑使用半同步复制(后续文档介绍)
Q2:同步复制会影响主库性能吗?
A2:是的,同步复制会增加主库的写入延迟,主要影响因素包括:
- 网络延迟:主从库之间的网络延迟越大,同步复制的性能影响越大
- 从库数量:配置的同步从库数量越多,主库等待时间越长
- 从库性能:从库的WAL接收和应用性能会影响主库等待时间
Q3:如何降低同步复制对主库性能的影响?
A3:可以采取以下措施降低同步复制的性能影响:
- 使用高性能网络连接主从库
- 优化从库配置,提高WAL接收和应用速度
- 合理设置同步条件,减少同步从库数量
- 考虑使用remote_write同步级别,而非完全同步
- 对非关键业务表使用异步复制,关键业务表使用同步复制(通过逻辑复制实现)
Q4:异步复制的数据丢失风险有多大?
A4:异步复制的数据丢失风险取决于:
- 主库的WAL生成速率
- 从库的复制延迟
- 主库的故障类型(如突然断电、硬件故障)
通过配置合适的wal_keep_size和使用复制槽,可以降低数据丢失风险,但无法完全消除。
Q5:如何在同步复制和异步复制之间切换?
A5:可以通过修改主库的synchronous_standby_names参数在两种模式之间切换:
sql
-- 切换到异步复制
ALTER SYSTEM SET synchronous_standby_names = '';
SELECT pg_reload_conf();
-- 切换到同步复制
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 ("standby1", "standby2")';
SELECT pg_reload_conf();Q6:同步复制中的从库优先级如何设置?
A6:同步从库的优先级由synchronous_standby_names参数中从库的顺序决定,排在前面的从库优先被选为同步从库。
sql
-- standby1优先级高于standby2
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 ("standby1", "standby2")';
SELECT pg_reload_conf();Q7:如何监控同步复制的性能?
A7:可以通过以下方式监控同步复制的性能:
sql
-- 监控主库写入等待时间
SELECT
pid,
state,
wait_event,
wait_event_type,
query,
now() - query_start AS query_duration
FROM pg_stat_activity
WHERE wait_event_type = 'Replication';
-- 监控复制延迟
SELECT
application_name,
sync_state,
(sent_lsn - replay_lsn) AS replay_lag
FROM pg_stat_replication;Q8:同步复制是否支持多个从库?
A8:是的,同步复制支持配置多个从库,可以通过synchronous_standby_names参数指定:
sql
-- 等待任意2个从库确认
ALTER SYSTEM SET synchronous_standby_names = 'ANY 2 ("standby1", "standby2", "standby3")';
-- 等待前2个从库确认
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 2 ("standby1", "standby2", "standby3")';同步复制与异步复制的应用场景
1. 异步复制应用场景
- 内容管理系统(CMS)
- 日志分析系统
- 数据仓库系统
- 开发测试环境
- 对性能要求高,可接受少量数据丢失的业务
2. 同步复制应用场景
- 金融交易系统
- 电子商务系统
- 医疗数据系统
- 政府政务系统
- 对数据安全性要求极高,可接受一定性能损失的业务
通过合理选择和配置同步复制与异步复制,可以在数据安全性和性能之间取得平衡,满足不同业务场景的需求。
