他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

49.9. ロジカルデコーディングための大規模トランザクションのストリーミング

基本的な出力プラグインコールバック(begin_cbchange_cbcommit_cbmessage_cbなど)は、トランザクションが実際にコミットしたときにのみ呼び出されます。 変更はトランザクションログからデコードされますが、コミット時に出力プラグインに渡されるだけです(トランザクションがアボートした場合は破棄されます)。

つまり、デコードは増分的に行われ、メモリー使用量を制御するためにディスクにオーバーフローする場合がありますが、デコードされたすべての変更は、トランザクションが最終的にコミットされたとき(より正確には、コミットがトランザクションログからデコードされたとき)に送信される必要があります。 トランザクションおよびネットワーク帯域幅のサイズによっては、転送時間によって適用ラグが大幅に増加する場合があります。

大規模なトランザクションによって発生する適用遅延を軽減するために、出力プラグインは、継続中のトランザクションの増分ストリーミングをサポートする追加のコールバックを提供できます。 複数の必要なストリーミングコールバック(stream_start_cbstream_stop_cbstream_abort_cbstream_commit_cbおよびstream_change_cb)と2つのオプションのコールバック(stream_message_cbおよびstream_truncate_cb)があります。

継続中のトランザクションをストリーミングする場合、変更(およびメッセージ)はstream_start_cbおよびstream_stop_cbコールバックで区切られたブロックでストリーミングされます。 デコードされたすべての変更が送信されると、トランザクションはstream_commit_cbコールバックを使用してコミットできます(またはstream_abort_cbコールバックを使用してアボートできます)。 2相コミットがサポートされている場合、トランザクションはstream_prepare_cbコールバックを使用して準備できます。 COMMIT PREPAREDcommit_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

stream_commit_cb(...);  <-- commit of the streamed transaction

もちろん、実際のコールバック呼び出しのシーケンスはもっと複雑かもしれません。 ストリーム化された複数のトランザクションにブロックがあったり、一部のトランザクションがアボートされたりするなどです。

ディスクへのスピル動作と同様に、ストリーミングは、WALからデコードされた変更の合計量(すべての継続中のトランザクションについて)がlogical_decoding_work_mem設定で定義された制限を超えたときにトリガされます。 その時点で、最大のトップレベルトランザクション(デコードされた変更に現在使用されているメモリ量で測定されます)が選択され、ストリーミングされます。 ただし、場合によっては、ストリーミングが有効になっていても、メモリしきい値を超えても完全なタプルがまだデコードされていない(例えば、メインテーブルの挿入ではなくトーストテーブルの挿入のみがデコードされているなど)ため、ディスクへのスピルが必要になることがあります。

大規模なトランザクションをストリーミングする場合でも、変更はコミット順に適用され、非ストリーミングモードと同じ保証が維持されます。