mirror of
https://github.com/postgres/postgres.git
synced 2025-08-31 17:02:12 +03:00
Add prepare API support for streaming transactions in logical replication.
Commit a8fd13cab0
added support for prepared transactions to built-in
logical replication via a new option "two_phase" for a subscription. The
"two_phase" option was not allowed with the existing streaming option.
This commit permits the combination of "streaming" and "two_phase"
subscription options. It extends the pgoutput plugin and the subscriber
side code to add the prepare API for streaming transactions which will
apply the changes accumulated in the spool-file at prepare time.
Author: Peter Smith and Ajin Cherian
Reviewed-by: Vignesh C, Amit Kapila, Greg Nancarrow
Tested-By: Haiying Tang
Discussion: https://postgr.es/m/02DA5F5E-CECE-4D9C-8B4B-418077E2C010@postgrespro.ru
Discussion: https://postgr.es/m/CAMGcDxeqEpWj3fTXwqhSwBdXd2RS9jzwWscO-XbeCfso6ts3+Q@mail.gmail.com
This commit is contained in:
@@ -1052,6 +1052,56 @@ apply_handle_rollback_prepared(StringInfo s)
|
||||
pgstat_report_activity(STATE_IDLE, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle STREAM PREPARE.
|
||||
*
|
||||
* Logic is in two parts:
|
||||
* 1. Replay all the spooled operations
|
||||
* 2. Mark the transaction as prepared
|
||||
*/
|
||||
static void
|
||||
apply_handle_stream_prepare(StringInfo s)
|
||||
{
|
||||
LogicalRepPreparedTxnData prepare_data;
|
||||
|
||||
if (in_streamed_transaction)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
||||
errmsg_internal("STREAM PREPARE message without STREAM STOP")));
|
||||
|
||||
/* Tablesync should never receive prepare. */
|
||||
if (am_tablesync_worker())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
||||
errmsg_internal("tablesync worker received a STREAM PREPARE message")));
|
||||
|
||||
logicalrep_read_stream_prepare(s, &prepare_data);
|
||||
|
||||
elog(DEBUG1, "received prepare for streamed transaction %u", prepare_data.xid);
|
||||
|
||||
/* Replay all the spooled operations. */
|
||||
apply_spooled_messages(prepare_data.xid, prepare_data.prepare_lsn);
|
||||
|
||||
/* Mark the transaction as prepared. */
|
||||
apply_handle_prepare_internal(&prepare_data);
|
||||
|
||||
CommitTransactionCommand();
|
||||
|
||||
pgstat_report_stat(false);
|
||||
|
||||
store_flush_position(prepare_data.end_lsn);
|
||||
|
||||
in_remote_transaction = false;
|
||||
|
||||
/* unlink the files with serialized changes and subxact info. */
|
||||
stream_cleanup_files(MyLogicalRepWorker->subid, prepare_data.xid);
|
||||
|
||||
/* Process any tables that are being synchronized in parallel. */
|
||||
process_syncing_tables(prepare_data.end_lsn);
|
||||
|
||||
pgstat_report_activity(STATE_IDLE, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle ORIGIN message.
|
||||
*
|
||||
@@ -1291,7 +1341,7 @@ apply_spooled_messages(TransactionId xid, XLogRecPtr lsn)
|
||||
*/
|
||||
oldcxt = MemoryContextSwitchTo(TopTransactionContext);
|
||||
|
||||
/* open the spool file for the committed transaction */
|
||||
/* Open the spool file for the committed/prepared transaction */
|
||||
changes_filename(path, MyLogicalRepWorker->subid, xid);
|
||||
elog(DEBUG1, "replaying changes from file \"%s\"", path);
|
||||
|
||||
@@ -2357,6 +2407,10 @@ apply_dispatch(StringInfo s)
|
||||
case LOGICAL_REP_MSG_ROLLBACK_PREPARED:
|
||||
apply_handle_rollback_prepared(s);
|
||||
return;
|
||||
|
||||
case LOGICAL_REP_MSG_STREAM_PREPARE:
|
||||
apply_handle_stream_prepare(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ereport(ERROR,
|
||||
|
Reference in New Issue
Block a user