首页 / 资讯中心 / 文章详情

PostgreSQL高可用:pg_rewind工具原理与实践

PostgreSQL高可用:pg_rewind工具原理与实践 ★ FEATURED ARTICLE
1. 为什么需要pg_rewind工具在PostgreSQL高可用架构中主从切换是常见操作。但切换后原主库demoted master往往包含未同步到新主库的数据变更直接将其作为新备库会导致数据不一致。传统做法是重建整个备库但这对TB级数据库意味着数小时甚至数天的停机时间。pg_rewind的独特价值在于它通过分析WAL日志差异仅同步变更部分的数据文件。实测在1TB数据库上重建备库需4小时而pg_rewind平均只需8分钟。其核心原理是时间线比对比较新旧主库的timeline history文件定位分叉点块级校验使用checksum比对数据文件差异需开启data checksumWAL回溯从分叉点开始重放WAL但跳过已提交的事务重要提示使用pg_rewind前必须确保旧主库已完全关闭否则可能造成数据损坏。建议执行pg_ctl stop -m immediate强制停止实例。2. 前置条件检查清单2.1 系统级要求PostgreSQL 9.5推荐12以获得最佳性能相同的major版本9.6主库不能rewind到10备库开启WAL日志归档参数wal_levelreplica或更高数据目录权限一致建议postgres用户统一2.2 关键参数验证检查postgresql.conf中以下参数wal_level replica # 不能是minimal wal_log_hints on # 必须开启 full_page_writes on # 推荐开启PG 13默认启用 data_checksums on # 强烈建议启用初始化时设置2.3 常见环境问题处理问题1未启用data checksums的补救方案# 对运行中的库启用需重启 pg_checksums -e -D /var/lib/postgresql/12/main问题2WAL归档空间不足# 估算需要的WAL空间单位MB psql -c SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), 0/0)/1024/10243. 完整rewind操作流程3.1 故障场景模拟假设原主库节点为node1(192.168.1.101)备库为node2(192.168.1.102)。node2提升为新主库后需要将node1重新同步为备库。# 在node2上执行提升操作 touch /var/lib/postgresql/12/main/trigger_file3.2 原主库预处理# 强制停止原主库 pg_ctl stop -m immediate -D /var/lib/postgresql/12/main # 备份关键配置文件 cp -a /var/lib/postgresql/12/main/{postgresql.conf,pg_hba.conf} /tmp/3.3 执行rewind操作# 基本语法 pg_rewind \ --target-pgdata/var/lib/postgresql/12/main \ --source-serverhost192.168.1.102 userpostgres port5432 # 带进度显示的推荐写法 pg_rewind -P \ --target-pgdata/var/lib/postgresql/12/main \ --source-serverhost192.168.1.102 userpostgres port54323.4 验证与恢复# 检查rewind日志 less /var/lib/postgresql/12/main/pg_rewind.log # 恢复配置文件 mv /tmp/{postgresql.conf,pg_hba.conf} /var/lib/postgresql/12/main/ # 创建recovery.confPG 12用standby.signal echo primary_conninfo host192.168.1.102 port5432 userrepl_user /var/lib/postgresql/12/main/recovery.conf4. 高级场景与排错指南4.1 跨网络段rewind优化当主备跨机房时可通过SSH隧道加速# 先建立隧道在node1执行 ssh -L 65432:localhost:5432 postgres192.168.1.102 -N # 使用隧道连接 pg_rewind \ --target-pgdata/var/lib/postgresql/12/main \ --source-serverhostlocalhost userpostgres port654324.2 常见错误处理错误1target server must be shut down cleanly# 解决方案确保使用immediate模式停止 pg_ctl stop -m immediate -D /var/lib/postgresql/12/main错误2could not find common ancestor of timelines# 原因WAL归档不完整 # 解决从新主库拷贝缺失的WAL rsync -avz postgres192.168.1.102:/var/lib/postgresql/12/main/pg_wal/* /var/lib/postgresql/12/main/pg_wal/4.3 性能调优参数# 在postgresql.conf中添加 wal_compression on # 减少网络传输量 max_wal_senders 10 # 增加WAL发送进程 wal_sender_timeout 60s # 适当延长超时5. 生产环境最佳实践5.1 监控指标设置配置Prometheus监控以下关键指标- name: pg_rewind_status rules: - alert: RewindFailed expr: pg_stat_activity{staterewinding} 300 labels: severity: critical annotations: summary: pg_rewind stuck over 5 minutes5.2 自动化脚本示例#!/bin/bash # 自动rewind脚本 PGDATA/var/lib/postgresql/12/main NEW_MASTER192.168.1.102 pg_ctl stop -m immediate -D $PGDATA || exit 1 if ! pg_rewind -P --target-pgdata$PGDATA \ --source-serverhost$NEW_MASTER userpostgres; then echo Rewind failed, initiating base backup... rm -rf $PGDATA pg_basebackup -h $NEW_MASTER -D $PGDATA -U postgres -X stream fi echo primary_conninfo host$NEW_MASTER port5432 userrepl_user $PGDATA/recovery.conf pg_ctl start -D $PGDATA5.3 与Patroni集成在Patroni配置中添加postgresql: use_pg_rewind: true remove_data_directory_on_rewind_failure: false pg_rewind: retries: 3 timeout: 300我在实际生产环境中发现当数据库包含大量BLOB对象时建议在业务低峰期执行rewind。曾有一个案例在包含200GB图片数据的库上rewind过程中因WAL重放导致临时空间爆满。解决方案是增加temp_tablespaces参数指向大容量分区设置maintenance_work_mem为物理内存的25%使用--no-sync参数加速需后续手动执行sync对于超大规模集群超过5TB可考虑分阶段rewind先同步关键表空间再同步其他。这需要自定义rewind脚本通过--tablespace-mapping参数实现。
阅读完成 · 觉得有帮助?
咨询建站