🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 48.3\. 流复制协议 为了初始化流复制,前端需要发送带`replication`参数的startup消息。 这告诉后端进入walsender模式,在这个模式下可以发送数量不多的复制命令集而不是通常的SQL命令。 并且在walsender模式下,只能使用简单查询协议。 walsender模式下可以接受的命令如下: IDENTIFY_SYSTEM 请求服务端标识自己。服务端会应答一个只有一行的结果集,包含3个字段。 systemid 标识数据库集群的唯一的系统标识符。 这个可以用于检查初始化备机用的基础备份来自同一个数据库集群。 timeline 当前的时间线ID(TimelineID)。 同样可用于检查备机和主机的一致性。 xlogpos 当前的xlog的写入位置。 可用于获得在事务日志中流从哪而开始的已知的位置信息。 TIMELINE_HISTORY `_tli_` 请求服务端为时间线`_tli_`发送时间线历史文件。 服务端会应答一个只有一行的结果集,包含3个字段。 filename 时间线历史文件的文件名,比如00000002.history。 content 时间线历史文件的内容。 START_REPLICATION `_XXX/XXX_` TIMELINE `_tli_` 指示服务端从时间线`_tli_`上的WAL位置`_XXX/XXX_`开始WAL流。 服务端可能会回应一个错误,比如,如果在请求的WAL段已经被回收的情况下。 如果成功,服务端响应一个CopyBothResponse消息,然后开启到前端的WAL流。 如果客户端请求的时间线不是最新的,但是是服务端历史的一部分,服务端将会传送从请求的开始点开始直到服务端切换到另一个时间线为止这个时间线上的所有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午夜开始的微秒数。 Byte`_n_` 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 备机的当前时间戳。 BASE_BACKUP [`LABEL` `_'label'_`] [`PROGRESS`] [`FAST`] [`WAL`] [`NOWAIT`] 指示服务器开始一个基础备份的流。系统将在备份开始前自动进入备份模式,并且在备份完成后回到原来的状态。 可以接受以下选项: `LABEL` `_'label'_` 设定备份的标签。 如果没有指定,则使用`base backup`。 标签的引号使用规则与[standard_conforming_strings](#calibre_link-1031)开关打开时的标准SQL字符串相同。 `PROGRESS` 请求产生进度报告时要用的信息。 这将在每个表空间的头部发回一个近似的大小,用于计算到流结束还有多少距离。 这个大小是在传输前通过一次性统计所有文件的大小获取的,可能会产生性能上的冲击 - 实际上在传送第一个流前可能会花比较长的时间。 既然数据库文件可能在备份过程中改变,这个大小只是近似的,并且在估算和实际发送文件之间可能增长和收缩。 `FAST` 请求一个快速的检查点(checkpoint)。 `WAL` 包含这个备份所必要的WAL段。将包括在备份开始和结束期间`pg_xlog`目录下的所有base目录tar文件。 `NOWAIT` 缺省时备份会等待最后一个需要的xlog段被归档,或者在没有启用归档的情况下发出一个警告。 指定`NOWAIT`可以把等待和警告无效,让客户端负责确认需要的日志是否有效。 备份开始时,服务端首先发送2个通常的结果集,然后是1个以上的CopyResponse结果。 最初的通常的结果集里,包含由2列构成的单一行的备份位置。 第一个列是XLogRecPtr形式的开始位置,第二列是对应的时间线ID。 第二个通常的结果集里各个表空间一行数据。 每行包含的字段如下: spcoid 表空间的oid。 base目录的情况下则为`NULL`。 spclocation 表空间目录的完全路径。base目录的情况下则为`NULL`。 size 要求进度状况报告的情况下,表空间的估算容量。 没有要求的情况下为`NULL`。 第二个通常结果集之后被送过来的是一个以上的CopyResponse结果。 一个是PGDATA用的,其余的则是每个`pg_default`、`pg_global`以外的追加表空间都有一个。 CopyResponse结果内的数据是表空间内容的tar形式(遵照POSIX 1003.1-2008规定的"ustar交换形式")的转储(dump)。 但是,标准规定的最后的2个零数据块被省掉了。 tar数据结束后,和开始位置的形式相同,是包含备份终了位置的最终的结果集。 为data目录和每个表空间做的tar归档包含目录下的所有文件,不管它们是PostgreSQL 的文件还是相同目录下的其它在文件。 但是以下文件被排除在外: * `postmaster.pid` * `postmaster.opts` * `pg_xlog`,包含子目录。如果备份是包含WAL执行的,将包含一个合成版的`pg_xlog`。 它只包含对于备份工作必须的文件而没有其余的内容。 如果服务器的文件系统支持的话,所有者,组和文件模式会被设置。 所有的表空间被传送完后,发送最终的通常结果集。 这个结果集里包含单一行单一列的XLogRecPtr格式的备份结束位置。