48.3. 流复制协议

要启动流复制,前端在启动消息中发送replication参数。这会告诉后端进入到walsender模式,在其中一小组复制命令而不是SQL命令可以被发出。只有简单查询协议可以在walsender模式中使用。 在walsender模式中可以接受的命令有:

IDENTIFY_SYSTEM

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

systemid

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

timeline

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

xlogpos

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

TIMELINE_HISTORY tli

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

filename

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

content

时间线历史文件的内容。

START_REPLICATION XXX/XXX TIMELINE tli

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

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

在流传送完一个非最新时间线上所有的WAL之后,服务器将会通过退出COPY模式来结束流。当客户端认识到这一点并也退出COPY模式时,服务器会发送一个包含一行两列的结果集,以指示在该服务器历史中的下一个时间线。第一列是下一个时间线的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记录绝不会被分割到两个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。如果后备机正在发送通知告知热备机反馈将不再通过此连接发送,这个值可能为0。后来的非0消息将重新启动反馈机制。

Int32

后备机的当前世代。

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

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

LABEL 'label'

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

PROGRESS

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

FAST

请求一个快速检查点。

WAL

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

NOWAIT

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

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

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

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

spcoid

表空间的oid,如果是base目录则为NULL

spclocation

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

size

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

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

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

  • postmaster.pid

  • postmaster.opts

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

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

一旦所有的表空间已经被发送,一个最终普通结果集将被发送。这个结果集包含了备份的结束位置,它在一个单行单列的结果中使用XLogRecPtr格式给出。