1. 理解pg_rewind的核心价值
当PostgreSQL主库突然宕机且备库已经接替成为新主库后,传统做法是重建整个备库——这个过程可能耗费数小时甚至数天。pg_rewind的出现彻底改变了这种局面,它能够像时光机一样,将旧主库"回退"到与新主库一致的状态,通常只需几分钟。
这个工具的核心原理是通过对比两个节点的WAL(预写式日志)差异,仅同步变更过的数据块。与rsync等全量同步工具不同,pg_rewind能智能识别哪些数据块在分歧后被修改过。在PostgreSQL 12中,这项功能得到显著增强,新增了对--write-recovery-conf参数的支持,使故障切换后的配置更加自动化。
2. 环境准备与前置条件
2.1 版本兼容性检查
pg_rewind要求主备库必须运行相同主版本的PostgreSQL(如都是12.x)。通过以下命令验证:
pg_rewind --version psql -c "SELECT version();"2.2 关键参数配置
在postgresql.conf中必须启用以下参数:
wal_level = replica # 必须≥replica full_page_writes = on # 崩溃恢复必需 track_commit_timestamp = on # PG 12新增支持注意:修改配置后需要重启实例生效。生产环境建议提前规划维护窗口。
2.3 数据目录权限设置
确保运行pg_rewind的操作系统用户对数据目录有写权限:
chmod 700 /var/lib/postgresql/12/main chown -R postgres:postgres /var/lib/postgresql3. 实战演练:主备切换与重同步
3.1 模拟主库故障场景
- 在主库创建测试数据:
CREATE TABLE test_rewind AS SELECT generate_series(1,1000000) AS id;- 强制停止主库模拟崩溃:
pg_ctl -D /var/lib/postgresql/12/main stop -m immediate- 提升备库为新主库:
SELECT pg_promote();3.2 执行pg_rewind操作
在原主库服务器执行:
pg_rewind \ --target-pgdata=/var/lib/postgresql/12/main \ --source-server="host=new_primary dbname=postgres user=postgres" \ --write-recovery-conf关键参数解析:
--target-pgdata:待修复的旧主库数据目录--source-server:新主库连接字符串--write-recovery-conf:自动生成recovery.conf(PG 12新特性)
3.3 验证与恢复服务
- 检查rewind日志:
cat /var/lib/postgresql/12/main/pg_rewind.log- 启动修复后的实例:
pg_ctl -D /var/lib/postgresql/12/main start- 验证数据一致性:
SELECT count(*) FROM test_rewind;4. 高级应用场景与技巧
4.1 网络隔离环境处理
当节点间无法直接连接时,可先备份新主库的WAL:
pg_basebackup -h new_primary -U postgres -D ./backup -Fp -Xs -P然后使用本地模式rewind:
pg_rewind --target-pgdata=/old/primary --source-pgdata=./backup4.2 大库优化参数
对于TB级数据库,建议增加:
pg_rewind --progress --buffer-size=8192 ...--progress:显示实时进度--buffer-size:增大I/O缓冲区(单位MB)
4.3 自动化脚本示例
#!/bin/bash PRIMARY_CONN="host=10.0.0.2 user=replicator" TARGET_DIR="/var/lib/postgresql/12/main" if pg_rewind --dry-run --target-pgdata=$TARGET_DIR --source-server="$PRIMARY_CONN"; then pg_rewind --target-pgdata=$TARGET_DIR --source-server="$PRIMARY_CONN" \ --write-recovery-conf pg_ctl -D $TARGET_DIR start else echo "Rewind not possible, need full base backup" pg_basebackup -h 10.0.0.2 -U replicator -D $TARGET_DIR -Fp -Xs -P -R fi5. 故障排查与性能优化
5.1 常见错误解决方案
| 错误信息 | 原因分析 | 解决方案 |
|---|---|---|
| "target server must be shut down" | 目标库未关闭 | 执行pg_ctl stop -m fast |
| "could not find common ancestor" | WAL日志不连续 | 检查wal_keep_segments参数 |
| "permission denied" | 目录权限不足 | 设置700权限并属主为postgres |
5.2 性能监控指标
通过pg_stat_progress_basebackup视图监控:
SELECT * FROM pg_stat_progress_basebackup WHERE pid = pg_backend_pid();关键指标说明:
backup_streamed:已传输字节数backup_total:总需传输字节数tablespaces_streamed:已处理表空间数
5.3 WAL归档配置建议
在postgresql.conf中添加:
wal_keep_segments = 100 # 保留至少100个WAL段 archive_mode = on # 启用归档 archive_command = 'test ! -f /mnt/wal_archive/%f && cp %p /mnt/wal_archive/%f'6. 生产环境最佳实践
定期验证机制:每月执行一次模拟rewind测试,确保灾难恢复流程可靠
监控关键指标:
pg_stat_replication.sync_statepg_stat_archiver.last_failed_wal
容量规划建议:
- 保留至少20%的磁盘空间用于rewind临时文件
- 网络带宽应满足每小时传输1TB数据的能力
安全加固措施:
CREATE ROLE rewind_user WITH LOGIN REPLICATION; ALTER SYSTEM SET primary_conninfo = 'user=rewind_user password=securepass';
我在实际运维中总结出一个经验公式来预估rewind时间:
预估时间(分钟) = 数据库大小(GB) × 0.05 + 未同步WAL数量 × 0.1例如500GB数据库有100个未同步WAL文件,预计需要约35分钟完成rewind。这个经验值基于SSD存储和千兆网络环境,实际时间可能因硬件配置有所不同。