46.3. 流复制协议 #
要发起流式复制,前端在启动消息中发送 replication 参数。这告知后端进入 WAL 发送进程模式,在该模式下可以发出一小组复制命令,而不是 SQL 语句。WAL 发送进程模式只能使用简单查询协议。WAL 发送进程模式接受以下命令:
- IDENTIFY_SYSTEM
请求服务器标识自身。服务器返回一个只有一行的结果集,包含三个字段:
- systemid
标识集簇的唯一系统标识符。可用于检查初始化备库所用的基础备份是否来自同一个集簇。
- timeline
当前 TimelineID。也可用于检查备库是否与主库一致。
- xlogpos
当前 xlog 刷盘位置。可用于获取事务日志中一个已知的位置,以便从该处开始流式传输。
- START_REPLICATION
XXX/XXX 指示服务器开始流式传输 WAL,从 WAL 位置
XXX/XXX开始。服务器可能回复错误,例如所请求的 WAL 段已被回收。成功时,服务器会回复一条 CopyBothResponse 消息,然后开始向前端流式传输 WAL。WAL 将持续流式传输,直到连接断开为止;不会再接受其他命令。WAL 数据以一系列 CopyData 消息发送。(这样可以混合发送其他信息;尤其是服务器在开始流式传输后遇到故障时,可以发送 ErrorResponse 消息。)每条 CopyData 消息的有效载荷遵循以下格式:
- XLogData (B)
- Byte1('w')
标识此消息为 WAL 数据。
- Byte8
本消息中 WAL 数据的起始点,以 XLogRecPtr 格式给出。
- Byte8
服务器上 WAL 的当前末尾,以 XLogRecPtr 格式给出。
- Byte8
传输时服务器的系统时钟,以 TimestampTz 格式给出。
- Byte
n WAL 数据流的一段。
单条 WAL 记录绝不会拆分到两条 CopyData 消息中。当一条 WAL 记录跨越 WAL 页边界(因而已经用继续记录拆分)时,它可以在页边界处拆分。换句话说,第一条主 WAL 记录与它的继续记录可以在不同的 CopyData 消息中发送。
注意,WAL 数据内部以及上面描述的头部中的所有字段,都采用发送服务器的本机格式。字节序和时间戳的格式是不可预测的,除非接收方已验证发送方的系统标识符与自己
pg_control中的内容一致。如果 WAL 发送进程正常终止(postmaster 关闭期间),它会在退出前发送一条 CommandComplete 消息。当然,异常关闭时可能不会发生这种情况。
接收进程可以随时使用以下消息格式之一回复发送端(同样放在 CopyData 消息的有效载荷中):
- 备库状态更新 (F)
- Byte1('r')
将该消息标识为接收端状态更新。
- Byte8
备库上已接收并写入磁盘的最后一个 WAL 字节 + 1 的位置,以 XLogRecPtr 格式给出。
- Byte8
备库上已刷出到磁盘的最后一个 WAL 字节 + 1 的位置,以 XLogRecPtr 格式给出。
- Byte8
备库上已应用的最后一个 WAL 字节 + 1 的位置,以 XLogRecPtr 格式给出。
- Byte8
传输时服务器的系统时钟,以 TimestampTz 格式给出。
- 热备反馈消息 (F)
- Byte1('h')
将该消息标识为热备反馈消息。
- Byte8
传输时服务器的系统时钟,以 TimestampTz 格式给出。
- Byte4
备库当前的 xmin。如果备库发送通知说此连接将不再发送热备反馈,则该值可能为 0。之后的非零消息可以重新启动反馈机制。
- Byte4
备库当前的纪元。
- BASE_BACKUP [
LABEL'label'] [PROGRESS] [FAST] [WAL] [NOWAIT] 指示服务器开始流式传输基础备份。在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。接受以下选项:
LABEL'label'设置备份的标签。如果未指定,则将使用
base backup作为备份标签。标签的引号使用规则与打开standard_conforming_strings的标准SQL字符串相同。PROGRESS请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小,可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的,可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。由于备份期间数据库文件可能会发生变化,因此大小仅为近似值,在估算与实际发送文件之间的这段时间里可能会增长或缩小。
FAST请求快速检查点。
WAL在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的
pg_xlog目录中。NOWAIT默认情况下,备份会等待最后一个必需的 WAL 段完成归档;如果未启用日志归档,则发出警告。指定
NOWAIT会同时禁用等待和警告,由客户端负责确保所需日志可用。
备份开始时,服务器首先发送两个普通结果集,然后发送一个或多个 CopyResponse 结果。
第一个普通结果集包含备份的起始位置,以 XLogRecPtr 格式作为单行单列给出。
第二个普通结果集中的每个表空间都有一行。这一行中的字段是:
- spcoid
表空间的 OID,如果是基础目录则为
NULL。- spclocation
表空间目录的完整路径,如果是基础目录则为
NULL。- size
如果请求了进度报告,则为表空间的大致大小;否则为
NULL。
第二个普通结果集之后,将发送一个或多个 CopyResponse 结果,PGDATA 一个,除
pg_default和pg_global之外的每个表空间各一个。CopyResponse 结果中的数据是表空间内容的 tar 格式(遵循 POSIX 1003.1-2008 标准规定的“ustar 交换格式”)转储,但省略了标准中规定的结尾两个全零块。tar 数据完成后,会发送最后一个普通结果集。数据目录和每个表空间的tar归档将包含目录中的所有文件,无论它们是PostgreSQL文件还是添加到同一目录的其他文件。唯一排除的文件是:
postmaster.pidpostmaster.optspg_xlog,包括子目录。如果备份时包含了 WAL 文件,则会包含一个合成的 pg_xlog 版本,但其中只包含使备份能够工作所必需的文件,而不包含其余内容。
如果服务器上的底层文件系统支持,则会设置属主、组和文件模式。
所有表空间发送完毕后,会发送最后一个常规结果集。该结果集包含备份的结束位置,以 XLogRecPtr 格式作为单行单列给出。