]> granicus.if.org Git - postgresql/commitdiff
Fix base backup rate limiting in presence of slow i/o
authorMagnus Hagander <magnus@hagander.net>
Mon, 19 Dec 2016 09:11:04 +0000 (10:11 +0100)
committerMagnus Hagander <magnus@hagander.net>
Mon, 19 Dec 2016 09:11:04 +0000 (10:11 +0100)
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

src/backend/replication/basebackup.c

index ffc7e586dba712748dd13b31fdaac2cb91504ae1..40b3c117e8fc4ef5381edbc2fe52800cc3d23497 100644 (file)
@@ -1370,26 +1370,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();
 }