Running pg_basebackup with a throttling of say 10M runs it into the risk of
the I/O on the server actually being slower than pg_basebackup (I have
preproduced similar issues on fake-slow disks with lower rate limits).
What happens in this case in basebackup.c is that the value for "sleep"
comes out negative. This means we don't sleep, which is fine.
However, that also means we don't set throttle_last.
That means that the next time we come around to throttle(), the value for
"elapsed" is even bigger, which results in an even bigger negative number,
and we're "stuck".
AFAICT this means that a temporary I/O spike that makes reading of the disk
too slow can leave us in a situation where we never recover, and thus never
end up sleeping ever again, effectively turning off rate limiting.
I wonder if the
else if (sleep > 0)
at the bottom of throttle()
should just be a simple else and always run, resetting last_throttle?