mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-03 04:26:52 +02:00
Make tablesync worker exit when apply dies while it was waiting for it
This avoids "orphaned" sync workers. This was caused by a thinko in wait_for_sync_status_change. Author: Petr Jelinek <petr.jelinek@2ndquadrant.com> Reported-by: Masahiko Sawada <sawada.mshk@gmail.com>
This commit is contained in:
parent
34aebcf42a
commit
3c9bc2157a
@ -146,7 +146,12 @@ finish_sync_worker(void)
|
|||||||
/*
|
/*
|
||||||
* Wait until the table synchronization change.
|
* Wait until the table synchronization change.
|
||||||
*
|
*
|
||||||
* Returns false if the relation subscription state disappeared.
|
* If called from apply worker, it will wait for the synchronization worker to
|
||||||
|
* change table state in shmem. If called from synchronization worker, it
|
||||||
|
* will wait for apply worker to change table state in shmem.
|
||||||
|
*
|
||||||
|
* Returns false if the opposite worker has disappeared or the table state has
|
||||||
|
* been reset.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
wait_for_sync_status_change(Oid relid, char origstate)
|
wait_for_sync_status_change(Oid relid, char origstate)
|
||||||
@ -161,14 +166,27 @@ wait_for_sync_status_change(Oid relid, char origstate)
|
|||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
|
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
|
||||||
|
|
||||||
|
/* Check if the opposite worker is still running and bail if not. */
|
||||||
worker = logicalrep_worker_find(MyLogicalRepWorker->subid,
|
worker = logicalrep_worker_find(MyLogicalRepWorker->subid,
|
||||||
relid, false);
|
am_tablesync_worker() ? InvalidOid : relid,
|
||||||
|
false);
|
||||||
if (!worker)
|
if (!worker)
|
||||||
{
|
{
|
||||||
LWLockRelease(LogicalRepWorkerLock);
|
LWLockRelease(LogicalRepWorkerLock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If I'm the synchronization worker, look at my own state. Otherwise
|
||||||
|
* look at the state of the synchronization worker we found above.
|
||||||
|
*/
|
||||||
|
if (am_tablesync_worker())
|
||||||
|
worker = MyLogicalRepWorker;
|
||||||
|
|
||||||
|
Assert(worker->relid == relid);
|
||||||
state = worker->relstate;
|
state = worker->relstate;
|
||||||
|
|
||||||
LWLockRelease(LogicalRepWorkerLock);
|
LWLockRelease(LogicalRepWorkerLock);
|
||||||
|
|
||||||
if (state == SUBREL_STATE_UNKNOWN)
|
if (state == SUBREL_STATE_UNKNOWN)
|
||||||
@ -179,7 +197,7 @@ wait_for_sync_status_change(Oid relid, char origstate)
|
|||||||
|
|
||||||
rc = WaitLatch(&MyProc->procLatch,
|
rc = WaitLatch(&MyProc->procLatch,
|
||||||
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
|
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
|
||||||
10000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
|
1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
|
||||||
|
|
||||||
/* emergency bailout if postmaster has died */
|
/* emergency bailout if postmaster has died */
|
||||||
if (rc & WL_POSTMASTER_DEATH)
|
if (rc & WL_POSTMASTER_DEATH)
|
||||||
|
Loading…
Reference in New Issue
Block a user