pg_rewind — 把一个PostgreSQL数据目录与另一个从该目录中复制出来的数据目录同步
pg_rewind
[option
...] { -D
| --target-pgdata
} directory
{ --source-pgdata=
| directory
--source-server=
} connstr
pg_rewind是用于在集簇的时间线分叉以后,同步一个 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会话所复制,则在目标服务器被启动时必须让这些 WAL 可用。
这可以通过在目标数据目录中创建一个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之前移除它们。在做了rewind之后,一些那样的文件可能已经被从源服务器拷贝,这样就有必要移除已经拷贝的数据并且恢复到rewind之前使用的链接集合。
pg_rewind接受以下命令行参数:
-D directory
--target-pgdata=directory
此选项指定与源同步的目标数据目录。在运行pg_rewind之前,目标服务器必须干净地关闭。
--source-pgdata=directory
指定要与目标服务器同步的源服务器数据目录的文件系统路径。此选项要求源服务器被干净地关闭。
--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
使用目标集群配置中定义的restore_command
来从WAL归档中检索WAL文件,
如果这些文件在pg_wal
目录中不再可用。
--config-file=filename
使用指定的主服务器配置文件用于目标集群。这会影响pg_rewind,
当它在此集群上使用postgres命令进行倒带操作时
(在使用选项restore_command
时
-c/--restore-target-wal
和强制完成崩溃恢复时)。
--debug
打印详细的调试输出,主要用于开发人员调试pg_rewind。
--no-ensure-shutdown
pg_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;
当使用近期升级的在线群集作为源执行pg_rewind时,必须在升级后执行CHECKPOINT
以便其控制文件反映最新的时间线信息,
pg_rewind使用这些信息检查目标群集是否可以使用指定的源群集倒回。
其基本思想是从源集簇拷贝所有文件系统级别的改变到目标集簇:
以源集簇的时间线历史从目标集簇分叉出来的点之前的最后一个检查点为起点,扫描目标集簇的 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
和.DS_Store
以及任何以pgsql_tmp
开头的文件或目录都被省略。
创建一个backup_label
文件,在故障转移时创建的检查点处开始WAL重放,并将pg_control
文件配置为最小一致性LSN,该LSN定义为从活动源回放时的pg_current_wal_insert_lsn()
结果,或从停止的源回放时的最后一个检查点LSN。
启动目标时,PostgreSQL将重放所有必需的WAL,从而使数据目录处于一致状态。