# 49.9.用于逻辑解码的大型事务流

基本输出插件回调(例如。,开始,改变,承诺信息_cb)仅在事务实际提交时调用。更改仍然从事务日志中解码,但仅在提交时传递给输出插件(如果事务中止,则丢弃)。

这意味着,虽然解码以增量方式进行,并可能溢出到磁盘以控制内存使用,但当事务最终提交时(或者更准确地说,当从事务日志中解码提交时),必须传输所有解码的更改。根据事务的大小和网络带宽,传输时间可能会显著增加应用延迟。

为了减少大型事务导致的应用延迟,输出插件可以提供额外的回调,以支持正在进行的事务的增量流。有多个必需的流式回调(流\u开始\u cb,流_停止_cb,流_中止_cb,流_提交_cb流_变化_cb)和两个可选回调(流消息流_截断_cb).

流式传输正在进行的事务时,更改(和消息)以块的形式流式传输,块由流\u开始\u cb流_停止_cb回电。一旦传输了所有解码的更改,就可以使用流_提交_cb回调(或可能使用流_中止_cb回调)。如果支持两阶段提交,则可以使用流_准备_cb回拨,做好准备使用提交_准备_cb使用回滚\u准备\u 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解码的更改总量(对于所有正在进行的事务)超过逻辑解码工作记忆背景此时,选择并流式传输最大的顶级事务(通过当前用于解码更改的内存量来衡量)。然而,在某些情况下,即使启用了流媒体,我们仍然必须溢出到磁盘,因为我们超过了内存阈值,但仍然没有解码完整的元组,例如,只有解码的toast表插入,但没有主表插入。

即使在流式处理大型事务时,更改仍按提交顺序应用,保留与非流式处理模式相同的保证。