Jeff Janes wrote: > I'm attaching a patch for each option. Each one independently solves the > problem. But I think we should do both. There is no point in issuing > unnecessary kill system calls, and there may also be more spurious wake-ups > than just these ones.
I modified patch 1 a bit -- result attached. I would like to back-patch this all the way back to 9.4, but there are a few conflicts due to c29aff959dc so I think I'm going to do pg10 only unless I get some votes that it should go further back. I think it should be fairly trivial to resolve. The other patch should be applied to master only IMO. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>From e482f52f792df3685f4f9d955d54e04570db5cc5 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> 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
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers