pg_rewind — 将 PostgreSQL 数据目录与其从其派生的另一个数据目录同步
pg_rewind
[选项
...] { -D
| --target-pgdata
} 目录
{ --source-pgdata=
| 目录
--source-server=
}connstr
pg_rewind 是一个用于在 PostgreSQL 集群的时间线分歧后,将一个 PostgreSQL 集群与同一集群的另一个副本同步的工具。一个典型的场景是在故障转移后将旧的主服务器作为跟随新主服务器的备用服务器重新联机。
在成功回退后,目标数据目录的状态类似于源数据目录的基本备份。与进行新的基本备份或使用 rsync 等工具不同,pg_rewind 不需要比较或复制集群中未更改的关系块。仅复制现有关系文件中的已更改块;包括新关系文件、配置文件和 WAL 段在内的所有其他文件都将被完整复制。因此,当数据库很大且集群之间只有很小一部分块不同时,回退操作明显快于其他方法。
pg_rewind 检查源集群和目标集群的时间线历史记录以确定它们分歧的点,并期望在目标集群的 pg_wal
目录中找到 WAL,一直追溯到分歧点。分歧点可以在目标时间线、源时间线或它们的共同祖先上找到。在目标集群在分歧后不久关闭的典型故障转移场景中,这不是问题,但如果目标集群在分歧后运行了很长时间,则其旧 WAL 文件可能不再存在。在这种情况下,您可以手动将它们从 WAL 存档复制到 pg_wal
目录,或使用 -c
选项运行 pg_rewind 以从 WAL 存档自动检索它们。使用 pg_rewind 不仅限于故障转移,例如,可以提升备用服务器,运行一些写入事务,然后回退以再次成为备用服务器。
在运行 pg_rewind 之后,WAL 重放需要完成,以便数据目录处于一致状态。当目标服务器再次启动时,它将进入存档恢复并重放分歧点之前最后一个检查点中源服务器生成的所有 WAL。如果在运行 pg_rewind 时某些 WAL 不再在源服务器中可用,因此无法被 pg_rewind 会话复制,则必须在启动目标服务器时使其可用。这可以通过在目标数据目录中创建 recovery.signal
文件并配置 postgresql.conf
中合适的 restore_command 来完成。
pg_rewind 要求目标服务器在 postgresql.conf
中启用 wal_log_hints 选项,或在使用 initdb 初始化集群时启用数据校验和。这些目前都不是默认开启的。还必须将 full_page_writes 设置为 on
,但默认情况下已启用。
如果 pg_rewind 在处理期间失败,则目标的数据文件夹可能无法恢复。在这种情况下,建议进行新的完整备份。
由于 pg_rewind 完全从源复制配置文件,因此在重新启动目标服务器之前可能需要更正用于恢复的配置,尤其是在将目标重新引入为源的备用服务器时。如果在回退操作完成后但在未配置恢复的情况下重新启动服务器,则目标可能再次偏离主服务器。
如果 pg_rewind 发现无法直接写入的文件,它将立即失败。例如,当源服务器和目标服务器对只读 SSL 密钥和证书使用相同的文件映射时,可能会发生这种情况。如果目标服务器上存在此类文件,建议在运行 pg_rewind 之前将其删除。在进行回退后,一些此类文件可能已从源复制,在这种情况下,可能需要删除复制的数据并恢复回退前使用的链接集。
pg_rewind 接受以下命令行参数
-D 目录
--target-pgdata=目录
此选项指定与源同步的目标数据目录。在运行 pg_rewind 之前,必须干净地关闭目标服务器
--source-pgdata=目录
指定与目标同步的源服务器数据目录的文件系统路径。此选项要求干净地关闭源服务器。
--source-server=connstr
指定一个 libpq 连接字符串以连接到源 PostgreSQL 服务器,以与目标同步。连接必须是具有足够权限以在源服务器上执行 pg_rewind 使用的函数(有关详细信息,请参见备注部分)的普通(非复制)连接或超级用户角色。此选项要求源服务器正在运行并接受连接。
-R
--write-recovery-conf
在输出目录中创建 standby.signal
并将连接设置追加到 postgresql.auto.conf
。此选项需要 --source-server
。
-n
--dry-run
执行所有操作,但实际上不修改目标目录。
-N
--no-sync
默认情况下,pg_rewind
将等待所有文件安全地写入磁盘。此选项导致 pg_rewind
在不等待的情况下返回,速度更快,但意味着随后的操作系统崩溃可能导致数据目录损坏。通常,此选项对于测试很有用,但不能用于生产安装。
-P
--progress
启用进度报告。打开此功能将在从源集群复制数据时提供近似进度报告。
-c
--restore-target-wal
如果 pg_wal
目录中不再提供这些文件,则使用目标集群配置中定义的 restore_command
从 WAL 存档中检索 WAL 文件。
--config-file=文件名
使用目标集群的指定主服务器配置文件。当 pg_rewind 在此集群上使用 postgres 命令对 rewind 操作进行内部使用时(使用选项 -c/--restore-target-wal
检索 restore_command
以及强制完成崩溃恢复时),这会影响 pg_rewind。
--debug
打印详细的调试输出,这对于调试 pg_rewind 的开发人员非常有用。
--no-ensure-shutdown
pg_rewind 要求在 rewind 之前干净地关闭目标服务器。默认情况下,如果目标服务器未干净地关闭,pg_rewind 会以单用户模式启动目标服务器以首先完成崩溃恢复,然后停止它。通过传递此选项,pg_rewind 会跳过此操作,如果服务器未干净地关闭,则会立即出错。在这种情况下,用户应自行处理情况。
-V
--version
显示版本信息,然后退出。
-?
--help
显示帮助,然后退出。
当使用 --source-server
选项时,pg_rewind 还会使用 libpq 支持的环境变量(请参见 第 34.15 节)。
环境变量 PG_COLOR
指定是否在诊断消息中使用颜色。可能的值包括 always
、auto
和 never
。
在使用在线集群作为源执行 pg_rewind 时,可以使用对源集群上 pg_rewind 使用的函数拥有足够权限的角色,而不是超级用户。以下是创建此类角色(此处命名为 rewind_user
)的方法
CREATE USER rewind_user LOGIN; GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user; GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user; GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user; GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;
基本思想是将所有文件系统级更改从源集群复制到目标集群
从源集群的时间线历史从目标集群分叉之前的最后一个检查点开始,扫描目标集群的 WAL 日志。对于每条 WAL 记录,记录每个被触及的数据块。这将生成源集群分叉后在目标集群中更改的所有数据块的列表。如果某些 WAL 文件不再可用,请尝试使用 -c
选项重新运行 pg_rewind,以在 WAL 存档中搜索丢失的文件。
使用直接文件系统访问 (--source-pgdata
) 或 SQL (--source-server
) 将所有这些更改的块从源集群复制到目标集群。关系文件现在处于源和目标的 WAL 时间线分歧之前的最后一个已完成检查点时刻的状态,加上源上在分歧之后更改的任何块的当前状态。
从源集群复制所有其他文件,包括新关系文件、WAL 段、pg_xact
和配置文件到目标集群。与基本备份类似,目录 pg_dynshmem/
、pg_notify/
、pg_replslot/
、pg_serial/
、pg_snapshots/
、pg_stat_tmp/
和 pg_subtrans/
的内容从从源集群复制的数据中省略。文件 backup_label
、tablespace_map
、pg_internal.init
、postmaster.opts
和 postmaster.pid
以及任何以 pgsql_tmp
开头文件或目录都将被省略。
创建一个 backup_label
文件,以便在故障转移时创建的检查点开始 WAL 重放,并使用从活动源回退时 pg_current_wal_insert_lsn()
的结果或从已停止源回退时最后一个检查点 LSN 定义的最小一致性 LSN 配置 pg_control
文件。
启动目标时,PostgreSQL 重放所有必需的 WAL,从而使数据目录处于一致状态。