diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2017-06-03 09:18:52 -0400 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2017-06-03 09:20:56 -0400 |
commit | 3c9bc2157a4f465b3c070d1250597568d2dc285f (patch) | |
tree | b2d5d9831852365bb6e2a08141ffdbb8665ecf71 /src | |
parent | 34aebcf42a70089b76ff8e9ccda331f111153eeb (diff) | |
download | postgresql-3c9bc2157a4f465b3c070d1250597568d2dc285f.tar.gz postgresql-3c9bc2157a4f465b3c070d1250597568d2dc285f.zip |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/replication/logical/tablesync.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index 85e480db4bd..6e268f3521d 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -146,7 +146,12 @@ finish_sync_worker(void) /* * 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 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(); LWLockAcquire(LogicalRepWorkerLock, LW_SHARED); + + /* Check if the opposite worker is still running and bail if not. */ worker = logicalrep_worker_find(MyLogicalRepWorker->subid, - relid, false); + am_tablesync_worker() ? InvalidOid : relid, + false); if (!worker) { LWLockRelease(LogicalRepWorkerLock); 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; + LWLockRelease(LogicalRepWorkerLock); if (state == SUBREL_STATE_UNKNOWN) @@ -179,7 +197,7 @@ wait_for_sync_status_change(Oid relid, char origstate) rc = WaitLatch(&MyProc->procLatch, 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 */ if (rc & WL_POSTMASTER_DEATH) |