mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Skip empty transaction stream in test_decoding.
We were decoding empty transactions via streaming APIs added in commit
45fdc9738b
even when the user used the option 'skip-empty-xacts'. The APIs
makes no effort to skip empty xacts under the assumption that we will
never try to stream such transactions. However, that is not true because
we can pick to stream a transaction that has change messages for
REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT and we don't send such messages to
downstream rather they are just to update the internal state. So, we need
to skip such xacts when plugin uses the option 'skip-empty-xacts'.
Diagnosed-By: Amit Kapila
Author: Dilip Kumar
Reviewed-by: Amit Kapila
Discussion: https://postgr.es/m/CAA4eK1+OqgFNZkf7=ETe_y5ntjgDk3T0wcdkd4Sot_u1hySGfw@mail.gmail.com
This commit is contained in:
@ -64,6 +64,10 @@ static void pg_decode_message(LogicalDecodingContext *ctx,
|
||||
Size sz, const char *message);
|
||||
static void pg_decode_stream_start(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn);
|
||||
static void pg_output_stream_start(LogicalDecodingContext *ctx,
|
||||
TestDecodingData *data,
|
||||
ReorderBufferTXN *txn,
|
||||
bool last_write);
|
||||
static void pg_decode_stream_stop(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn);
|
||||
static void pg_decode_stream_abort(LogicalDecodingContext *ctx,
|
||||
@ -583,34 +587,38 @@ pg_decode_message(LogicalDecodingContext *ctx,
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* We never try to stream any empty xact so we don't need any special handling
|
||||
* for skip_empty_xacts in streaming mode APIs.
|
||||
*/
|
||||
static void
|
||||
pg_decode_stream_start(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn)
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
data->xact_wrote_changes = false;
|
||||
if (data->skip_empty_xacts)
|
||||
return;
|
||||
pg_output_stream_start(ctx, data, txn, true);
|
||||
}
|
||||
|
||||
static void
|
||||
pg_output_stream_start(LogicalDecodingContext *ctx, TestDecodingData *data, ReorderBufferTXN *txn, bool last_write)
|
||||
{
|
||||
OutputPluginPrepareWrite(ctx, last_write);
|
||||
if (data->include_xids)
|
||||
appendStringInfo(ctx->out, "opening a streamed block for transaction TXN %u", txn->xid);
|
||||
else
|
||||
appendStringInfo(ctx->out, "opening a streamed block for transaction");
|
||||
OutputPluginWrite(ctx, true);
|
||||
OutputPluginWrite(ctx, last_write);
|
||||
}
|
||||
|
||||
/*
|
||||
* We never try to stream any empty xact so we don't need any special handling
|
||||
* for skip_empty_xacts in streaming mode APIs.
|
||||
*/
|
||||
static void
|
||||
pg_decode_stream_stop(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn)
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
if (data->skip_empty_xacts && !data->xact_wrote_changes)
|
||||
return;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
if (data->include_xids)
|
||||
appendStringInfo(ctx->out, "closing a streamed block for transaction TXN %u", txn->xid);
|
||||
@ -619,10 +627,6 @@ pg_decode_stream_stop(LogicalDecodingContext *ctx,
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* We never try to stream any empty xact so we don't need any special handling
|
||||
* for skip_empty_xacts in streaming mode APIs.
|
||||
*/
|
||||
static void
|
||||
pg_decode_stream_abort(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn,
|
||||
@ -630,6 +634,9 @@ pg_decode_stream_abort(LogicalDecodingContext *ctx,
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
if (data->skip_empty_xacts && !data->xact_wrote_changes)
|
||||
return;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
if (data->include_xids)
|
||||
appendStringInfo(ctx->out, "aborting streamed (sub)transaction TXN %u", txn->xid);
|
||||
@ -638,10 +645,6 @@ pg_decode_stream_abort(LogicalDecodingContext *ctx,
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* We never try to stream any empty xact so we don't need any special handling
|
||||
* for skip_empty_xacts in streaming mode APIs.
|
||||
*/
|
||||
static void
|
||||
pg_decode_stream_commit(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn,
|
||||
@ -649,6 +652,9 @@ pg_decode_stream_commit(LogicalDecodingContext *ctx,
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
if (data->skip_empty_xacts && !data->xact_wrote_changes)
|
||||
return;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
|
||||
if (data->include_xids)
|
||||
@ -676,6 +682,13 @@ pg_decode_stream_change(LogicalDecodingContext *ctx,
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
/* output stream start if we haven't yet */
|
||||
if (data->skip_empty_xacts && !data->xact_wrote_changes)
|
||||
{
|
||||
pg_output_stream_start(ctx, data, txn, false);
|
||||
}
|
||||
data->xact_wrote_changes = true;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
if (data->include_xids)
|
||||
appendStringInfo(ctx->out, "streaming change for TXN %u", txn->xid);
|
||||
@ -722,6 +735,12 @@ pg_decode_stream_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
if (data->skip_empty_xacts && !data->xact_wrote_changes)
|
||||
{
|
||||
pg_output_stream_start(ctx, data, txn, false);
|
||||
}
|
||||
data->xact_wrote_changes = true;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
if (data->include_xids)
|
||||
appendStringInfo(ctx->out, "streaming truncate for TXN %u", txn->xid);
|
||||
|
Reference in New Issue
Block a user