基本输出插件回调(例如 begin_cb、 change_cb、commit_cb 和 message_cb)只会在事务实际提交时被调用。更改仍然会 从事务日志中解码出来,但只有在提交时才会传给输出插件(如果事务中止,则 会被丢弃)。
这意味着,虽然解码是增量进行的,并且可能会溢写到磁盘以便控制内存使用,但 当事务最终提交时(更准确地说,当从事务日志中解码到该提交时),所有已解 码的更改都必须被传输出去。根据事务大小和网络带宽,传输时间可能会显著增 加应用滞后。
为了减少大事务造成的应用滞后,输出插件可以提供额外的回调,以支持对进行中 事务进行增量流式传送。必需的流式传送回调有多个: stream_start_cb、 stream_stop_cb、 stream_abort_cb、 stream_commit_cb 和 stream_change_cb;另有两个可选回调: stream_message_cb 和 stream_truncate_cb。
在流式传送进行中事务时,更改(以及消息)会按由 stream_start_cb 和 stream_stop_cb 回调界定的块进行传送。一旦所有解码出 的更改都已传输,事务就可以通过 stream_commit_cb 回调来提交(或者可能通过 stream_abort_cb 回调来中止)。
某个事务的一组流式回调调用示例可能如下:
stream_start_cb(...); <-- start of first block of changes stream_change_cb(...); stream_change_cb(...); stream_message_cb(...); stream_change_cb(...); ... stream_change_cb(...); stream_stop_cb(...); <-- end of first block of changes stream_start_cb(...); <-- start of second block of changes stream_change_cb(...); stream_change_cb(...); stream_change_cb(...); ... stream_message_cb(...); stream_change_cb(...); stream_stop_cb(...); <-- end of second block of changes stream_commit_cb(...); <-- commit of the streamed transaction
当然,回调调用的实际顺序可能会更复杂。可能会有多个流式事务的块,其中一 些事务也可能会被中止,等等。
与溢写到磁盘的行为类似,当从 WAL 中解码出的更改总量(针对所有进行中事 务)超过 logical_decoding_work_mem 设置定义的限制 时,就会触发流式传送。此时,会选择最大的顶层事务(按当前用于已解码更改 的内存量衡量)并进行流式传送。不过,在某些情况下,即使启用了流式传送, 我们仍然必须溢写到磁盘,因为虽然超过了内存阈值,但还没有解码出完整的元 组,例如只解码了 toast 表插入,而没有解码主表插入。
即使在流式处理大事务时,更改仍然会按提交顺序应用,从而保留与非流式模式 相同的保证。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。