diff options
author | Magnus Hagander <magnus@hagander.net> | 2016-12-19 10:11:04 +0100 |
---|---|---|
committer | Magnus Hagander <magnus@hagander.net> | 2016-12-19 10:16:02 +0100 |
commit | bc53d71308a2b4bd8216932fda3e21cec4915ff8 (patch) | |
tree | 15ac0202812743eca9a7d2380561a24f4a3f2228 | |
parent | 53140bf22bc4b361836b68f08a2946a2fd2ab240 (diff) | |
download | postgresql-bc53d71308a2b4bd8216932fda3e21cec4915ff8.tar.gz postgresql-bc53d71308a2b4bd8216932fda3e21cec4915ff8.zip |
Fix base backup rate limiting in presence of slow i/o
When source i/o on disk was too slow compared to the rate limiting
specified, the system could end up with a negative value for sleep that
it never got out of, which caused rate limiting to effectively be
turned off.
Discussion: https://postgr.es/m/CABUevEy_-e0YvL4ayoX8bH_Ja9w%2BBHoP6jUgdxZuG2nEj3uAfQ%40mail.gmail.com
Analysis by me, patch by Antonin Houska
-rw-r--r-- | src/backend/replication/basebackup.c | 24 |
1 files changed, 7 insertions, 17 deletions
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 901a65c51ca..624dea3b03a 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -1300,26 +1300,16 @@ throttle(size_t increment) if (wait_result & WL_LATCH_SET) CHECK_FOR_INTERRUPTS(); } - else - { - /* - * The actual transfer rate is below the limit. A negative value - * would distort the adjustment of throttled_last. - */ - wait_result = 0; - sleep = 0; - } /* - * Only a whole multiple of throttling_sample was processed. The rest will - * be done during the next call of this function. + * As we work with integers, only whole multiple of throttling_sample was + * processed. The rest will be done during the next call of this function. */ throttling_counter %= throttling_sample; - /* Once the (possible) sleep has ended, new period starts. */ - if (wait_result & WL_TIMEOUT) - throttled_last += elapsed + sleep; - else if (sleep > 0) - /* Sleep was necessary but might have been interrupted. */ - throttled_last = GetCurrentIntegerTimestamp(); + /* + * Time interval for the remaining amount and possible next increments + * starts now. + */ + throttled_last = GetCurrentIntegerTimestamp(); } |