mirror of
https://github.com/postgres/postgres.git
synced 2025-10-19 15:49:24 +03:00
Allow altering of two_phase option of a SUBSCRIPTION.
The two_phase option is controlled by both the publisher (as a slot option) and the subscriber (as a subscription option), so the slot option must also be modified. Changing the 'two_phase' option for a subscription from 'true' to 'false' is permitted only when there are no pending prepared transactions corresponding to that subscription. Otherwise, the changes of already prepared transactions can be replicated again along with their corresponding commit leading to duplicate data or errors. To avoid data loss, the 'two_phase' option for a subscription can only be changed from 'false' to 'true' once the initial data synchronization is completed. Therefore this is performed later by the logical replication worker. Author: Hayato Kuroda, Ajin Cherian, Amit Kapila Reviewed-by: Peter Smith, Hou Zhijie, Amit Kapila, Vitaly Davydov, Vignesh C Discussion: https://postgr.es/m/8fab8-65d74c80-1-2f28e880@39088166
This commit is contained in:
@@ -401,9 +401,6 @@ static void apply_handle_tuple_routing(ApplyExecutionData *edata,
|
||||
LogicalRepTupleData *newtup,
|
||||
CmdType operation);
|
||||
|
||||
/* Compute GID for two_phase transactions */
|
||||
static void TwoPhaseTransactionGid(Oid subid, TransactionId xid, char *gid, int szgid);
|
||||
|
||||
/* Functions for skipping changes */
|
||||
static void maybe_start_skipping_changes(XLogRecPtr finish_lsn);
|
||||
static void stop_skipping_changes(void);
|
||||
@@ -3911,7 +3908,7 @@ maybe_reread_subscription(void)
|
||||
/* !slotname should never happen when enabled is true. */
|
||||
Assert(newsub->slotname);
|
||||
|
||||
/* two-phase should not be altered */
|
||||
/* two-phase cannot be altered while the worker is running */
|
||||
Assert(newsub->twophasestate == MySubscription->twophasestate);
|
||||
|
||||
/*
|
||||
@@ -4396,24 +4393,6 @@ cleanup_subxact_info()
|
||||
subxact_data.nsubxacts_max = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Form the prepared transaction GID for two_phase transactions.
|
||||
*
|
||||
* Return the GID in the supplied buffer.
|
||||
*/
|
||||
static void
|
||||
TwoPhaseTransactionGid(Oid subid, TransactionId xid, char *gid, int szgid)
|
||||
{
|
||||
Assert(subid != InvalidRepOriginId);
|
||||
|
||||
if (!TransactionIdIsValid(xid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
||||
errmsg_internal("invalid two-phase transaction ID")));
|
||||
|
||||
snprintf(gid, szgid, "pg_gid_%u_%u", subid, xid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common function to run the apply loop with error handling. Disable the
|
||||
* subscription, if necessary.
|
||||
@@ -5014,7 +4993,7 @@ AtEOXact_LogicalRepWorkers(bool isCommit)
|
||||
List *workers;
|
||||
ListCell *lc2;
|
||||
|
||||
workers = logicalrep_workers_find(subid, true);
|
||||
workers = logicalrep_workers_find(subid, true, false);
|
||||
foreach(lc2, workers)
|
||||
{
|
||||
LogicalRepWorker *worker = (LogicalRepWorker *) lfirst(lc2);
|
||||
|
Reference in New Issue
Block a user