1
0
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:
Peter Eisentraut
2017-08-04 21:14:35 -04:00
parent ff98a5e1e4
commit 7e174fa793
5 changed files with 117 additions and 6 deletions

View File

@ -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;
}