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
This commit is contained in:
parent
0d1a33438d
commit
4778826532
@ -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
|
executed within that transaction. A transaction that is prepared for
|
||||||
a two-phase commit using <command>PREPARE TRANSACTION</command> will
|
a two-phase commit using <command>PREPARE TRANSACTION</command> will
|
||||||
also be decoded if the output plugin callbacks needed for decoding
|
also be decoded if the output plugin callbacks needed for decoding
|
||||||
them are provided. It is possible that the current transaction which
|
them are provided. It is possible that the current prepared transaction
|
||||||
is being decoded is aborted concurrently via a <command>ROLLBACK PREPARED</command>
|
which is being decoded is aborted concurrently via a
|
||||||
command. In that case, the logical decoding of this transaction will
|
<command>ROLLBACK PREPARED</command> command. In that case, the logical
|
||||||
be aborted too. We will skip all the changes of such a transaction once
|
decoding of this transaction will be aborted too. All the changes of such
|
||||||
the abort is detected and abort the transaction when we read WAL for
|
a transaction are skipped once the abort is detected and the
|
||||||
<command>ROLLBACK PREPARED</command>.
|
<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>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
|
@ -2664,6 +2664,14 @@ ReorderBufferPrepare(ReorderBuffer *rb, TransactionId xid,
|
|||||||
|
|
||||||
ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn,
|
ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn,
|
||||||
txn->commit_time, txn->origin_id, txn->origin_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user