Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  basebackup_throttle.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * basebackup_throttle.c
 *   Basebackup sink implementing throttling. Data is forwarded to the
 *   next base backup sink in the chain at a rate no greater than the
 *   configured maximum.
 *
 * Portions Copyright (c) 2010-2025, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *   src/backend/backup/basebackup_throttle.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "backup/basebackup_sink.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/latch.h"
#include "utils/timestamp.h"

typedef struct bbsink_throttle
{
 /* Common information for all types of sink. */
 bbsink  base;

 /* The actual number of bytes, transfer of which may cause sleep. */
 uint64  throttling_sample;

 /* Amount of data already transferred but not yet throttled.  */
 int64  throttling_counter;

 /* The minimum time required to transfer throttling_sample bytes. */
 TimeOffset elapsed_min_unit;

 /* The last check of the transfer rate. */
 TimestampTz throttled_last;
} bbsink_throttle;

static void bbsink_throttle_begin_backup(bbsink *sink);
static void bbsink_throttle_archive_contents(bbsink *sink, size_t len);
static void bbsink_throttle_manifest_contents(bbsink *sink, size_t len);
static void throttle(bbsink_throttle *sink, size_t increment);

static const bbsink_ops bbsink_throttle_ops = {
 .begin_backup = bbsink_throttle_begin_backup,
 .begin_archive = bbsink_forward_begin_archive,
 .archive_contents = bbsink_throttle_archive_contents,
 .end_archive = bbsink_forward_end_archive,
 .begin_manifest = bbsink_forward_begin_manifest,
 .manifest_contents = bbsink_throttle_manifest_contents,
 .end_manifest = bbsink_forward_end_manifest,
 .end_backup = bbsink_forward_end_backup,
 .cleanup = bbsink_forward_cleanup
};

/*
 * How frequently to throttle, as a fraction of the specified rate-second.
 */

#define THROTTLING_FREQUENCY 8

/*
 * Create a new basebackup sink that performs throttling and forwards data
 * to a successor sink.
 */

bbsink *
bbsink_throttle_new(bbsink *next, uint32 maxrate)
{
 bbsink_throttle *sink;

 Assert(next != NULL);
 Assert(maxrate > 0);

 sink = palloc0(sizeof(bbsink_throttle));
 *((const bbsink_ops **) &sink->base.bbs_ops) = &bbsink_throttle_ops;
 sink->base.bbs_next = next;

 sink->throttling_sample =
  (int64) maxrate * (int64) 1024 / THROTTLING_FREQUENCY;

 /*
  * The minimum amount of time for throttling_sample bytes to be
  * transferred.
 */

 sink->elapsed_min_unit = USECS_PER_SEC / THROTTLING_FREQUENCY;

 return &sink->base;
}

/*
 * There's no real work to do here, but we need to record the current time so
 * that it can be used for future calculations.
 */

static void
bbsink_throttle_begin_backup(bbsink *sink)
{
 bbsink_throttle *mysink = (bbsink_throttle *) sink;

 bbsink_forward_begin_backup(sink);

 /* The 'real data' starts now (header was ignored). */
 mysink->throttled_last = GetCurrentTimestamp();
}

/*
 * First throttle, and then pass archive contents to next sink.
 */

static void
bbsink_throttle_archive_contents(bbsink *sink, size_t len)
{
 throttle((bbsink_throttle *) sink, len);

 bbsink_forward_archive_contents(sink, len);
}

/*
 * First throttle, and then pass manifest contents to next sink.
 */

static void
bbsink_throttle_manifest_contents(bbsink *sink, size_t len)
{
 throttle((bbsink_throttle *) sink, len);

 bbsink_forward_manifest_contents(sink, len);
}

/*
 * Increment the network transfer counter by the given number of bytes,
 * and sleep if necessary to comply with the requested network transfer
 * rate.
 */

static void
throttle(bbsink_throttle *sink, size_t increment)
{
 TimeOffset elapsed_min;

 Assert(sink->throttling_counter >= 0);

 sink->throttling_counter += increment;
 if (sink->throttling_counter < sink->throttling_sample)
  return;

 /* How much time should have elapsed at minimum? */
 elapsed_min = sink->elapsed_min_unit *
  (sink->throttling_counter / sink->throttling_sample);

 /*
  * Since the latch could be set repeatedly because of concurrently WAL
  * activity, sleep 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() - sink->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 */
  CHECK_FOR_INTERRUPTS();

  /*
   * (TAR_SEND_SIZE / throttling_sample * elapsed_min_unit) should be
   * the maximum time to sleep. Thus the cast to long is safe.
 */

  wait_result = WaitLatch(MyLatch,
        WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
        (long) (sleep / 1000),
        WAIT_EVENT_BASE_BACKUP_THROTTLE);

  if (wait_result & WL_LATCH_SET)
   CHECK_FOR_INTERRUPTS();

  /* Done waiting? */
  if (wait_result & WL_TIMEOUT)
   break;
 }

 /*
  * 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.
 */

 sink->throttling_counter %= sink->throttling_sample;

 /*
  * Time interval for the remaining amount and possible next increments
  * starts now.
 */

 sink->throttled_last = GetCurrentTimestamp();
}

Messung V0.5 in Prozent
C=92 H=96 G=93

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.1Bemerkung:  (vorverarbeitet am  2026-08-08) ¤

*Bot Zugriff






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002