postgresql下pg_rewind数据库恢复

在 PostgreSQL 主备切换(Failover)后,旧的主库因为数据可能领先或与新主库(原备库)产生了分歧,无法直接启动同步。pg_rewind 的作用是对比两者的 WAL 日志,将旧主库"回滚"到分叉点,使其能够以增量同步的方式重新加入集群,避免了全量重做数据(pg_basebackup)的巨大开销。

一、实现流程

pg_rewind 的工作可以分为五个关键阶段:

1. 扫描新主库的 WAL 日志

pg_rewind 首先读取新主库 的 WAL 日志,从当前时刻向上追溯,直到找到与旧主库最后一次同步时的共同时间线位置。

2. 扫描旧主库的数据文件

这是最关键的一步。pg_rewind 会读取旧主库从分叉点开始之后的所有 WAL 日志。

  • 它会解析这些 WAL 记录中的 Data Page ID
  • 记录下哪些数据页(Page)在分叉后被修改过了。
  • 将这些被修改过的块编号放入一个散列表中。

3. 从新主库获取对应数据块

一旦确定了旧主库中哪些块是"脏"的(即分叉后修改过的),pg_rewind 就会连接到新主库,仅请求这些特定块的最新副本。

  • 此时它会利用新主库的 wal_log_hints 参数或数据校验和,因为这些机制强制 PostgreSQL 在 checkpoint 后的第一次修改时记录整个数据页的内容(Full Page Writes)。

4. 覆盖旧主库的数据块

将从新主库拷贝过来的"正确"数据页,直接写入到旧主库对应的文件位置中。同时,它还会同步一些系统文件(如 pg_controlpg_xact 等)。

5. 复制新主库的 WAL 日志

最后,它会从新主库拷贝分叉点之后的所有 WAL 日志到旧主库的 pg_wal 目录。这是为了确保旧主库在下次启动时,可以通过重放这些 WAL 日志来实现数据的最终一致性。

二、pg_rewind 恢复示例

以下是使用 pg_rewind 恢复旧主库为新从库的详细步骤:

2.1 前提条件

  1. 配置要求:主库在故障前必须开启了 wal_log_hints = on,或者数据库初始化时开启了数据校验和(data checksums)。
  2. 状态确认
    • 新主库(原备库)已提升并处于读写状态。
    • 旧主库(待恢复库)必须已经彻底停止(干净关闭或宕机后未再写入)。

2.2 操作步骤

假设:

  • 新主库 IP:192.168.1.102
  • 旧主库 IP:192.168.1.101 (当前操作在该机器上执行)
  • 数据目录:/var/lib/postgresql/data
2.2.1. 停止旧主库(如果还在运行)

确保旧主库完全停止

systemctl stop postgresql

2.2.2. 执行 pg_rewind

旧主库 节点上,使用 postgres 用户执行以下命令:

pg_rewind --target-pgdata=/var/lib/postgresql/data \

--source-server="host=192.168.1.102 user=postgres dbname=postgres password=your_password" \

--progress

  • --target-pgdata:旧主库的数据目录。
  • --source-server:指向新主库的连接字符串。
  • 注意:连接用户需具备超级用户权限或 pg_rewind 所需的特定权限。
2.2.3. 配置为从库模式

pg_rewind 只负责同步数据文件,不会自动开启流复制。你需要将其设置为备库:

  1. 创建从库标记文件

touch /var/lib/postgresql/data/standby.signal

  1. 修改连接信息 : 编辑 /var/lib/postgresql/data/postgresql.auto.conf,更新 primary_conninfo 指向新主库

primary_conninfo = 'host=192.168.1.102 port=5432 user=replica_user password=your_password'

2.2.4. 启动旧主库(此时作为新从库)

systemctl start postgresql

2.3 验证状态

  1. 检查同步状态: 在新主库执行:

SELECT * FROM pg_stat_replication;

  1. 查看日志: 检查旧主库(现从库)日志,确认是否出现 started streaming WAL from primary at ... 的字样。

三、核心注意事项

  • WAL 保留:pg_rewind 需要新主库上保留自"分叉点"以来的所有 WAL 日志。可以调大 max_slot_wal_keep_size 或使用 WAL 归档。如果日志已被清理,pg_rewind 会失败,此时只能通过 pg_basebackup重新做全量备份。
  • 配置文件:pg_rewind 默认会覆盖 postgresql.conf 等配置文件。如果主从配置有细微差异(如内存分配),建议执行后检查一下。
  • 复制槽:如果使用了物理复制槽,在新主库上可能需要重新创建对应新从库的复制槽。
相关推荐
重生之绝世牛码12 小时前
Linux软件安装 —— PostgreSQL高可用集群安装(postgreSQL + repmgr主从复制 + keepalived故障转移)
大数据·linux·运维·数据库·postgresql·软件安装·postgresql高可用
数据知道12 小时前
PostgreSQL 实战:详解 UPSERT(INSERT ON CONFLICT)
数据库·python·postgresql
数据知道14 小时前
PostgreSQL 实战:一文掌握如何优雅的进行递归查询?
大数据·数据库·postgresql
数据知道15 小时前
PostgreSQL 实战:索引的设计原则详解
数据库·postgresql
重生之绝世牛码16 小时前
Linux软件安装 —— PostgreSQL集群安装(主从复制集群)
大数据·linux·运维·数据库·postgresql·软件安装·postgresql主从集群
l1t20 小时前
修改德哥的PostgreSQL求解数独SQL在cedardb上运行
数据库·sql·postgresql·cedardb
数据知道2 天前
PostgreSQL 实战:EXPLAIN 执行计划详解
数据库·postgresql
l1t2 天前
DeepSeek辅助总结的测试PostgreSQL数据库插入性能方法
数据库·postgresql
PGCCC3 天前
通知:中国PostgreSQL培训认证 2026年度开班计划
数据库·postgresql
Linging_243 天前
PGSQL与Mysql对比学习
数据库·学习·mysql·postgresql