Datum
bdr_apply_pause(PG_FUNCTION_ARGS)
{
+ /*
+ * It's safe to pause without grabbing the segment lock;
+ * an overlapping resume won't do any harm.
+ */
BdrWorkerCtl->pause_apply = true;
PG_RETURN_VOID();
}
Datum
bdr_apply_resume(PG_FUNCTION_ARGS)
{
+ int i;
+
+ LWLockAcquire(BdrWorkerCtl->lock, LW_SHARED);
BdrWorkerCtl->pause_apply = false;
+
+ /*
+ * To get apply workers to notice immediately we have to set all their
+ * latches. This will also force config reloads, but that's cheap and
+ * harmless.
+ */
+ for (i = 0; i < bdr_max_workers; i++)
+ {
+ BdrWorker *w = &BdrWorkerCtl->slots[i];
+ if (w->worker_type == BDR_WORKER_APPLY)
+ {
+ BdrApplyWorker *apply = &w->data.apply;
+ SetLatch(apply->proclatch);
+ }
+ }
+
+ LWLockRelease(BdrWorkerCtl->lock);
PG_RETURN_VOID();
}
* flag in shmem. We don't pause until the end of the current
* transaction, to avoid sleeping with locks held.
*
- * XXX With the 1s timeout below, we don't risk delaying the
- * resumption too much. But it would be better to use a global
- * latch that can be set by pg_bdr_apply_resume(), and not have
- * to wake up so often.
+ * Sleep for 5 minutes before re-checking. We shouldn't really
+ * need to since we set the proc latch on resume, but it doesn't
+ * hurt to be careful.
*/
-
while (BdrWorkerCtl->pause_apply && !IsTransactionState())
{
ResetLatch(&MyProc->procLatch);
rc = WaitLatch(&MyProc->procLatch,
WL_TIMEOUT | WL_LATCH_SET | WL_POSTMASTER_DEATH,
- 1000L);
+ 300000L);
if (rc & WL_POSTMASTER_DEATH)
proc_exit(1);
\ccc regression
invalid command \ccc
INSERT INTO pause_test(x) VALUES ('after resume');
+-- The pause latch timeout is 5 minutes. To make sure that setting
+-- the latch is doing its job and unpausing before timeout, expect
+-- resume to take effect well before then.
+BEGIN;
+SET LOCAL statement_timeout = '60s';
SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
pg_xlog_wait_remote_apply
---------------------------
(1 row)
+COMMIT;
\cc postgres
invalid command \cc
-- Must see all three rows
\ccc regression
INSERT INTO pause_test(x) VALUES ('after resume');
+
+-- The pause latch timeout is 5 minutes. To make sure that setting
+-- the latch is doing its job and unpausing before timeout, expect
+-- resume to take effect well before then.
+BEGIN;
+SET LOCAL statement_timeout = '60s';
SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
+COMMIT;
\cc postgres