51.3. 流复制协议
要启动流复制,前端在启动消息中发送replication参数。一个布尔值true会告诉后端进入到walsender模式,在其中一小组复制命令而不是SQL命令可以被发出。只有简单查询协议可以在walsender模式中使用。在启用log_replication_commands时,服务器日志中会记录复制命令。传递database作为值指示 walsender 连接到dbname参数指定的数据库,这将允许该连接被用于来自哪个数据库的逻辑复制。
出于测试复制命令的目的,你可以通过psql或者任何使用libpq的工具使用包含replication选项的连接字符串建立一个复制连接,例如:
psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
不过更常用的是:pg_receivexlog(对于物理复制)或者pg_recvlogical(对于逻辑复制)。
在walsender模式中可以接受的命令有:
- IDENTIFY_SYSTEM
-
请求服务器标识它自己。服务器以一个行构成的结果集作为答复,其中包含四个域:
- systemid (text)
标识该集簇的唯一的系统标识符。这可以被用来检查用于初始化后备机的基础备份是否来自于同一个集簇。
- timeline (int4)
当前的时间线 ID。也对于检查后备机是否与主控机一致有用。
- xlogpos (text)
当前的 xlog 刷写位置。用于得到一个在事务日志中的已知位置作为流的开始位置。
- dbname (text)
要连接到的数据库或者空。
- TIMELINE_HISTORY tli
-
请求服务器将时间线tli的历史文件发送过来。服务器将以一行组成的结果集作为答复,其中包含两个域:
- filename (text)
时间线历史文件的文件名,例如00000002.history。
- content (bytea)
时间线历史文件的内容。
- CREATE_REPLICATION_SLOT slot_name { PHYSICAL [ RESERVE_WAL ] | LOGICAL output_plugin }
-
创建一个物理的或者逻辑的复制槽。更多关于复制槽的内容请见 第 26.2.6 节。
- slot_name
要创建的槽的名称。必须是一个合法的复制槽名称(见 第 26.2.6.1 节)。
- output_plugin
被用于逻辑解码的输出插件的名称(见 第 47.6 节)。
- RESERVE_WAL
指定这个物理复制槽立即保留WAL。否则,只有来自流复制客户端的连接上才会保留WAL。
- 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。如果后备机正在发送通知告知热备机反馈将不再通过此连接发送,这个值可能为0。后来的非0消息将重新启动反馈机制。
- Int32
后备机的当前世代。
- 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
-
删除一个复制槽,释放任何保留的服务器端资源。如果该槽当前正在被一个活动连接使用,这个命令会失败。
- slot_name
要删除的槽的名称。
- 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_xlog目录中。
- NOWAIT
默认情况下,备份会等待直到最后一个要求的 WAL 段被归档,或者当日至归档被禁用时发出一个警告。指定NOWAIT会禁用等待和警告,而让客户端负责确保所要求的日志是可用的。
- MAX_RATE rate
单位时间内从服务器传输到客户端的最大数据量限制。期望的单位是千字节每秒。如果指定了这个选项,值必须等于零或者位于 32 kB到 1 GB(包括)范围之间。如果 0 被传入或者没有指定该选项,对于传输将没有限制。
- TABLESPACE_MAP
在名为tablespace_map的文件中包括有关pg_tblspc目录中存在的符号链接的信息。这个表空间映射文件包括了在目录pg_tblspc中存在的每一个符号链接的名字以及它的完整路径。
当备份被启动,服务器将首先发送两个普通结果集,后面会跟着一个或多个CopyResponse结果。
第一个普通结果集在一行两列中包含了备份的起始位置。第一列包含使用XLogRecPtr格式给出的开始位置,第二列包含相应的时间线ID。
第二个普通结果集中为每一个表空间都有一行。行中的域有:
- spcoid(oid)
表空间的 OID,如果是base目录则为空。
- spclocation(text)
表空间目录的完整路径,如果是base目录则为空。
- size(int8)
如果进度报告被请求,这里是表空间的近似大小,否则为空。
在第二个普通结果集之后,一个或多个CopyResponse结果将被发送,一个用于主数据目录而对每一个除pg_default和pg_global之外的额外表空间也会有一个。CopyResponse结果中的数据将会使一个tar格式(遵循POSIX 1003.1-2008标准中指定的"ustar交换格式")的表空间内容转储,不过标准中定义的两个拖尾全0块将被忽略。在tar数据完成后,一个最终普通结果集将被发送,包含了备份的WAL结束位置,格式与起始位置相同。
用于数据目录和每个表空间的tar归档将包含目录中的所有文件,不管它们是否为PostgreSQL文件或者是被加入的其他文件。唯一被排除的文件是:
postmaster.pid
postmaster.opts
在 PostgreSQL 服务器操作期间创建的多个临时文件
pg_xlog及其子目录。如果备份运行时要求包括WAL文件,一个pg_xlog的合成版本将被包括进来,但是只会包含那些备份工作必需的文件,而不是包含剩下的内容。
pg_replslot被复制为一个空目录。
除常规文件和目录之外的其他文件(例如符号链接和特殊设备文件)会被跳过(pg_tblspc中的符号链接会被保留)。
如果服务器上的底层文件系统支持,所有者、组合文件模式都会被设置。