mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Only kill sync workers at commit time in subscription DDL
This allows a transaction abort to avoid killing those workers. Author: Petr Jelinek <petr.jelinek@2ndquadrant.com>
This commit is contained in:
@ -73,6 +73,14 @@ typedef struct LogicalRepCtxStruct
|
||||
|
||||
LogicalRepCtxStruct *LogicalRepCtx;
|
||||
|
||||
typedef struct LogicalRepWorkerId
|
||||
{
|
||||
Oid subid;
|
||||
Oid relid;
|
||||
} LogicalRepWorkerId;
|
||||
|
||||
static List *on_commit_stop_workers = NIL;
|
||||
|
||||
static void ApplyLauncherWakeup(void);
|
||||
static void logicalrep_launcher_onexit(int code, Datum arg);
|
||||
static void logicalrep_worker_onexit(int code, Datum arg);
|
||||
@ -249,6 +257,30 @@ logicalrep_worker_find(Oid subid, Oid relid, bool only_running)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to logicalrep_worker_find(), but returns list of all workers for
|
||||
* the subscription, instead just one.
|
||||
*/
|
||||
List *
|
||||
logicalrep_workers_find(Oid subid, bool only_running)
|
||||
{
|
||||
int i;
|
||||
List *res = NIL;
|
||||
|
||||
Assert(LWLockHeldByMe(LogicalRepWorkerLock));
|
||||
|
||||
/* Search for attached worker for a given subscription id. */
|
||||
for (i = 0; i < max_logical_replication_workers; i++)
|
||||
{
|
||||
LogicalRepWorker *w = &LogicalRepCtx->workers[i];
|
||||
|
||||
if (w->in_use && w->subid == subid && (!only_running || w->proc))
|
||||
res = lappend(res, w);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start new apply background worker.
|
||||
*/
|
||||
@ -513,6 +545,27 @@ logicalrep_worker_stop(Oid subid, Oid relid)
|
||||
LWLockRelease(LogicalRepWorkerLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Request worker for specified sub/rel to be stopped on commit.
|
||||
*/
|
||||
void
|
||||
logicalrep_worker_stop_at_commit(Oid subid, Oid relid)
|
||||
{
|
||||
LogicalRepWorkerId *wid;
|
||||
MemoryContext oldctx;
|
||||
|
||||
/* Make sure we store the info in context that survives until commit. */
|
||||
oldctx = MemoryContextSwitchTo(TopTransactionContext);
|
||||
|
||||
wid = palloc(sizeof(LogicalRepWorkerId));
|
||||
wid->subid = subid;
|
||||
wid->relid = relid;
|
||||
|
||||
on_commit_stop_workers = lappend(on_commit_stop_workers, wid);
|
||||
|
||||
MemoryContextSwitchTo(oldctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up (using latch) any logical replication worker for specified sub/rel.
|
||||
*/
|
||||
@ -753,15 +806,41 @@ ApplyLauncherShmemInit(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether current transaction has manipulated logical replication
|
||||
* workers.
|
||||
*/
|
||||
bool
|
||||
XactManipulatesLogicalReplicationWorkers(void)
|
||||
{
|
||||
return (on_commit_stop_workers != NIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wakeup the launcher on commit if requested.
|
||||
*/
|
||||
void
|
||||
AtEOXact_ApplyLauncher(bool isCommit)
|
||||
{
|
||||
if (isCommit && on_commit_launcher_wakeup)
|
||||
ApplyLauncherWakeup();
|
||||
if (isCommit)
|
||||
{
|
||||
ListCell *lc;
|
||||
|
||||
foreach (lc, on_commit_stop_workers)
|
||||
{
|
||||
LogicalRepWorkerId *wid = lfirst(lc);
|
||||
logicalrep_worker_stop(wid->subid, wid->relid);
|
||||
}
|
||||
|
||||
if (on_commit_launcher_wakeup)
|
||||
ApplyLauncherWakeup();
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to pfree on_commit_stop_workers. It was allocated in
|
||||
* transaction memory context, which is going to be cleaned soon.
|
||||
*/
|
||||
on_commit_stop_workers = NIL;
|
||||
on_commit_launcher_wakeup = false;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user