1/*-------------------------------------------------------------------------
3 * basebackup_throttle.c
4 * Basebackup sink implementing throttling. Data is forwarded to the
5 * next base backup sink in the chain at a rate no greater than the
8 * Portions Copyright (c) 2010-2025, PostgreSQL Global Development Group
11 * src/backend/backup/basebackup_throttle.c
13 *-------------------------------------------------------------------------
25 /* Common information for all types of sink. */
28 /* The actual number of bytes, transfer of which may cause sleep. */
31 /* Amount of data already transferred but not yet throttled. */
34 /* The minimum time required to transfer throttling_sample bytes. */
37 /* The last check of the transfer rate. */
59 * How frequently to throttle, as a fraction of the specified rate-second.
61 #define THROTTLING_FREQUENCY 8
64 * Create a new basebackup sink that performs throttling and forwards data
65 * to a successor sink.
83 * The minimum amount of time for throttling_sample bytes to be
92 * There's no real work to do here, but we need to record the current time so
93 * that it can be used for future calculations.
102 /* The 'real data' starts now (header was ignored). */
107 * First throttle, and then pass archive contents to next sink.
118 * First throttle, and then pass manifest contents to next sink.
129 * Increment the network transfer counter by the given number of bytes,
130 * and sleep if necessary to comply with the requested network transfer
144 /* How much time should have elapsed at minimum? */
149 * Since the latch could be set repeatedly because of concurrently WAL
150 * activity, sleep in a loop to ensure enough time has passed.
158 /* Time elapsed since the last measurement (and possible wake up). */
161 /* sleep if the transfer is faster than it should be */
162 sleep = elapsed_min - elapsed;
168 /* We're eating a potentially set latch, so check for interrupts */
172 * (TAR_SEND_SIZE / throttling_sample * elapsed_min_unit) should be
173 * the maximum time to sleep. Thus the cast to long is safe.
177 (
long) (sleep / 1000),
178 WAIT_EVENT_BASE_BACKUP_THROTTLE);
189 * As we work with integers, only whole multiple of throttling_sample was
190 * processed. The rest will be done during the next call of this function.
195 * Time interval for the remaining amount and possible next increments
TimestampTz GetCurrentTimestamp(void)
void bbsink_forward_begin_backup(bbsink *sink)
void bbsink_forward_begin_manifest(bbsink *sink)
void bbsink_forward_end_backup(bbsink *sink, XLogRecPtr endptr, TimeLineID endtli)
void bbsink_forward_cleanup(bbsink *sink)
void bbsink_forward_manifest_contents(bbsink *sink, size_t len)
void bbsink_forward_end_archive(bbsink *sink)
void bbsink_forward_archive_contents(bbsink *sink, size_t len)
void bbsink_forward_begin_archive(bbsink *sink, const char *archive_name)
void bbsink_forward_end_manifest(bbsink *sink)
static void bbsink_throttle_archive_contents(bbsink *sink, size_t len)
static void throttle(bbsink_throttle *sink, size_t increment)
bbsink * bbsink_throttle_new(bbsink *next, uint32 maxrate)
static void bbsink_throttle_begin_backup(bbsink *sink)
struct bbsink_throttle bbsink_throttle
#define THROTTLING_FREQUENCY
static void bbsink_throttle_manifest_contents(bbsink *sink, size_t len)
static const bbsink_ops bbsink_throttle_ops
Assert(PointerIsAligned(start, uint64))
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
void * palloc0(Size size)
#define CHECK_FOR_INTERRUPTS()
void(* begin_backup)(bbsink *sink)
TimestampTz throttled_last
TimeOffset elapsed_min_unit
const bbsink_ops * bbs_ops
#define WL_EXIT_ON_PM_DEATH