52.4. 流复制协议

要启动流复制,前端在启动消息中发送replication参数。一个布尔值true会告诉后端进入到walsender模式,在其中一小组复制命令而不是SQL命令可以被发出。只有简单查询协议可以在walsender模式中使用。在启用log_replication_commands时,服务器日志中会记录复制命令。传递database作为值指示 walsender 连接到dbname参数指定的数据库,这将允许该连接被用于来自哪个数据库的逻辑复制。

出于测试复制命令的目的,你可以通过psql或者任何使用libpq的工具使用包含replication选项的连接字符串建立一个复制连接,例如:

psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"

不过更常用的是:pg_receivewal(对于物理复制)或者pg_recvlogical(对于逻辑复制)。

在walsender模式中可以接受的命令有:

IDENTIFY_SYSTEM

请求服务器标识它自己。服务器以一个行构成的结果集作为答复,其中包含四个域:

systemid (text)

标识该集簇的唯一的系统标识符。这可以被用来检查用于初始化后备机的基础备份是否来自于同一个集簇。

timeline (int4)

当前的时间线 ID。也对于检查后备机是否与主控机一致有用。

xlogpos (text)

当前的 WAL 刷写位置。用于得到一个在预写日志中的已知位置作为流的开始位置。

dbname (text)

要连接到的数据库或者空。

SHOW name

请求服务器发送运行时参数的当前设置。这与SQL命令SHOW类似。

name

运行时参数的名称。在第 19 章中记录了可用的参数。

TIMELINE_HISTORY tli

请求服务器将时间线tli的历史文件发送过来。服务器将以一行组成的结果集作为答复,其中包含两个域:

filename (text)

时间线历史文件的文件名,例如00000002.history

content (bytea)

时间线历史文件的内容。

CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL [ RESERVE_WAL ] | LOGICAL output_plugin [ EXPORT_SNAPSHOT | NOEXPORT_SNAPSHOT | USE_SNAPSHOT ] }

创建一个物理的或者逻辑的复制槽。更多关于复制槽的内容请见 第 26.2.6 节

slot_name

要创建的槽的名称。必须是一个合法的复制槽名称(见 第 26.2.6.1 节)。

output_plugin

被用于逻辑解码的输出插件的名称(见 第 48.6 节)。

TEMPORARY

声明该复制槽是临时的。出错或会话结束时,不保存临时槽并自动将其删除。

RESERVE_WAL

指定这个物理复制槽立即保留WAL。否则,只有来自流复制客户端的连接上才会保留WAL

EXPORT_SNAPSHOT
NOEXPORT_SNAPSHOT
USE_SNAPSHOT

决定如何处理逻辑插槽初始化期间创建的快照。默认情况下, EXPORT_SNAPSHOT将导出快照以用于其他会话。该选项不能在事务中使用。 USE_SNAPSHOT将使用执行命令的当前事务的快照。 该选项必须在事务中使用,并且CREATE_REPLICATION_SLOT 必须是在该事务中运行的第一个命令。最后,NOEXPORT_SNAPSHOT 将正常使用快照进行逻辑解码,但不会对其执行任何操作。

为了响应此命令,服务器将发送包含以下字段的单行结果集:

slot_name (text)

新创建的复制槽的名称。

consistent_point (text)

插槽一致的WAL位置。这是从此复制插槽开始流式传输的最早位置。

snapshot_name (text)

该命令导出的快照标识符。在此连接上执行新命令或复制连接关闭之前, 快照有效。如果创建的插槽是物理的,则为空。

output_plugin (text)

新创建的复制插槽使用的输出插件的名称。如果创建的插槽是物理的,则为空。

START_REPLICATION [ SLOT slot_name ] [ PHYSICAL ] XXX/XXX [ TIMELINE tli ]

指示服务器开始启动流WAL,从 WAL 位置XXX/XXX开始。如果TIMELINE选项被指定,流传送会在时间线tli上开始,否则会选择服务器的当前时间线。服务器可以回复一个错误,例如如果被请求的WAL节已经被回收了。如果成功,服务器将会响应一个CopyBothResponse消息,并且然后开始以流的方式把WAL传送给前端。

如果通过slot_name提供了一个槽的名称,它将被更新复制进度,这样该服务器知道哪些 WAL 段以及哪些事务(如果hot_standby_feedback为打开)仍然被后备机所需要。

如果客户端请求一个并非最新的时间线,但是属于服务器历史的一部分,服务器将会把该时间线上从请求点开始的所有WAL以流式传送,一直到服务器切换到另外一个时间线的点。如果客户端请求在一个老的时间线末尾进行流传送,服务器将在不进入COPY模式的情况下立即响应CommandComplete。

在流传送完一个非最新时间线上所有的WAL之后,服务器将会通过退出COPY模式来结束流。当客户端认识到这一点并也退出COPY模式时,服务器会发送一个包含一行两列的结果集,以指示在该服务器历史中的下一个时间线。第一列是下一个时间线的 ID(类型int8),而第二列是发生切换的 WAL 位置(类型text)。通常,切换位置是被流传送的WAL的末尾,但是在很少的情况下服务器会从旧的时间线中发送一些WAL,而该时间线是服务器本身在提示之前还没有重放的。最后,服务器发送CommandComplete消息,并且做好准备接受一个新的命令。

WAL数据以一系列CopyData消息的形式被发送(这允许其他信息穿插其中,特别是服务器可以在开始流传送后遇到失败时发送一个ErrorResponse消息)。每个从服务器到客户端的CopyData消息承载了一个下列格式之一的消息:

XLogData (B)

Byte1('w')

标识该消息是WAL数据。

Int64

在消息中WAL数据的起始点。

Int64

服务器上WAL的当前终点。

Int64

在传送时服务器的系统时钟,以从2000-01-01午夜开始的微秒计。

Byten

WAL数据流的一节。

一个WAL记录绝不会被分割到两个XLogData消息。如果一个WAL记录跨越了一个WAL页面的边界,并且因此已经被使用连续的记录分割,它可以在页面边界被分割。换句话说,第一个主要WAL记录和它的后续记录可以在不同的XLogData消息中被发送。

主要存活消息 (B)

Byte1('k')

标识该消息是一个发送者存活消息。

Int64

服务器上WAL的当前终点。

Int64

在传送时服务器的系统时钟,以从2000-01-01午夜开始的微秒计。

Byte1

1表示客户端应该尽快回复该消息,以避免连接超时。否则为0。

接收进程可以在任何时候给发送者发送回复,回复可以使用下列消息格式之一(也在CopData消息中使用):

后备机状态更新 (F)

Byte1('r')

标识该消息是一个接收者状态更新。

Int64

接收到并且写入到后备机磁盘的最后一个WAL比特的位置+1。

Int64

被刷入到后备机磁盘的最后一个WAL比特的位置+1。

Int64

被应用在后备机上的最后一个WAL比特的位置+1。

Int64

在传送时客户端的系统时钟,以从2000-01-01午夜开始的微秒计。

Byte1

如果为1,客户端要求服务器马上回复这个消息。这可以被用来ping服务器以测试连接是否仍然完好。

热备机反馈消息 (F)

Byte1('h')

标识该消息是一个热备机反馈消息。

Int64

在传送时客户端的系统时钟,以从2000-01-01午夜开始的微秒计。

Int32

备用数据库的当前全局xmin,不包括来自任何复制插槽的catalog_xmin。 如果此值和以下catalog_xmin均为0,则将此视为热备机反馈将不再在此连接上发送的通知。 稍后的非零消息可以重新启动反馈机制。

Int32

备用服务器上全局xmin xid的时代。

Int32

备用数据库中任何复制插槽的最低catalog_xmin。 如果备用数据库上不存在catalog_xmin或者热备份反馈被禁用,则设置为0。

Int32

备用服务器上catalog_xmin xid的时代。

START_REPLICATION SLOT slot_name LOGICAL XXX/XXX [ ( option_name [ option_value ] [, ...] ) ]

指示服务器为逻辑复制开始流式传送 WAL,从 WAL 位置XXX/XXX开始。服务器可以回复一个错误,例如如果请求的 WAL 小节已经回环。如果成功,服务器会响应一个 CopyBothResponse 消息,并且接着开始流失传送 WAL 给前端。

消息内部的消息与START_REPLICATION ... PHYSICAL中记录的格式相同。

与选中槽关联的输出插件被用来处理流的输出。

SLOT slot_name

要从哪个槽流式传送改变。这个参数是必须的,并且必须对应于一个现有的用LOGICAL模式的CREATE_REPLICATION_SLOT创建的逻辑复制槽。

XXX/XXX

要开始流传送的 WAL 位置。

option_name

一个传递给该槽的逻辑解码插件的选项的名称。

option_value

字符串常量形式的选项值,与前面指定的选项关联。

DROP_REPLICATION_SLOT slot_name [ WAIT ]

删除一个复制槽,释放任何保留的服务器端资源。 如果插槽是在walsender连接到的数据库以外的数据库中创建的逻辑插槽,则此命令将失败。

slot_name

要删除的槽的名称。

WAIT

此选项会导致命令等待处于活动状态的插槽,直到它变为非活动状态, 而不是默认的引发错误行为。

BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ]

指示服务器开始流传送一个基础备份。在备份开始之前系统将自动被置于备份模式,而在备份结束时会自动被退出备份模式。可以接受下列选项:

LABEL 'label'

设置备份的标签。如果没有指定,将会使用base backup作为标签。标签的引号规则和standard_conforming_strings开启时标准SQL字符串的一样。

PROGRESS

请求用以生成一个进度报告的信息。这将送回位于每个表空间头部的一个近似大小,它可以被用于计算流还有多久才能被完成。它通过在传输开始之前枚举所有文件大小来计算,并且可能会对性能产生一种负面影响 -- 特别情况下它可能会在流传送第一个数据之前就耗费很长时间。因为数据库文件可能在备份期间改变,这个大小只是近似的并且可能在近似计算和发送真正的文件之间增长或者收缩。

FAST

请求一个快速检查点。

WAL

在备份中包含必需的WAL段。这将把开始和停止备份之间的所有文件包括在base目录tar文件中的pg_wal目录中。

NOWAIT

默认情况下,备份会等待直到最后一个要求的 WAL 段被归档,或者当日至归档被禁用时发出一个警告。指定NOWAIT会禁用等待和警告,而让客户端负责确保所要求的日志是可用的。

MAX_RATE rate

单位时间内从服务器传输到客户端的最大数据量限制。期望的单位是千字节每秒。如果指定了这个选项,值必须等于零或者位于 32 kB到 1 GB(包括)范围之间。如果 0 被传入或者没有指定该选项,对于传输将没有限制。

TABLESPACE_MAP

在名为tablespace_map的文件中包括有关pg_tblspc目录中存在的符号链接的信息。这个表空间映射文件包括了在目录pg_tblspc中存在的每一个符号链接的名字以及它的完整路径。

当备份被启动,服务器将首先发送两个普通结果集,后面会跟着一个或多个CopyResponse结果。

第一个普通结果集在一行两列中包含了备份的起始位置。第一列包含使用XLogRecPtr格式给出的开始位置,第二列包含相应的时间线ID。

第二个普通结果集中为每一个表空间都有一行。行中的域有:

spcoidoid

表空间的 OID,如果是base目录则为空。

spclocationtext

表空间目录的完整路径,如果是base目录则为空。

sizeint8

如果进度报告被请求,这里是表空间的近似大小,否则为空。

在第二个普通结果集之后,一个或多个CopyResponse结果将被发送,一个用于主数据目录而对每一个除pg_defaultpg_global之外的额外表空间也会有一个。CopyResponse结果中的数据将会使一个tar格式(遵循POSIX 1003.1-2008标准中指定的ustar交换格式)的表空间内容转储,不过标准中定义的两个拖尾全0块将被忽略。在tar数据完成后,一个最终普通结果集将被发送,包含了备份的WAL结束位置,格式与起始位置相同。

用于数据目录和每个表空间的tar归档将包含目录中的所有文件,不管它们是否为PostgreSQL文件或者是被加入的其他文件。唯一被排除的文件是:

  • postmaster.pid

  • postmaster.opts

  • 在PostgreSQL服务器运行期间创建的各种临时文件和目录, 例如任何以pgsql_tmp开头的文件或目录。

  • pg_wal及其子目录。如果备份运行时要求包括WAL文件,一个pg_wal的合成版本将被包括进来,但是只会包含那些备份工作必需的文件,而不是包含剩下的内容。

  • pg_dynshmempg_notifypg_replslotpg_serialpg_snapshotspg_stat_tmppg_subtrans被复制为一个空目录(即使它们是符号链接)。

  • 除常规文件和目录之外的其他文件,例如符号链接(除了上面列出的目录之外) 和特殊设备文件,会被跳过(pg_tblspc中的符号链接会被保留)。

如果服务器上的底层文件系统支持,所有者、组合文件模式都会被设置。