From e482f52f792df3685f4f9d955d54e04570db5cc5 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Mon, 4 Sep 2017 13:18:44 +0200 Subject: [PATCH] fix basebackup throttle --- src/backend/replication/basebackup.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 9776858f03..4db79d733c 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -1336,10 +1336,7 @@ _tarWriteDir(const char *pathbuf, int basepathlen, struct stat *statbuf, static void throttle(size_t increment) { - TimeOffset elapsed, - elapsed_min, - sleep; - int wait_result; + TimeOffset elapsed_min; if (throttling_counter < 0) return; @@ -1348,14 +1345,29 @@ throttle(size_t increment) if (throttling_counter < throttling_sample) return; - /* Time elapsed since the last measurement (and possible wake up). */ - elapsed = GetCurrentTimestamp() - throttled_last; - /* How much should have elapsed at minimum? */ - elapsed_min = elapsed_min_unit * (throttling_counter / throttling_sample); - sleep = elapsed_min - elapsed; - /* Only sleep if the transfer is faster than it should be. */ - if (sleep > 0) + /* How much time should have elapsed at minimum? */ + elapsed_min = elapsed_min_unit * + (throttling_counter / throttling_sample); + + /* + * Since the latch could be set repeatedly because of concurrently WAL + * activity, sleep enough times in a loop to ensure enough time has + * passed. + */ + for (;;) { + TimeOffset elapsed, + sleep; + int wait_result; + + /* Time elapsed since the last measurement (and possible wake up). */ + elapsed = GetCurrentTimestamp() - throttled_last; + + /* sleep if the transfer is faster than it should be */ + sleep = elapsed_min - elapsed; + if (sleep <= 0) + break; + ResetLatch(MyLatch); /* We're eating a potentially set latch, so check for interrupts */ -- 2.11.0