Commit 47788265 authored by Amit Kapila's avatar Amit Kapila

Ensure to send a prepare after we detect concurrent abort during decoding.

It is possible that while decoding a prepared transaction, it gets aborted
concurrently via a ROLLBACK PREPARED command. In that case, we were
skipping all the changes and directly sending Rollback Prepared when we
find the same in WAL. However, the downstream has no idea of the GID of
such a transaction. So, ensure to send prepare even when a concurrent
abort is detected.

Author: Ajin Cherian
Reviewed-by: Markus Wanner, Amit Kapila
Discussion: https://postgr.es/m/f82133c6-6055-b400-7922-97dae9f2b50b@enterprisedb.com
parent 0d1a3343
......@@ -545,12 +545,15 @@ CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
executed within that transaction. A transaction that is prepared for
a two-phase commit using <command>PREPARE TRANSACTION</command> will
also be decoded if the output plugin callbacks needed for decoding
them are provided. It is possible that the current transaction which
is being decoded is aborted concurrently via a <command>ROLLBACK PREPARED</command>
command. In that case, the logical decoding of this transaction will
be aborted too. We will skip all the changes of such a transaction once
the abort is detected and abort the transaction when we read WAL for
<command>ROLLBACK PREPARED</command>.
them are provided. It is possible that the current prepared transaction
which is being decoded is aborted concurrently via a
<command>ROLLBACK PREPARED</command> command. In that case, the logical
decoding of this transaction will be aborted too. All the changes of such
a transaction are skipped once the abort is detected and the
<function>prepare_cb</function> callback is invoked. Thus even in case of
a concurrent abort, enough information is provided to the output plugin
for it to properly deal with <command>ROLLBACK PREPARED</command> once
that is decoded.
</para>
<note>
......
......@@ -2664,6 +2664,14 @@ ReorderBufferPrepare(ReorderBuffer *rb, TransactionId xid,
ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn,
txn->commit_time, txn->origin_id, txn->origin_lsn);
/*
* We send the prepare for the concurrently aborted xacts so that later
* when rollback prepared is decoded and sent, the downstream should be
* able to rollback such a xact. See comments atop DecodePrepare.
*/
if (txn->concurrent_abort)
rb->prepare(rb, txn, txn->final_lsn);
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment