49.3. 流复制协议

为了初始化流复制,前端需要发送带replication参数的startup消息。 布尔值true告诉后端进入walsender模式, 在这个模式下可以发送数量不多的复制命令集而不是通常的SQL命令。 并且在walsender模式下,只能使用简单查询协议。传递database 指导walsender连接到在dbname参数中指定的数据库, 这将允许该连接从那个数据库中进行逻辑复制。

为了测试复制命令的目的,可以通过psql 或者任何其他使用libpq的工具和包含replication 选项的连接字符串做一个复制连接,比如:

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

不过,通常使用pg_receivexlog(用于物理复制) 或pg_recvlogical(用于逻辑复制)更有用。

walsender模式下可以接受的命令如下:

IDENTIFY_SYSTEM

请求服务端标识自己。服务端会应答一个只有一行的结果集,包含4个字段。

systemid

标识数据库集群的唯一的系统标识符。 这个可以用于检查初始化备机用的基础备份来自同一个数据库集群。

timeline

当前的时间线ID(TimelineID)。 同样可用于检查备机和主机的一致性。

xlogpos

当前的xlog的刷新位置。 可用于获得在事务日志中流从哪而开始的已知的位置信息。

dbname

数据库连接到或者为NULL。

TIMELINE_HISTORY tli

请求服务端为时间线tli发送时间线历史文件。 服务端会应答一个只有一行的结果集,包含3个字段。

filename

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

content

时间线历史文件的内容。

CREATE_REPLICATION_SLOT slot_name { PHYSICAL | LOGICAL output_plugin }

创建一个物理或逻辑复制槽。参阅第 25.2.6 节 获取更多关于复制槽的信息。

slot_name

要创建的槽的名字。必须是有效的复制槽名称(参阅 第 25.2.6.1 节)。

output_plugin

用于逻辑解码的输出插件的名字(参阅 第 46.6 节)。

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

指示服务端从WAL位置XXX/XXX开始WAL流。 如果声明了TIMELINE选项,则从时间线 tli开始流;否则,选择服务器的当前时间线。 服务端可能会回应一个错误,比如,如果在请求的WAL段已经被回收的情况下。 如果成功,服务端响应一个CopyBothResponse消息,然后开启到前端的WAL流。

如果通过slot_name提供了槽的名字, 那么它将作为复制进程被更新,这样服务器就知道了是哪个WAL段, 和hot_standby_feedback是否是在哪个事务上,仍然被备用服务器所需。

如果客户端请求的时间线不是最新的,但是是服务端历史的一部分,服务端将会传送从请求的开始点开始直到服务端切换到另一个时间线为止这个时间线上的所有WAL。 如果客户端请求的流正好在旧时间线的终点上,服务端会立即响应一个CommandComplete而不进入COPY模式。

传送完这个非最新的时间线上的所有WAL后,服务端退出COPY模式结束流。 当客户端也以退出COPY模式作为应答,服务端发送一个只有一行的结果集,包含2的字段,指示在这个服务器上的下一个时间线。 第一列是下一个时间线的ID,第二列是发生切换的XLOG位置。 通常切换点是已经传送的WAL流的终点,但是在极端的情况下,服务端发送的WAL可能来自自己升级前还没有回放的旧的时间线。 最终服务端发送CommandComplete消息并准备接收新的命令。

WAL数据作为一系列的CopyData消息发送。 (这允许混合其它信息,具体而言服务端在开始流之后发生了失败可以发送ErrorResponse消息。) 每个从服务端到客户端的CopyData消息的装载数据中包含下面的格式的消息:

XLogData (B)

Byte1('w')

标识消息是一个WAL数据。

Int64

消息内的WAL数据开始点。

Int64

当前服务端上的WAL終点。

Int64

传送时服务端上的系统时间,是从2000-01-01午夜开始的微秒数。

Byten

WAL数据流的片段。

单个的WAL记录一定不会被分割成2个XLogData消息。 当一个WAL记录跨越WAL页的边界,并且因此已经被连续的记录分割了,可以在页边界上分割。 换句话说,第一个主要的WAL记录和它后续的记录可能以不同XLogData消息传送。

主keepalive消息 (B)

Byte1('k')

标识这是一个发送者的keepalive消息。

Int64

服务端上当前的WAL终点。

Int64

传送时服务端上的系统时间,是从2000-01-01午夜开始的微秒数。

Byte1

1意味着客户端应该尽可能快的应答这个消息,以防止超时切断连接。0的意思相反。

接受进程可以在任何时间使用以下消息格式(同样作为CopyData消息的装载数据)应答发送者:

备机状态更新(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。如果备机正在传送热备机反馈将不再发到这个连接上的通知,这个值可能为0。之后非零的消息可能再初始化反馈机制。

Int32

备机的当前时间戳。

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

指示服务端从WAL位置XXX/XXX开始WAL流。 服务端可能会回应一个错误,比如,如果在请求的WAL段已经被回收的情况下。 如果成功,服务端响应一个CopyBothResponse消息,然后开启到前端的WAL流。

CopyBothResponse消息里面的信息的格式START_REPLICATION ... PHYSICAL 所记录的格式相同。

与选定的槽相关的输出插件用来处理流的输出。

SLOT slot_name

要流动变化的槽的名字。这个参数是必须的,并且必须对应于在LOGICAL 模式下用CREATE_REPLICATION_SLOT创建的现有逻辑复制槽。

XXX/XXX

开始流的WAL位置。

option_name

传递到槽的逻辑解码插件的选项名。

option_value

可选值,以字符串常量的格式,与指定的选项相关。

DROP_REPLICATION_SLOT slot_name

删除一个复制槽,释放任意保留的服务器端资源。如果该槽被一个活动的连接并发使用, 则该命令失败。

slot_name

要删除的槽的名字。

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

指示服务器开始一个基础备份的流。系统将在备份开始前自动进入备份模式,并且在备份完成后回到原来的状态。 可以接受以下选项:

LABEL 'label'

设定备份的标签。 如果没有指定,则使用base backup。 标签的引号使用规则与standard_conforming_strings开关打开时的标准SQL字符串相同。

PROGRESS

请求产生进度报告时要用的信息。 这将在每个表空间的头部发回一个近似的大小,用于计算到流结束还有多少距离。 这个大小是在传输前通过一次性统计所有文件的大小获取的,可能会产生性能上的冲击 - 实际上在传送第一个流前可能会花比较长的时间。 既然数据库文件可能在备份过程中改变,这个大小只是近似的,并且在估算和实际发送文件之间可能增长和收缩。

FAST

请求一个快速的检查点(checkpoint)。

WAL

包含这个备份所必要的WAL段。将包括在备份开始和结束期间pg_xlog目录下的所有base目录tar文件。

NOWAIT

缺省时备份会等待最后一个需要的xlog段被归档,或者在没有启用归档的情况下发出一个警告。 指定NOWAIT可以把等待和警告无效,让客户端负责确认需要的日志是否有效。

MAX_RATE rate

限制(节流)单位时间内从服务器传递到客户端的数据的最大数量。 预期的单位是千字节每秒。如果声明了这个选项,那么值必须要么等于0, 要么必须介于范围32kB到1GB(包含)之间。如果给出0或者没有声明该选项, 则在传输上没有限制。

备份开始时,服务端首先发送2个通常的结果集,然后是1个以上的CopyResponse结果。

最初的通常的结果集里,包含由2列构成的单一行的备份位置。 第一个列是XLogRecPtr形式的开始位置,第二列是对应的时间线ID。

第二个通常的结果集里各个表空间一行数据。 每行包含的字段如下:

spcoid

表空间的oid。 base目录的情况下则为NULL

spclocation

表空间目录的完全路径。base目录的情况下则为NULL

size

要求进度状况报告的情况下,表空间的估算容量。 没有要求的情况下为NULL

第二个通常结果集之后被送过来的是一个以上的CopyResponse结果。 一个是PGDATA用的,其余的则是每个pg_defaultpg_global以外的追加表空间都有一个。 CopyResponse结果内的数据是表空间内容的tar形式(遵照POSIX 1003.1-2008规定的"ustar交换形式")的转储(dump)。 但是,标准规定的最后的2个零数据块被省掉了。 tar数据结束后,和开始位置的形式相同,是包含备份终了位置的最终的结果集。

为data目录和每个表空间做的tar归档包含目录下的所有文件,不管它们是PostgreSQL 的文件还是相同目录下的其它在文件。 但是以下文件被排除在外:

  • postmaster.pid

  • postmaster.opts

  • 在PostgreSQL服务器操作期间创建的各种临时文件。

  • pg_xlog,包含子目录。如果备份是包含WAL执行的,将包含一个合成版的pg_xlog。 它只包含对于备份工作必须的文件而没有其余的内容。

  • pg_replslot是作为空目录拷贝的。

  • 跳过除了普通文件和目录之外的文件,比如符号连接和特殊驱动文件。 (维护在pg_tblspc中的符号连接。)

如果服务器的文件系统支持的话,所有者,组和文件模式会被设置。

所有的表空间被传送完后,发送最终的通常结果集。 这个结果集里包含单一行单一列的XLogRecPtr格式的备份结束位置。