基本的な出力プラグインコールバック(begin_cb
、change_cb
、commit_cb
、message_cb
など)は、トランザクションが実際にコミットしたときにのみ呼び出されます。
変更はトランザクションログからデコードされますが、コミット時に出力プラグインに渡されるだけです(トランザクションがアボートした場合は破棄されます)。
つまり、デコードは増分的に行われ、メモリ使用量を制御するためにディスクにオーバーフローする場合がありますが、デコードされたすべての変更は、トランザクションが最終的にコミットされたとき(より正確には、コミットがトランザクションログからデコードされたとき)に送信される必要があります。 トランザクションおよびネットワーク帯域幅のサイズによっては、転送時間によって適用ラグが大幅に増加する場合があります。
大規模なトランザクションによって発生する適用遅延を軽減するために、出力プラグインは、継続中のトランザクションの増分ストリーミングをサポートする追加のコールバックを提供できます。
複数の必要なストリーミングコールバック(stream_start_cb
、stream_stop_cb
、stream_abort_cb
、stream_commit_cb
およびstream_change_cb
)と2つのオプションのコールバック(stream_message_cb
およびstream_truncate_cb
)があります。
2相コマンドのストリーミングをサポートする場合は、追加のコールバックを提供する必要があります(詳細は49.10を参照してください)。
継続中のトランザクションをストリーミングする場合、変更(およびメッセージ)はstream_start_cb
およびstream_stop_cb
コールバックで区切られたブロックでストリーミングされます。
デコードされたすべての変更が送信されると、トランザクションはstream_commit_cb
コールバックを使用してコミットできます(またはstream_abort_cb
コールバックを使用してアボートできます)。
2相コミットがサポートされている場合、トランザクションはstream_prepare_cb
コールバックを使用して準備できます。
COMMIT PREPARED
はcommit_prepared_cb
コールバックを使用して準備できます。
またはrollback_prepared_cb
を使用してアボートできます。
1つのトランザクションに対するストリーミングコールバック呼び出しのシーケンスの例は、次のようになります。
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 [a. when using normal commit] stream_commit_cb(...); <-- commit of the streamed transaction [b. when using two-phase commit] stream_prepare_cb(...); <-- prepare the streamed transaction commit_prepared_cb(...); <-- commit of the prepared transaction
もちろん、実際のコールバック呼び出しのシーケンスはもっと複雑かもしれません。 ストリーム化された複数のトランザクションにブロックがあったり、一部のトランザクションがアボートされたりするなどです。
ディスクへのスピル動作と同様に、ストリーミングは、WALからデコードされた変更の合計量(すべての継続中のトランザクションについて)がlogical_decoding_work_mem
設定で定義された制限を超えたときにトリガされます。
その時点で、最大のトップレベルトランザクション(デコードされた変更に現在使用されているメモリ量で測定されます)が選択され、ストリーミングされます。
ただし、場合によっては、ストリーミングが有効になっていても、メモリしきい値を超えても完全なタプルがまだデコードされていない(例えば、メインテーブルの挿入ではなくトーストテーブルの挿入のみがデコードされているなど)ため、ディスクへのスピルが必要になることがあります。
大規模なトランザクションをストリーミングする場合でも、変更はコミット順に適用され、非ストリーミングモードと同じ保証が維持されます。