PostgreSQL Source Code  git master
basebackup.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include "access/xlog_internal.h"
#include "catalog/pg_type.h"
#include "common/file_perm.h"
#include "lib/stringinfo.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/pg_list.h"
#include "pgtar.h"
#include "pgstat.h"
#include "port.h"
#include "postmaster/syslogger.h"
#include "replication/basebackup.h"
#include "replication/walsender.h"
#include "replication/walsender_private.h"
#include "storage/bufpage.h"
#include "storage/checksum.h"
#include "storage/dsm_impl.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/reinit.h"
#include "utils/builtins.h"
#include "utils/ps_status.h"
#include "utils/relcache.h"
#include "utils/timestamp.h"
Include dependency graph for basebackup.c:

Go to the source code of this file.

Data Structures

struct  basebackup_options
 

Macros

#define TAR_SEND_SIZE   32768
 
#define THROTTLING_FREQUENCY   8
 

Functions

static int64 sendDir (const char *path, int basepathlen, bool sizeonly, List *tablespaces, bool sendtblspclinks)
 
static bool sendFile (const char *readfilename, const char *tarfilename, struct stat *statbuf, bool missing_ok, Oid dboid)
 
static void sendFileWithContent (const char *filename, const char *content)
 
static int64 _tarWriteHeader (const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
 
static int64 _tarWriteDir (const char *pathbuf, int basepathlen, struct stat *statbuf, bool sizeonly)
 
static void send_int8_string (StringInfoData *buf, int64 intval)
 
static void SendBackupHeader (List *tablespaces)
 
static void base_backup_cleanup (int code, Datum arg)
 
static void perform_base_backup (basebackup_options *opt)
 
static void parse_basebackup_options (List *options, basebackup_options *opt)
 
static void SendXlogRecPtrResult (XLogRecPtr ptr, TimeLineID tli)
 
static int compareWalFileNames (const ListCell *a, const ListCell *b)
 
static void throttle (size_t increment)
 
static bool is_checksummed_file (const char *fullpath, const char *filename)
 
void SendBaseBackup (BaseBackupCmd *cmd)
 
int64 sendTablespace (char *path, bool sizeonly)
 

Variables

static bool backup_started_in_recovery = false
 
static char * statrelpath = NULL
 
static uint64 throttling_sample
 
static int64 throttling_counter
 
static TimeOffset elapsed_min_unit
 
static TimestampTz throttled_last
 
static XLogRecPtr startptr
 
static long long int total_checksum_failures
 
static bool noverify_checksums = false
 
static const char * excludeDirContents []
 
static const char * excludeFiles []
 
static const char *const noChecksumFiles []
 

Macro Definition Documentation

◆ TAR_SEND_SIZE

#define TAR_SEND_SIZE   32768

Definition at line 86 of file basebackup.c.

Referenced by perform_base_backup(), and sendFile().

◆ THROTTLING_FREQUENCY

#define THROTTLING_FREQUENCY   8

Definition at line 91 of file basebackup.c.

Referenced by perform_base_backup().

Function Documentation

◆ _tarWriteDir()

static int64 _tarWriteDir ( const char *  pathbuf,
int  basepathlen,
struct stat statbuf,
bool  sizeonly 
)
static

Definition at line 1627 of file basebackup.c.

References _tarWriteHeader(), pg_dir_create_mode, and pgwin32_is_junction().

Referenced by sendDir().

1629 {
1630  /* If symlink, write it as a directory anyway */
1631 #ifndef WIN32
1632  if (S_ISLNK(statbuf->st_mode))
1633 #else
1634  if (pgwin32_is_junction(pathbuf))
1635 #endif
1636  statbuf->st_mode = S_IFDIR | pg_dir_create_mode;
1637 
1638  return _tarWriteHeader(pathbuf + basepathlen + 1, NULL, statbuf, sizeonly);
1639 }
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1585
int pg_dir_create_mode
Definition: file_perm.c:18
bool pgwin32_is_junction(const char *path)

◆ _tarWriteHeader()

static int64 _tarWriteHeader ( const char *  filename,
const char *  linktarget,
struct stat statbuf,
bool  sizeonly 
)
static

Definition at line 1585 of file basebackup.c.

References elog, ereport, errmsg(), ERROR, pq_putmessage, TAR_NAME_TOO_LONG, TAR_OK, TAR_SYMLINK_TOO_LONG, and tarCreateHeader().

Referenced by _tarWriteDir(), perform_base_backup(), sendDir(), sendFile(), sendFileWithContent(), and sendTablespace().

1587 {
1588  char h[512];
1589  enum tarError rc;
1590 
1591  if (!sizeonly)
1592  {
1593  rc = tarCreateHeader(h, filename, linktarget, statbuf->st_size,
1594  statbuf->st_mode, statbuf->st_uid, statbuf->st_gid,
1595  statbuf->st_mtime);
1596 
1597  switch (rc)
1598  {
1599  case TAR_OK:
1600  break;
1601  case TAR_NAME_TOO_LONG:
1602  ereport(ERROR,
1603  (errmsg("file name too long for tar format: \"%s\"",
1604  filename)));
1605  break;
1606  case TAR_SYMLINK_TOO_LONG:
1607  ereport(ERROR,
1608  (errmsg("symbolic link target too long for tar format: "
1609  "file name \"%s\", target \"%s\"",
1610  filename, linktarget)));
1611  break;
1612  default:
1613  elog(ERROR, "unrecognized tar error: %d", rc);
1614  }
1615 
1616  pq_putmessage('d', h, sizeof(h));
1617  }
1618 
1619  return sizeof(h);
1620 }
Definition: pgtar.h:17
tarError
Definition: pgtar.h:15
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime)
Definition: tar.c:112
static char * filename
Definition: pg_dumpall.c:91
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:42

◆ base_backup_cleanup()

static void base_backup_cleanup ( int  code,
Datum  arg 
)
static

Definition at line 214 of file basebackup.c.

References do_pg_abort_backup().

Referenced by perform_base_backup().

215 {
217 }
void do_pg_abort_backup(void)
Definition: xlog.c:11102

◆ compareWalFileNames()

static int compareWalFileNames ( const ListCell a,
const ListCell b 
)
static

Definition at line 618 of file basebackup.c.

References lfirst.

Referenced by perform_base_backup().

619 {
620  char *fna = (char *) lfirst(a);
621  char *fnb = (char *) lfirst(b);
622 
623  return strcmp(fna + 8, fnb + 8);
624 }
#define lfirst(lc)
Definition: pg_list.h:190

◆ is_checksummed_file()

static bool is_checksummed_file ( const char *  fullpath,
const char *  filename 
)
static

Definition at line 1317 of file basebackup.c.

References noChecksumFiles.

Referenced by sendFile().

1318 {
1319  const char *const *f;
1320 
1321  /* Check that the file is in a tablespace */
1322  if (strncmp(fullpath, "./global/", 9) == 0 ||
1323  strncmp(fullpath, "./base/", 7) == 0 ||
1324  strncmp(fullpath, "/", 1) == 0)
1325  {
1326  /* Compare file against noChecksumFiles skiplist */
1327  for (f = noChecksumFiles; *f; f++)
1328  if (strcmp(*f, filename) == 0)
1329  return false;
1330 
1331  return true;
1332  }
1333  else
1334  return false;
1335 }
static char * filename
Definition: pg_dumpall.c:91
static const char *const noChecksumFiles[]
Definition: basebackup.c:196

◆ parse_basebackup_options()

static void parse_basebackup_options ( List options,
basebackup_options opt 
)
static

Definition at line 630 of file basebackup.c.

References DefElem::arg, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, basebackup_options::fastcheckpoint, basebackup_options::includewal, intVal, basebackup_options::label, lfirst, MAX_RATE_LOWER, MAX_RATE_UPPER, basebackup_options::maxrate, maxrate, MemSet, noverify_checksums, basebackup_options::nowait, basebackup_options::progress, basebackup_options::sendtblspcmapfile, and strVal.

Referenced by SendBaseBackup().

631 {
632  ListCell *lopt;
633  bool o_label = false;
634  bool o_progress = false;
635  bool o_fast = false;
636  bool o_nowait = false;
637  bool o_wal = false;
638  bool o_maxrate = false;
639  bool o_tablespace_map = false;
640  bool o_noverify_checksums = false;
641 
642  MemSet(opt, 0, sizeof(*opt));
643  foreach(lopt, options)
644  {
645  DefElem *defel = (DefElem *) lfirst(lopt);
646 
647  if (strcmp(defel->defname, "label") == 0)
648  {
649  if (o_label)
650  ereport(ERROR,
651  (errcode(ERRCODE_SYNTAX_ERROR),
652  errmsg("duplicate option \"%s\"", defel->defname)));
653  opt->label = strVal(defel->arg);
654  o_label = true;
655  }
656  else if (strcmp(defel->defname, "progress") == 0)
657  {
658  if (o_progress)
659  ereport(ERROR,
660  (errcode(ERRCODE_SYNTAX_ERROR),
661  errmsg("duplicate option \"%s\"", defel->defname)));
662  opt->progress = true;
663  o_progress = true;
664  }
665  else if (strcmp(defel->defname, "fast") == 0)
666  {
667  if (o_fast)
668  ereport(ERROR,
669  (errcode(ERRCODE_SYNTAX_ERROR),
670  errmsg("duplicate option \"%s\"", defel->defname)));
671  opt->fastcheckpoint = true;
672  o_fast = true;
673  }
674  else if (strcmp(defel->defname, "nowait") == 0)
675  {
676  if (o_nowait)
677  ereport(ERROR,
678  (errcode(ERRCODE_SYNTAX_ERROR),
679  errmsg("duplicate option \"%s\"", defel->defname)));
680  opt->nowait = true;
681  o_nowait = true;
682  }
683  else if (strcmp(defel->defname, "wal") == 0)
684  {
685  if (o_wal)
686  ereport(ERROR,
687  (errcode(ERRCODE_SYNTAX_ERROR),
688  errmsg("duplicate option \"%s\"", defel->defname)));
689  opt->includewal = true;
690  o_wal = true;
691  }
692  else if (strcmp(defel->defname, "max_rate") == 0)
693  {
694  long maxrate;
695 
696  if (o_maxrate)
697  ereport(ERROR,
698  (errcode(ERRCODE_SYNTAX_ERROR),
699  errmsg("duplicate option \"%s\"", defel->defname)));
700 
701  maxrate = intVal(defel->arg);
702  if (maxrate < MAX_RATE_LOWER || maxrate > MAX_RATE_UPPER)
703  ereport(ERROR,
704  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
705  errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
706  (int) maxrate, "MAX_RATE", MAX_RATE_LOWER, MAX_RATE_UPPER)));
707 
708  opt->maxrate = (uint32) maxrate;
709  o_maxrate = true;
710  }
711  else if (strcmp(defel->defname, "tablespace_map") == 0)
712  {
713  if (o_tablespace_map)
714  ereport(ERROR,
715  (errcode(ERRCODE_SYNTAX_ERROR),
716  errmsg("duplicate option \"%s\"", defel->defname)));
717  opt->sendtblspcmapfile = true;
718  o_tablespace_map = true;
719  }
720  else if (strcmp(defel->defname, "noverify_checksums") == 0)
721  {
722  if (o_noverify_checksums)
723  ereport(ERROR,
724  (errcode(ERRCODE_SYNTAX_ERROR),
725  errmsg("duplicate option \"%s\"", defel->defname)));
726  noverify_checksums = true;
727  o_noverify_checksums = true;
728  }
729  else
730  elog(ERROR, "option \"%s\" not recognized",
731  defel->defname);
732  }
733  if (opt->label == NULL)
734  opt->label = "base backup";
735 }
#define MAX_RATE_LOWER
Definition: basebackup.h:20
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:570
#define MemSet(start, val, len)
Definition: c.h:955
#define MAX_RATE_UPPER
Definition: basebackup.h:21
#define ERROR
Definition: elog.h:43
static bool noverify_checksums
Definition: basebackup.c:112
static int32 maxrate
const char * label
Definition: basebackup.c:48
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
Node * arg
Definition: parsenodes.h:731
#define lfirst(lc)
Definition: pg_list.h:190
#define intVal(v)
Definition: value.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
char * defname
Definition: parsenodes.h:730

◆ perform_base_backup()

static void perform_base_backup ( basebackup_options opt)
static

Definition at line 226 of file basebackup.c.

References _tarWriteHeader(), AllocateDir(), AllocateFile(), Assert, BACKUP_LABEL_FILE, backup_started_in_recovery, base_backup_cleanup(), buf, CheckXLogRemoved(), compareWalFileNames(), dirent::d_name, StringInfoData::data, DataDir, do_pg_start_backup(), do_pg_stop_backup(), elapsed_min_unit, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errcode_for_file_access(), errmsg(), ERROR, basebackup_options::fastcheckpoint, FreeDir(), FreeFile(), GetCurrentTimestamp(), basebackup_options::includewal, InvalidOid, is_absolute_path, IsTLHistoryFileName, IsXLogFileName, basebackup_options::label, lappend(), lfirst, linitial, list_sort(), lnext(), lstat, makeStringInfo(), MAXFNAMELEN, MAXPGPATH, basebackup_options::maxrate, Min, NIL, basebackup_options::nowait, palloc0(), tablespaceinfo::path, PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pgoff_t, pgstat_stat_directory, pq_beginmessage(), pq_endmessage(), pq_putemptymessage(), pq_putmessage, pq_sendbyte(), pq_sendint16(), basebackup_options::progress, psprintf(), pstrdup(), ReadDir(), RecoveryInProgress(), SendBackupHeader(), sendDir(), sendFile(), sendFileWithContent(), sendTablespace(), basebackup_options::sendtblspcmapfile, SendXlogRecPtrResult(), tablespaceinfo::size, snprintf, startptr, stat, statrelpath, StatusFilePath, TABLESPACE_MAP, TAR_SEND_SIZE, tblspc_map_file, ThisTimeLineID, throttle(), throttled_last, throttling_counter, THROTTLING_FREQUENCY, throttling_sample, total_checksum_failures, USECS_PER_SEC, wal_segment_size, WARNING, XLByteToPrevSeg, XLByteToSeg, XLOG_CONTROL_FILE, XLOGDIR, XLogFileName, and XLogFromFileName.

Referenced by SendBaseBackup().

227 {
228  TimeLineID starttli;
229  XLogRecPtr endptr;
230  TimeLineID endtli;
231  StringInfo labelfile;
233  int datadirpathlen;
234  List *tablespaces = NIL;
235 
236  datadirpathlen = strlen(DataDir);
237 
239 
240  labelfile = makeStringInfo();
241  tblspc_map_file = makeStringInfo();
242 
244 
245  startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &starttli,
246  labelfile, &tablespaces,
247  tblspc_map_file,
248  opt->progress, opt->sendtblspcmapfile);
249 
250  /*
251  * Once do_pg_start_backup has been called, ensure that any failure causes
252  * us to abort the backup so we don't "leak" a backup counter. For this
253  * reason, *all* functionality between do_pg_start_backup() and the end of
254  * do_pg_stop_backup() should be inside the error cleanup block!
255  */
256 
258  {
259  ListCell *lc;
260  tablespaceinfo *ti;
261 
262  SendXlogRecPtrResult(startptr, starttli);
263 
264  /*
265  * Calculate the relative path of temporary statistics directory in
266  * order to skip the files which are located in that directory later.
267  */
269  strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0)
270  statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1);
271  else if (strncmp(pgstat_stat_directory, "./", 2) != 0)
273  else
275 
276  /* Add a node for the base directory at the end */
277  ti = palloc0(sizeof(tablespaceinfo));
278  ti->size = opt->progress ? sendDir(".", 1, true, tablespaces, true) : -1;
279  tablespaces = lappend(tablespaces, ti);
280 
281  /* Send tablespace header */
282  SendBackupHeader(tablespaces);
283 
284  /* Setup and activate network throttling, if client requested it */
285  if (opt->maxrate > 0)
286  {
288  (int64) opt->maxrate * (int64) 1024 / THROTTLING_FREQUENCY;
289 
290  /*
291  * The minimum amount of time for throttling_sample bytes to be
292  * transferred.
293  */
295 
296  /* Enable throttling. */
297  throttling_counter = 0;
298 
299  /* The 'real data' starts now (header was ignored). */
301  }
302  else
303  {
304  /* Disable throttling. */
305  throttling_counter = -1;
306  }
307 
308  /* Send off our tablespaces one by one */
309  foreach(lc, tablespaces)
310  {
311  tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc);
313 
314  /* Send CopyOutResponse message */
315  pq_beginmessage(&buf, 'H');
316  pq_sendbyte(&buf, 0); /* overall format */
317  pq_sendint16(&buf, 0); /* natts */
318  pq_endmessage(&buf);
319 
320  if (ti->path == NULL)
321  {
322  struct stat statbuf;
323 
324  /* In the main tar, include the backup_label first... */
326 
327  /*
328  * Send tablespace_map file if required and then the bulk of
329  * the files.
330  */
331  if (tblspc_map_file && opt->sendtblspcmapfile)
332  {
333  sendFileWithContent(TABLESPACE_MAP, tblspc_map_file->data);
334  sendDir(".", 1, false, tablespaces, false);
335  }
336  else
337  sendDir(".", 1, false, tablespaces, true);
338 
339  /* ... and pg_control after everything else. */
340  if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0)
341  ereport(ERROR,
343  errmsg("could not stat file \"%s\": %m",
346  }
347  else
348  sendTablespace(ti->path, false);
349 
350  /*
351  * If we're including WAL, and this is the main data directory we
352  * don't terminate the tar stream here. Instead, we will append
353  * the xlog files below and terminate it then. This is safe since
354  * the main data directory is always sent *last*.
355  */
356  if (opt->includewal && ti->path == NULL)
357  {
358  Assert(lnext(tablespaces, lc) == NULL);
359  }
360  else
361  pq_putemptymessage('c'); /* CopyDone */
362  }
363 
364  endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli);
365  }
367 
368 
369  if (opt->includewal)
370  {
371  /*
372  * We've left the last tar file "open", so we can now append the
373  * required WAL files to it.
374  */
375  char pathbuf[MAXPGPATH];
376  XLogSegNo segno;
377  XLogSegNo startsegno;
378  XLogSegNo endsegno;
379  struct stat statbuf;
380  List *historyFileList = NIL;
381  List *walFileList = NIL;
382  char firstoff[MAXFNAMELEN];
383  char lastoff[MAXFNAMELEN];
384  DIR *dir;
385  struct dirent *de;
386  ListCell *lc;
387  TimeLineID tli;
388 
389  /*
390  * I'd rather not worry about timelines here, so scan pg_wal and
391  * include all WAL files in the range between 'startptr' and 'endptr',
392  * regardless of the timeline the file is stamped with. If there are
393  * some spurious WAL files belonging to timelines that don't belong in
394  * this server's history, they will be included too. Normally there
395  * shouldn't be such files, but if there are, there's little harm in
396  * including them.
397  */
398  XLByteToSeg(startptr, startsegno, wal_segment_size);
399  XLogFileName(firstoff, ThisTimeLineID, startsegno, wal_segment_size);
400  XLByteToPrevSeg(endptr, endsegno, wal_segment_size);
401  XLogFileName(lastoff, ThisTimeLineID, endsegno, wal_segment_size);
402 
403  dir = AllocateDir("pg_wal");
404  while ((de = ReadDir(dir, "pg_wal")) != NULL)
405  {
406  /* Does it look like a WAL segment, and is it in the range? */
407  if (IsXLogFileName(de->d_name) &&
408  strcmp(de->d_name + 8, firstoff + 8) >= 0 &&
409  strcmp(de->d_name + 8, lastoff + 8) <= 0)
410  {
411  walFileList = lappend(walFileList, pstrdup(de->d_name));
412  }
413  /* Does it look like a timeline history file? */
414  else if (IsTLHistoryFileName(de->d_name))
415  {
416  historyFileList = lappend(historyFileList, pstrdup(de->d_name));
417  }
418  }
419  FreeDir(dir);
420 
421  /*
422  * Before we go any further, check that none of the WAL segments we
423  * need were removed.
424  */
425  CheckXLogRemoved(startsegno, ThisTimeLineID);
426 
427  /*
428  * Sort the WAL filenames. We want to send the files in order from
429  * oldest to newest, to reduce the chance that a file is recycled
430  * before we get a chance to send it over.
431  */
432  list_sort(walFileList, compareWalFileNames);
433 
434  /*
435  * There must be at least one xlog file in the pg_wal directory, since
436  * we are doing backup-including-xlog.
437  */
438  if (walFileList == NIL)
439  ereport(ERROR,
440  (errmsg("could not find any WAL files")));
441 
442  /*
443  * Sanity check: the first and last segment should cover startptr and
444  * endptr, with no gaps in between.
445  */
446  XLogFromFileName((char *) linitial(walFileList),
447  &tli, &segno, wal_segment_size);
448  if (segno != startsegno)
449  {
450  char startfname[MAXFNAMELEN];
451 
452  XLogFileName(startfname, ThisTimeLineID, startsegno,
454  ereport(ERROR,
455  (errmsg("could not find WAL file \"%s\"", startfname)));
456  }
457  foreach(lc, walFileList)
458  {
459  char *walFileName = (char *) lfirst(lc);
460  XLogSegNo currsegno = segno;
461  XLogSegNo nextsegno = segno + 1;
462 
463  XLogFromFileName(walFileName, &tli, &segno, wal_segment_size);
464  if (!(nextsegno == segno || currsegno == segno))
465  {
466  char nextfname[MAXFNAMELEN];
467 
468  XLogFileName(nextfname, ThisTimeLineID, nextsegno,
470  ereport(ERROR,
471  (errmsg("could not find WAL file \"%s\"", nextfname)));
472  }
473  }
474  if (segno != endsegno)
475  {
476  char endfname[MAXFNAMELEN];
477 
478  XLogFileName(endfname, ThisTimeLineID, endsegno, wal_segment_size);
479  ereport(ERROR,
480  (errmsg("could not find WAL file \"%s\"", endfname)));
481  }
482 
483  /* Ok, we have everything we need. Send the WAL files. */
484  foreach(lc, walFileList)
485  {
486  char *walFileName = (char *) lfirst(lc);
487  FILE *fp;
488  char buf[TAR_SEND_SIZE];
489  size_t cnt;
490  pgoff_t len = 0;
491 
492  snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFileName);
493  XLogFromFileName(walFileName, &tli, &segno, wal_segment_size);
494 
495  fp = AllocateFile(pathbuf, "rb");
496  if (fp == NULL)
497  {
498  int save_errno = errno;
499 
500  /*
501  * Most likely reason for this is that the file was already
502  * removed by a checkpoint, so check for that to get a better
503  * error message.
504  */
505  CheckXLogRemoved(segno, tli);
506 
507  errno = save_errno;
508  ereport(ERROR,
510  errmsg("could not open file \"%s\": %m", pathbuf)));
511  }
512 
513  if (fstat(fileno(fp), &statbuf) != 0)
514  ereport(ERROR,
516  errmsg("could not stat file \"%s\": %m",
517  pathbuf)));
518  if (statbuf.st_size != wal_segment_size)
519  {
520  CheckXLogRemoved(segno, tli);
521  ereport(ERROR,
523  errmsg("unexpected WAL file size \"%s\"", walFileName)));
524  }
525 
526  /* send the WAL file itself */
527  _tarWriteHeader(pathbuf, NULL, &statbuf, false);
528 
529  while ((cnt = fread(buf, 1,
530  Min(sizeof(buf), wal_segment_size - len),
531  fp)) > 0)
532  {
533  CheckXLogRemoved(segno, tli);
534  /* Send the chunk as a CopyData message */
535  if (pq_putmessage('d', buf, cnt))
536  ereport(ERROR,
537  (errmsg("base backup could not send data, aborting backup")));
538 
539  len += cnt;
540  throttle(cnt);
541 
542  if (len == wal_segment_size)
543  break;
544  }
545 
546  if (len != wal_segment_size)
547  {
548  CheckXLogRemoved(segno, tli);
549  ereport(ERROR,
551  errmsg("unexpected WAL file size \"%s\"", walFileName)));
552  }
553 
554  /* wal_segment_size is a multiple of 512, so no need for padding */
555 
556  FreeFile(fp);
557 
558  /*
559  * Mark file as archived, otherwise files can get archived again
560  * after promotion of a new node. This is in line with
561  * walreceiver.c always doing an XLogArchiveForceDone() after a
562  * complete segment.
563  */
564  StatusFilePath(pathbuf, walFileName, ".done");
565  sendFileWithContent(pathbuf, "");
566  }
567 
568  /*
569  * Send timeline history files too. Only the latest timeline history
570  * file is required for recovery, and even that only if there happens
571  * to be a timeline switch in the first WAL segment that contains the
572  * checkpoint record, or if we're taking a base backup from a standby
573  * server and the target timeline changes while the backup is taken.
574  * But they are small and highly useful for debugging purposes, so
575  * better include them all, always.
576  */
577  foreach(lc, historyFileList)
578  {
579  char *fname = lfirst(lc);
580 
581  snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", fname);
582 
583  if (lstat(pathbuf, &statbuf) != 0)
584  ereport(ERROR,
586  errmsg("could not stat file \"%s\": %m", pathbuf)));
587 
588  sendFile(pathbuf, pathbuf, &statbuf, false, InvalidOid);
589 
590  /* unconditionally mark file as archived */
591  StatusFilePath(pathbuf, fname, ".done");
592  sendFileWithContent(pathbuf, "");
593  }
594 
595  /* Send CopyDone message for the last tar file */
596  pq_putemptymessage('c');
597  }
598  SendXlogRecPtrResult(endptr, endtli);
599 
601  {
602  if (total_checksum_failures > 1)
604  (errmsg("%lld total checksum verification failures", total_checksum_failures)));
605 
606  ereport(ERROR,
608  errmsg("checksum verification failure during base backup")));
609  }
610 
611 }
#define StatusFilePath(path, xlog, suffix)
#define NIL
Definition: pg_list.h:65
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137
static void throttle(size_t increment)
Definition: basebackup.c:1647
uint32 TimeLineID
Definition: xlogdefs.h:52
int wal_segment_size
Definition: xlog.c:112
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
#define USECS_PER_SEC
Definition: timestamp.h:94
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
char * pstrdup(const char *in)
Definition: mcxt.c:1161
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
#define Min(x, y)
Definition: c.h:904
static void SendBackupHeader(List *tablespaces)
Definition: basebackup.c:777
int errcode(int sqlerrcode)
Definition: elog.c:570
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:390
bool RecoveryInProgress(void)
Definition: xlog.c:7898
static bool backup_started_in_recovery
Definition: basebackup.c:78
Definition: dirent.h:9
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:87
XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, bool needtblspcmapfile)
Definition: xlog.c:10178
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:161
#define pgoff_t
Definition: win32_port.h:204
#define TABLESPACE_MAP
Definition: xlog.h:362
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define linitial(l)
Definition: pg_list.h:195
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
#define IsXLogFileName(fname)
XLogRecPtr do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
Definition: xlog.c:10697
void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli)
Definition: xlog.c:3846
#define MAXPGPATH
#define XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes)
static char * buf
Definition: pg_test_fsync.c:68
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:593
#define is_absolute_path(filename)
Definition: port.h:86
const char * label
Definition: basebackup.c:48
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2207
static void SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
Definition: basebackup.c:855
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:957
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1585
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
char * pgstat_stat_directory
Definition: pgstat.c:134
#define ereport(elevel, rest)
Definition: elog.h:141
static char * statrelpath
Definition: basebackup.c:81
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
List * lappend(List *list, void *datum)
Definition: list.c:321
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:264
#define MAXFNAMELEN
void * palloc0(Size size)
Definition: mcxt.c:955
#define XLOGDIR
uintptr_t Datum
Definition: postgres.h:367
#define XLOG_CONTROL_FILE
#define InvalidOid
Definition: postgres_ext.h:36
TimeLineID ThisTimeLineID
Definition: xlog.c:187
static TimestampTz throttled_last
Definition: basebackup.c:103
static StringInfo tblspc_map_file
Definition: xlogfuncs.c:46
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define lfirst(lc)
Definition: pg_list.h:190
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2534
#define THROTTLING_FREQUENCY
Definition: basebackup.c:91
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
#define lstat(path, sb)
Definition: win32_port.h:253
int FreeFile(FILE *file)
Definition: fd.c:2406
#define IsTLHistoryFileName(fname)
static int compareWalFileNames(const ListCell *a, const ListCell *b)
Definition: basebackup.c:618
static int64 sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, bool sendtblspclinks)
Definition: basebackup.c:1008
void list_sort(List *list, list_sort_comparator cmp)
Definition: list.c:1478
int errmsg(const char *fmt,...)
Definition: elog.c:784
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:298
#define TAR_SEND_SIZE
Definition: basebackup.c:86
char * DataDir
Definition: globals.c:62
#define BACKUP_LABEL_FILE
Definition: xlog.h:359
char d_name[MAX_PATH]
Definition: dirent.h:14
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:42
static int64 throttling_counter
Definition: basebackup.c:97
static void base_backup_cleanup(int code, Datum arg)
Definition: basebackup.c:214
Definition: pg_list.h:50
#define snprintf
Definition: port.h:192
static bool sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf, bool missing_ok, Oid dboid)
Definition: basebackup.c:1356
static uint64 throttling_sample
Definition: basebackup.c:94
static void sendFileWithContent(const char *filename, const char *content)
Definition: basebackup.c:910
int FreeDir(DIR *dir)
Definition: fd.c:2586
static TimeOffset elapsed_min_unit
Definition: basebackup.c:100
static XLogRecPtr startptr
Definition: basebackup.c:106
static long long int total_checksum_failures
Definition: basebackup.c:109
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ send_int8_string()

static void send_int8_string ( StringInfoData buf,
int64  intval 
)
static

Definition at line 767 of file basebackup.c.

References INT64_FORMAT, pq_sendbytes(), pq_sendint32(), and sprintf.

Referenced by SendBackupHeader().

768 {
769  char is[32];
770 
771  sprintf(is, INT64_FORMAT, intval);
772  pq_sendint32(buf, strlen(is));
773  pq_sendbytes(buf, is, strlen(is));
774 }
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
#define sprintf
Definition: port.h:194
#define INT64_FORMAT
Definition: c.h:400
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125

◆ SendBackupHeader()

static void SendBackupHeader ( List tablespaces)
static

Definition at line 777 of file basebackup.c.

References buf, lfirst, tablespaceinfo::oid, tablespaceinfo::path, pq_beginmessage(), pq_endmessage(), pq_puttextmessage(), pq_sendbytes(), pq_sendint16(), pq_sendint32(), pq_sendstring(), send_int8_string(), and tablespaceinfo::size.

Referenced by perform_base_backup().

778 {
780  ListCell *lc;
781 
782  /* Construct and send the directory information */
783  pq_beginmessage(&buf, 'T'); /* RowDescription */
784  pq_sendint16(&buf, 3); /* 3 fields */
785 
786  /* First field - spcoid */
787  pq_sendstring(&buf, "spcoid");
788  pq_sendint32(&buf, 0); /* table oid */
789  pq_sendint16(&buf, 0); /* attnum */
790  pq_sendint32(&buf, OIDOID); /* type oid */
791  pq_sendint16(&buf, 4); /* typlen */
792  pq_sendint32(&buf, 0); /* typmod */
793  pq_sendint16(&buf, 0); /* format code */
794 
795  /* Second field - spclocation */
796  pq_sendstring(&buf, "spclocation");
797  pq_sendint32(&buf, 0);
798  pq_sendint16(&buf, 0);
799  pq_sendint32(&buf, TEXTOID);
800  pq_sendint16(&buf, -1);
801  pq_sendint32(&buf, 0);
802  pq_sendint16(&buf, 0);
803 
804  /* Third field - size */
805  pq_sendstring(&buf, "size");
806  pq_sendint32(&buf, 0);
807  pq_sendint16(&buf, 0);
808  pq_sendint32(&buf, INT8OID);
809  pq_sendint16(&buf, 8);
810  pq_sendint32(&buf, 0);
811  pq_sendint16(&buf, 0);
812  pq_endmessage(&buf);
813 
814  foreach(lc, tablespaces)
815  {
816  tablespaceinfo *ti = lfirst(lc);
817 
818  /* Send one datarow message */
819  pq_beginmessage(&buf, 'D');
820  pq_sendint16(&buf, 3); /* number of columns */
821  if (ti->path == NULL)
822  {
823  pq_sendint32(&buf, -1); /* Length = -1 ==> NULL */
824  pq_sendint32(&buf, -1);
825  }
826  else
827  {
828  Size len;
829 
830  len = strlen(ti->oid);
831  pq_sendint32(&buf, len);
832  pq_sendbytes(&buf, ti->oid, len);
833 
834  len = strlen(ti->path);
835  pq_sendint32(&buf, len);
836  pq_sendbytes(&buf, ti->path, len);
837  }
838  if (ti->size >= 0)
839  send_int8_string(&buf, ti->size / 1024);
840  else
841  pq_sendint32(&buf, -1); /* NULL */
842 
843  pq_endmessage(&buf);
844  }
845 
846  /* Send a CommandComplete message */
847  pq_puttextmessage('C', "SELECT");
848 }
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137
void pq_sendstring(StringInfo buf, const char *str)
Definition: pqformat.c:197
static void send_int8_string(StringInfoData *buf, int64 intval)
Definition: basebackup.c:767
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:87
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static char * buf
Definition: pg_test_fsync.c:68
#define lfirst(lc)
Definition: pg_list.h:190
size_t Size
Definition: c.h:466
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:298
void pq_puttextmessage(char msgtype, const char *str)
Definition: pqformat.c:369

◆ SendBaseBackup()

void SendBaseBackup ( BaseBackupCmd cmd)

Definition at line 746 of file basebackup.c.

References basebackup_options::label, BaseBackupCmd::options, parse_basebackup_options(), perform_base_backup(), set_ps_display(), snprintf, update_process_title, WalSndSetState(), and WALSNDSTATE_BACKUP.

Referenced by exec_replication_command().

747 {
748  basebackup_options opt;
749 
750  parse_basebackup_options(cmd->options, &opt);
751 
753 
755  {
756  char activitymsg[50];
757 
758  snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"",
759  opt.label);
760  set_ps_display(activitymsg, false);
761  }
762 
763  perform_base_backup(&opt);
764 }
List * options
Definition: replnodes.h:44
bool update_process_title
Definition: ps_status.c:35
void set_ps_display(const char *activity, bool force)
Definition: ps_status.c:331
static void parse_basebackup_options(List *options, basebackup_options *opt)
Definition: basebackup.c:630
const char * label
Definition: basebackup.c:48
static void perform_base_backup(basebackup_options *opt)
Definition: basebackup.c:226
void WalSndSetState(WalSndState state)
Definition: walsender.c:3177
#define snprintf
Definition: port.h:192

◆ sendDir()

static int64 sendDir ( const char *  path,
int  basepathlen,
bool  sizeonly,
List tablespaces,
bool  sendtblspclinks 
)
static

Definition at line 1008 of file basebackup.c.

References _tarWriteDir(), _tarWriteHeader(), AllocateDir(), backup_started_in_recovery, CHECK_FOR_INTERRUPTS, dirent::d_name, DEBUG1, DEBUG2, elog, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, excludeDirContents, excludeFiles, FreeDir(), INIT_FORKNUM, InvalidOid, last_dir_separator(), lfirst, looks_like_temp_rel_name(), lstat, MAXPGPATH, OIDCHARS, parse_filename_for_nontemp_relation(), pg_atoi(), PG_TEMP_FILE_PREFIX, pgwin32_is_junction(), ReadDir(), readlink, RecoveryInProgress(), tablespaceinfo::rpath, S_ISDIR, S_ISREG, sendFile(), snprintf, stat, statrelpath, TABLESPACE_VERSION_DIRECTORY, and WARNING.

Referenced by perform_base_backup(), and sendTablespace().

1010 {
1011  DIR *dir;
1012  struct dirent *de;
1013  char pathbuf[MAXPGPATH * 2];
1014  struct stat statbuf;
1015  int64 size = 0;
1016  const char *lastDir; /* Split last dir from parent path. */
1017  bool isDbDir = false; /* Does this directory contain relations? */
1018 
1019  /*
1020  * Determine if the current path is a database directory that can contain
1021  * relations.
1022  *
1023  * Start by finding the location of the delimiter between the parent path
1024  * and the current path.
1025  */
1026  lastDir = last_dir_separator(path);
1027 
1028  /* Does this path look like a database path (i.e. all digits)? */
1029  if (lastDir != NULL &&
1030  strspn(lastDir + 1, "0123456789") == strlen(lastDir + 1))
1031  {
1032  /* Part of path that contains the parent directory. */
1033  int parentPathLen = lastDir - path;
1034 
1035  /*
1036  * Mark path as a database directory if the parent path is either
1037  * $PGDATA/base or a tablespace version path.
1038  */
1039  if (strncmp(path, "./base", parentPathLen) == 0 ||
1040  (parentPathLen >= (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) &&
1041  strncmp(lastDir - (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1),
1043  sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) == 0))
1044  isDbDir = true;
1045  }
1046 
1047  dir = AllocateDir(path);
1048  while ((de = ReadDir(dir, path)) != NULL)
1049  {
1050  int excludeIdx;
1051  bool excludeFound;
1052  ForkNumber relForkNum; /* Type of fork if file is a relation */
1053  int relOidChars; /* Chars in filename that are the rel oid */
1054 
1055  /* Skip special stuff */
1056  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
1057  continue;
1058 
1059  /* Skip temporary files */
1060  if (strncmp(de->d_name,
1062  strlen(PG_TEMP_FILE_PREFIX)) == 0)
1063  continue;
1064 
1065  /*
1066  * Check if the postmaster has signaled us to exit, and abort with an
1067  * error in that case. The error handler further up will call
1068  * do_pg_abort_backup() for us. Also check that if the backup was
1069  * started while still in recovery, the server wasn't promoted.
1070  * do_pg_stop_backup() will check that too, but it's better to stop
1071  * the backup early than continue to the end and fail there.
1072  */
1075  ereport(ERROR,
1076  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1077  errmsg("the standby was promoted during online backup"),
1078  errhint("This means that the backup being taken is corrupt "
1079  "and should not be used. "
1080  "Try taking another online backup.")));
1081 
1082  /* Scan for files that should be excluded */
1083  excludeFound = false;
1084  for (excludeIdx = 0; excludeFiles[excludeIdx] != NULL; excludeIdx++)
1085  {
1086  if (strcmp(de->d_name, excludeFiles[excludeIdx]) == 0)
1087  {
1088  elog(DEBUG1, "file \"%s\" excluded from backup", de->d_name);
1089  excludeFound = true;
1090  break;
1091  }
1092  }
1093 
1094  if (excludeFound)
1095  continue;
1096 
1097  /* Exclude all forks for unlogged tables except the init fork */
1098  if (isDbDir &&
1099  parse_filename_for_nontemp_relation(de->d_name, &relOidChars,
1100  &relForkNum))
1101  {
1102  /* Never exclude init forks */
1103  if (relForkNum != INIT_FORKNUM)
1104  {
1105  char initForkFile[MAXPGPATH];
1106  char relOid[OIDCHARS + 1];
1107 
1108  /*
1109  * If any other type of fork, check if there is an init fork
1110  * with the same OID. If so, the file can be excluded.
1111  */
1112  memcpy(relOid, de->d_name, relOidChars);
1113  relOid[relOidChars] = '\0';
1114  snprintf(initForkFile, sizeof(initForkFile), "%s/%s_init",
1115  path, relOid);
1116 
1117  if (lstat(initForkFile, &statbuf) == 0)
1118  {
1119  elog(DEBUG2,
1120  "unlogged relation file \"%s\" excluded from backup",
1121  de->d_name);
1122 
1123  continue;
1124  }
1125  }
1126  }
1127 
1128  /* Exclude temporary relations */
1129  if (isDbDir && looks_like_temp_rel_name(de->d_name))
1130  {
1131  elog(DEBUG2,
1132  "temporary relation file \"%s\" excluded from backup",
1133  de->d_name);
1134 
1135  continue;
1136  }
1137 
1138  snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
1139 
1140  /* Skip pg_control here to back up it last */
1141  if (strcmp(pathbuf, "./global/pg_control") == 0)
1142  continue;
1143 
1144  if (lstat(pathbuf, &statbuf) != 0)
1145  {
1146  if (errno != ENOENT)
1147  ereport(ERROR,
1149  errmsg("could not stat file or directory \"%s\": %m",
1150  pathbuf)));
1151 
1152  /* If the file went away while scanning, it's not an error. */
1153  continue;
1154  }
1155 
1156  /* Scan for directories whose contents should be excluded */
1157  excludeFound = false;
1158  for (excludeIdx = 0; excludeDirContents[excludeIdx] != NULL; excludeIdx++)
1159  {
1160  if (strcmp(de->d_name, excludeDirContents[excludeIdx]) == 0)
1161  {
1162  elog(DEBUG1, "contents of directory \"%s\" excluded from backup", de->d_name);
1163  size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
1164  excludeFound = true;
1165  break;
1166  }
1167  }
1168 
1169  if (excludeFound)
1170  continue;
1171 
1172  /*
1173  * Exclude contents of directory specified by statrelpath if not set
1174  * to the default (pg_stat_tmp) which is caught in the loop above.
1175  */
1176  if (statrelpath != NULL && strcmp(pathbuf, statrelpath) == 0)
1177  {
1178  elog(DEBUG1, "contents of directory \"%s\" excluded from backup", statrelpath);
1179  size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
1180  continue;
1181  }
1182 
1183  /*
1184  * We can skip pg_wal, the WAL segments need to be fetched from the
1185  * WAL archive anyway. But include it as an empty directory anyway, so
1186  * we get permissions right.
1187  */
1188  if (strcmp(pathbuf, "./pg_wal") == 0)
1189  {
1190  /* If pg_wal is a symlink, write it as a directory anyway */
1191  size += _tarWriteDir(pathbuf, basepathlen, &statbuf, sizeonly);
1192 
1193  /*
1194  * Also send archive_status directory (by hackishly reusing
1195  * statbuf from above ...).
1196  */
1197  size += _tarWriteHeader("./pg_wal/archive_status", NULL, &statbuf,
1198  sizeonly);
1199 
1200  continue; /* don't recurse into pg_wal */
1201  }
1202 
1203  /* Allow symbolic links in pg_tblspc only */
1204  if (strcmp(path, "./pg_tblspc") == 0 &&
1205 #ifndef WIN32
1206  S_ISLNK(statbuf.st_mode)
1207 #else
1208  pgwin32_is_junction(pathbuf)
1209 #endif
1210  )
1211  {
1212 #if defined(HAVE_READLINK) || defined(WIN32)
1213  char linkpath[MAXPGPATH];
1214  int rllen;
1215 
1216  rllen = readlink(pathbuf, linkpath, sizeof(linkpath));
1217  if (rllen < 0)
1218  ereport(ERROR,
1220  errmsg("could not read symbolic link \"%s\": %m",
1221  pathbuf)));
1222  if (rllen >= sizeof(linkpath))
1223  ereport(ERROR,
1224  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1225  errmsg("symbolic link \"%s\" target is too long",
1226  pathbuf)));
1227  linkpath[rllen] = '\0';
1228 
1229  size += _tarWriteHeader(pathbuf + basepathlen + 1, linkpath,
1230  &statbuf, sizeonly);
1231 #else
1232 
1233  /*
1234  * If the platform does not have symbolic links, it should not be
1235  * possible to have tablespaces - clearly somebody else created
1236  * them. Warn about it and ignore.
1237  */
1238  ereport(WARNING,
1239  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1240  errmsg("tablespaces are not supported on this platform")));
1241  continue;
1242 #endif /* HAVE_READLINK */
1243  }
1244  else if (S_ISDIR(statbuf.st_mode))
1245  {
1246  bool skip_this_dir = false;
1247  ListCell *lc;
1248 
1249  /*
1250  * Store a directory entry in the tar file so we can get the
1251  * permissions right.
1252  */
1253  size += _tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf,
1254  sizeonly);
1255 
1256  /*
1257  * Call ourselves recursively for a directory, unless it happens
1258  * to be a separate tablespace located within PGDATA.
1259  */
1260  foreach(lc, tablespaces)
1261  {
1262  tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc);
1263 
1264  /*
1265  * ti->rpath is the tablespace relative path within PGDATA, or
1266  * NULL if the tablespace has been properly located somewhere
1267  * else.
1268  *
1269  * Skip past the leading "./" in pathbuf when comparing.
1270  */
1271  if (ti->rpath && strcmp(ti->rpath, pathbuf + 2) == 0)
1272  {
1273  skip_this_dir = true;
1274  break;
1275  }
1276  }
1277 
1278  /*
1279  * skip sending directories inside pg_tblspc, if not required.
1280  */
1281  if (strcmp(pathbuf, "./pg_tblspc") == 0 && !sendtblspclinks)
1282  skip_this_dir = true;
1283 
1284  if (!skip_this_dir)
1285  size += sendDir(pathbuf, basepathlen, sizeonly, tablespaces, sendtblspclinks);
1286  }
1287  else if (S_ISREG(statbuf.st_mode))
1288  {
1289  bool sent = false;
1290 
1291  if (!sizeonly)
1292  sent = sendFile(pathbuf, pathbuf + basepathlen + 1, &statbuf,
1293  true, isDbDir ? pg_atoi(lastDir + 1, sizeof(Oid), 0) : InvalidOid);
1294 
1295  if (sent || sizeonly)
1296  {
1297  /* Add size, rounded up to 512byte block */
1298  size += ((statbuf.st_size + 511) & ~511);
1299  size += 512; /* Size of the header of the file */
1300  }
1301  }
1302  else
1303  ereport(WARNING,
1304  (errmsg("skipping special file \"%s\"", pathbuf)));
1305  }
1306  FreeDir(dir);
1307  return size;
1308 }
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:974
char * rpath
Definition: basebackup.h:28
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7898
static bool backup_started_in_recovery
Definition: basebackup.c:78
Definition: dirent.h:9
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
#define readlink(path, buf, size)
Definition: win32_port.h:231
int errcode_for_file_access(void)
Definition: elog.c:593
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1585
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
static const char * excludeFiles[]
Definition: basebackup.c:163
#define ereport(elevel, rest)
Definition: elog.h:141
static char * statrelpath
Definition: basebackup.c:81
ForkNumber
Definition: relpath.h:40
#define S_ISREG(m)
Definition: win32_port.h:308
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:264
char * last_dir_separator(const char *filename)
Definition: path.c:138
#define InvalidOid
Definition: postgres_ext.h:36
#define lfirst(lc)
Definition: pg_list.h:190
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2534
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3067
bool parse_filename_for_nontemp_relation(const char *name, int *oidchars, ForkNumber *fork)
Definition: reinit.c:374
#define S_ISDIR(m)
Definition: win32_port.h:305
#define lstat(path, sb)
Definition: win32_port.h:253
static int64 sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, bool sendtblspclinks)
Definition: basebackup.c:1008
int errmsg(const char *fmt,...)
Definition: elog.c:784
static const char * excludeDirContents[]
Definition: basebackup.c:122
#define elog(elevel,...)
Definition: elog.h:226
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
static bool sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf, bool missing_ok, Oid dboid)
Definition: basebackup.c:1356
#define OIDCHARS
Definition: relpath.h:30
int FreeDir(DIR *dir)
Definition: fd.c:2586
int32 pg_atoi(const char *s, int size, int c)
Definition: numutils.c:38
bool pgwin32_is_junction(const char *path)
static int64 _tarWriteDir(const char *pathbuf, int basepathlen, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1627

◆ sendFile()

static bool sendFile ( const char *  readfilename,
const char *  tarfilename,
struct stat statbuf,
bool  missing_ok,
Oid  dboid 
)
static

Definition at line 1356 of file basebackup.c.

References _tarWriteHeader(), AllocateFile(), Assert, buf, DataChecksumsEnabled(), ereport, errcode_for_file_access(), errmsg(), ERROR, filename, FreeFile(), i, is_checksummed_file(), last_dir_separator(), MemSet, Min, noverify_checksums, PageGetLSN, PageIsNew, PageHeaderData::pd_checksum, pg_checksum_page(), pgoff_t, pgstat_report_checksum_failures_in_db(), pq_putmessage, startptr, TAR_SEND_SIZE, throttle(), total_checksum_failures, and WARNING.

Referenced by perform_base_backup(), and sendDir().

1358 {
1359  FILE *fp;
1360  BlockNumber blkno = 0;
1361  bool block_retry = false;
1362  char buf[TAR_SEND_SIZE];
1363  uint16 checksum;
1364  int checksum_failures = 0;
1365  off_t cnt;
1366  int i;
1367  pgoff_t len = 0;
1368  char *page;
1369  size_t pad;
1370  PageHeader phdr;
1371  int segmentno = 0;
1372  char *segmentpath;
1373  bool verify_checksum = false;
1374 
1375  fp = AllocateFile(readfilename, "rb");
1376  if (fp == NULL)
1377  {
1378  if (errno == ENOENT && missing_ok)
1379  return false;
1380  ereport(ERROR,
1382  errmsg("could not open file \"%s\": %m", readfilename)));
1383  }
1384 
1385  _tarWriteHeader(tarfilename, NULL, statbuf, false);
1386 
1388  {
1389  char *filename;
1390 
1391  /*
1392  * Get the filename (excluding path). As last_dir_separator()
1393  * includes the last directory separator, we chop that off by
1394  * incrementing the pointer.
1395  */
1396  filename = last_dir_separator(readfilename) + 1;
1397 
1398  if (is_checksummed_file(readfilename, filename))
1399  {
1400  verify_checksum = true;
1401 
1402  /*
1403  * Cut off at the segment boundary (".") to get the segment number
1404  * in order to mix it into the checksum.
1405  */
1406  segmentpath = strstr(filename, ".");
1407  if (segmentpath != NULL)
1408  {
1409  segmentno = atoi(segmentpath + 1);
1410  if (segmentno == 0)
1411  ereport(ERROR,
1412  (errmsg("invalid segment number %d in file \"%s\"",
1413  segmentno, filename)));
1414  }
1415  }
1416  }
1417 
1418  while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0)
1419  {
1420  /*
1421  * The checksums are verified at block level, so we iterate over the
1422  * buffer in chunks of BLCKSZ, after making sure that
1423  * TAR_SEND_SIZE/buf is divisible by BLCKSZ and we read a multiple of
1424  * BLCKSZ bytes.
1425  */
1426  Assert(TAR_SEND_SIZE % BLCKSZ == 0);
1427 
1428  if (verify_checksum && (cnt % BLCKSZ != 0))
1429  {
1430  ereport(WARNING,
1431  (errmsg("cannot verify checksum in file \"%s\", block "
1432  "%d: read buffer size %d and page size %d "
1433  "differ",
1434  readfilename, blkno, (int) cnt, BLCKSZ)));
1435  verify_checksum = false;
1436  }
1437 
1438  if (verify_checksum)
1439  {
1440  for (i = 0; i < cnt / BLCKSZ; i++)
1441  {
1442  page = buf + BLCKSZ * i;
1443 
1444  /*
1445  * Only check pages which have not been modified since the
1446  * start of the base backup. Otherwise, they might have been
1447  * written only halfway and the checksum would not be valid.
1448  * However, replaying WAL would reinstate the correct page in
1449  * this case. We also skip completely new pages, since they
1450  * don't have a checksum yet.
1451  */
1452  if (!PageIsNew(page) && PageGetLSN(page) < startptr)
1453  {
1454  checksum = pg_checksum_page((char *) page, blkno + segmentno * RELSEG_SIZE);
1455  phdr = (PageHeader) page;
1456  if (phdr->pd_checksum != checksum)
1457  {
1458  /*
1459  * Retry the block on the first failure. It's
1460  * possible that we read the first 4K page of the
1461  * block just before postgres updated the entire block
1462  * so it ends up looking torn to us. We only need to
1463  * retry once because the LSN should be updated to
1464  * something we can ignore on the next pass. If the
1465  * error happens again then it is a true validation
1466  * failure.
1467  */
1468  if (block_retry == false)
1469  {
1470  /* Reread the failed block */
1471  if (fseek(fp, -(cnt - BLCKSZ * i), SEEK_CUR) == -1)
1472  {
1473  ereport(ERROR,
1475  errmsg("could not fseek in file \"%s\": %m",
1476  readfilename)));
1477  }
1478 
1479  if (fread(buf + BLCKSZ * i, 1, BLCKSZ, fp) != BLCKSZ)
1480  {
1481  ereport(ERROR,
1483  errmsg("could not reread block %d of file \"%s\": %m",
1484  blkno, readfilename)));
1485  }
1486 
1487  if (fseek(fp, cnt - BLCKSZ * i - BLCKSZ, SEEK_CUR) == -1)
1488  {
1489  ereport(ERROR,
1491  errmsg("could not fseek in file \"%s\": %m",
1492  readfilename)));
1493  }
1494 
1495  /* Set flag so we know a retry was attempted */
1496  block_retry = true;
1497 
1498  /* Reset loop to validate the block again */
1499  i--;
1500  continue;
1501  }
1502 
1503  checksum_failures++;
1504 
1505  if (checksum_failures <= 5)
1506  ereport(WARNING,
1507  (errmsg("checksum verification failed in "
1508  "file \"%s\", block %d: calculated "
1509  "%X but expected %X",
1510  readfilename, blkno, checksum,
1511  phdr->pd_checksum)));
1512  if (checksum_failures == 5)
1513  ereport(WARNING,
1514  (errmsg("further checksum verification "
1515  "failures in file \"%s\" will not "
1516  "be reported", readfilename)));
1517  }
1518  }
1519  block_retry = false;
1520  blkno++;
1521  }
1522  }
1523 
1524  /* Send the chunk as a CopyData message */
1525  if (pq_putmessage('d', buf, cnt))
1526  ereport(ERROR,
1527  (errmsg("base backup could not send data, aborting backup")));
1528 
1529  len += cnt;
1530  throttle(cnt);
1531 
1532  if (len >= statbuf->st_size)
1533  {
1534  /*
1535  * Reached end of file. The file could be longer, if it was
1536  * extended while we were sending it, but for a base backup we can
1537  * ignore such extended data. It will be restored from WAL.
1538  */
1539  break;
1540  }
1541  }
1542 
1543  /* If the file was truncated while we were sending it, pad it with zeros */
1544  if (len < statbuf->st_size)
1545  {
1546  MemSet(buf, 0, sizeof(buf));
1547  while (len < statbuf->st_size)
1548  {
1549  cnt = Min(sizeof(buf), statbuf->st_size - len);
1550  pq_putmessage('d', buf, cnt);
1551  len += cnt;
1552  throttle(cnt);
1553  }
1554  }
1555 
1556  /*
1557  * Pad to 512 byte boundary, per tar format requirements. (This small
1558  * piece of data is probably not worth throttling.)
1559  */
1560  pad = ((len + 511) & ~511) - len;
1561  if (pad > 0)
1562  {
1563  MemSet(buf, 0, pad);
1564  pq_putmessage('d', buf, pad);
1565  }
1566 
1567  FreeFile(fp);
1568 
1569  if (checksum_failures > 1)
1570  {
1571  ereport(WARNING,
1572  (errmsg("file \"%s\" has a total of %d checksum verification "
1573  "failures", readfilename, checksum_failures)));
1574 
1575  pgstat_report_checksum_failures_in_db(dboid, checksum_failures);
1576  }
1577 
1578  total_checksum_failures += checksum_failures;
1579 
1580  return true;
1581 }
static void throttle(size_t increment)
Definition: basebackup.c:1647
bool DataChecksumsEnabled(void)
Definition: xlog.c:4822
#define Min(x, y)
Definition: c.h:904
#define MemSet(start, val, len)
Definition: c.h:955
uint32 BlockNumber
Definition: block.h:31
void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount)
Definition: pgstat.c:1532
uint16 pd_checksum
Definition: bufpage.h:156
#define pgoff_t
Definition: win32_port.h:204
unsigned short uint16
Definition: c.h:357
#define ERROR
Definition: elog.h:43
static bool noverify_checksums
Definition: basebackup.c:112
static char * buf
Definition: pg_test_fsync.c:68
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2207
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1585
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
char * last_dir_separator(const char *filename)
Definition: path.c:138
static bool is_checksummed_file(const char *fullpath, const char *filename)
Definition: basebackup.c:1317
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:732
#define PageGetLSN(page)
Definition: bufpage.h:366
int FreeFile(FILE *file)
Definition: fd.c:2406
static char * filename
Definition: pg_dumpall.c:91
#define PageIsNew(page)
Definition: bufpage.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define TAR_SEND_SIZE
Definition: basebackup.c:86
int i
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:42
uint16 pg_checksum_page(char *page, BlockNumber blkno)
static XLogRecPtr startptr
Definition: basebackup.c:106
static long long int total_checksum_failures
Definition: basebackup.c:109

◆ sendFileWithContent()

static void sendFileWithContent ( const char *  filename,
const char *  content 
)
static

Definition at line 910 of file basebackup.c.

References _tarWriteHeader(), buf, MemSet, pg_file_create_mode, pq_putmessage, and stat.

Referenced by perform_base_backup().

911 {
912  struct stat statbuf;
913  int pad,
914  len;
915 
916  len = strlen(content);
917 
918  /*
919  * Construct a stat struct for the backup_label file we're injecting in
920  * the tar.
921  */
922  /* Windows doesn't have the concept of uid and gid */
923 #ifdef WIN32
924  statbuf.st_uid = 0;
925  statbuf.st_gid = 0;
926 #else
927  statbuf.st_uid = geteuid();
928  statbuf.st_gid = getegid();
929 #endif
930  statbuf.st_mtime = time(NULL);
931  statbuf.st_mode = pg_file_create_mode;
932  statbuf.st_size = len;
933 
934  _tarWriteHeader(filename, NULL, &statbuf, false);
935  /* Send the contents as a CopyData message */
936  pq_putmessage('d', content, len);
937 
938  /* Pad to 512 byte boundary, per tar format requirements */
939  pad = ((len + 511) & ~511) - len;
940  if (pad > 0)
941  {
942  char buf[512];
943 
944  MemSet(buf, 0, pad);
945  pq_putmessage('d', buf, pad);
946  }
947 }
int pg_file_create_mode
Definition: file_perm.c:19
#define MemSet(start, val, len)
Definition: c.h:955
static char * buf
Definition: pg_test_fsync.c:68
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1585
#define stat(a, b)
Definition: win32_port.h:264
static char * filename
Definition: pg_dumpall.c:91
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:42

◆ sendTablespace()

int64 sendTablespace ( char *  path,
bool  sizeonly 
)

Definition at line 957 of file basebackup.c.

References _tarWriteHeader(), ereport, errcode_for_file_access(), errmsg(), ERROR, lstat, MAXPGPATH, NIL, sendDir(), snprintf, stat, and TABLESPACE_VERSION_DIRECTORY.

Referenced by do_pg_start_backup(), and perform_base_backup().

958 {
959  int64 size;
960  char pathbuf[MAXPGPATH];
961  struct stat statbuf;
962 
963  /*
964  * 'path' points to the tablespace location, but we only want to include
965  * the version directory in it that belongs to us.
966  */
967  snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path,
969 
970  /*
971  * Store a directory entry in the tar file so we get the permissions
972  * right.
973  */
974  if (lstat(pathbuf, &statbuf) != 0)
975  {
976  if (errno != ENOENT)
977  ereport(ERROR,
979  errmsg("could not stat file or directory \"%s\": %m",
980  pathbuf)));
981 
982  /* If the tablespace went away while scanning, it's no error. */
983  return 0;
984  }
985 
986  size = _tarWriteHeader(TABLESPACE_VERSION_DIRECTORY, NULL, &statbuf,
987  sizeonly);
988 
989  /* Send all the files in the tablespace version directory */
990  size += sendDir(pathbuf, strlen(path), sizeonly, NIL, true);
991 
992  return size;
993 }
#define NIL
Definition: pg_list.h:65
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
int errcode_for_file_access(void)
Definition: elog.c:593
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1585
#define ereport(elevel, rest)
Definition: elog.h:141
#define stat(a, b)
Definition: win32_port.h:264
#define lstat(path, sb)
Definition: win32_port.h:253
static int64 sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, bool sendtblspclinks)
Definition: basebackup.c:1008
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define snprintf
Definition: port.h:192

◆ SendXlogRecPtrResult()

static void SendXlogRecPtrResult ( XLogRecPtr  ptr,
TimeLineID  tli 
)
static

Definition at line 855 of file basebackup.c.

References buf, MAXFNAMELEN, pq_beginmessage(), pq_endmessage(), pq_puttextmessage(), pq_sendbytes(), pq_sendint16(), pq_sendint32(), pq_sendstring(), snprintf, and generate_unaccent_rules::str.

Referenced by perform_base_backup().

856 {
858  char str[MAXFNAMELEN];
859  Size len;
860 
861  pq_beginmessage(&buf, 'T'); /* RowDescription */
862  pq_sendint16(&buf, 2); /* 2 fields */
863 
864  /* Field headers */
865  pq_sendstring(&buf, "recptr");
866  pq_sendint32(&buf, 0); /* table oid */
867  pq_sendint16(&buf, 0); /* attnum */
868  pq_sendint32(&buf, TEXTOID); /* type oid */
869  pq_sendint16(&buf, -1);
870  pq_sendint32(&buf, 0);
871  pq_sendint16(&buf, 0);
872 
873  pq_sendstring(&buf, "tli");
874  pq_sendint32(&buf, 0); /* table oid */
875  pq_sendint16(&buf, 0); /* attnum */
876 
877  /*
878  * int8 may seem like a surprising data type for this, but in theory int4
879  * would not be wide enough for this, as TimeLineID is unsigned.
880  */
881  pq_sendint32(&buf, INT8OID); /* type oid */
882  pq_sendint16(&buf, -1);
883  pq_sendint32(&buf, 0);
884  pq_sendint16(&buf, 0);
885  pq_endmessage(&buf);
886 
887  /* Data row */
888  pq_beginmessage(&buf, 'D');
889  pq_sendint16(&buf, 2); /* number of columns */
890 
891  len = snprintf(str, sizeof(str),
892  "%X/%X", (uint32) (ptr >> 32), (uint32) ptr);
893  pq_sendint32(&buf, len);
894  pq_sendbytes(&buf, str, len);
895 
896  len = snprintf(str, sizeof(str), "%u", tli);
897  pq_sendint32(&buf, len);
898  pq_sendbytes(&buf, str, len);
899 
900  pq_endmessage(&buf);
901 
902  /* Send a CommandComplete message */
903  pq_puttextmessage('C', "SELECT");
904 }
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137
void pq_sendstring(StringInfo buf, const char *str)
Definition: pqformat.c:197
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:87
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static char * buf
Definition: pg_test_fsync.c:68
unsigned int uint32
Definition: c.h:358
#define MAXFNAMELEN
size_t Size
Definition: c.h:466
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:298
void pq_puttextmessage(char msgtype, const char *str)
Definition: pqformat.c:369
#define snprintf
Definition: port.h:192

◆ throttle()

static void throttle ( size_t  increment)
static

Definition at line 1647 of file basebackup.c.

References CHECK_FOR_INTERRUPTS, elapsed_min_unit, GetCurrentTimestamp(), MyLatch, ResetLatch(), throttled_last, throttling_counter, throttling_sample, WAIT_EVENT_BASE_BACKUP_THROTTLE, WaitLatch(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_TIMEOUT.

Referenced by perform_base_backup(), and sendFile().

1648 {
1649  TimeOffset elapsed_min;
1650 
1651  if (throttling_counter < 0)
1652  return;
1653 
1654  throttling_counter += increment;
1656  return;
1657 
1658  /* How much time should have elapsed at minimum? */
1659  elapsed_min = elapsed_min_unit *
1661 
1662  /*
1663  * Since the latch could be set repeatedly because of concurrently WAL
1664  * activity, sleep in a loop to ensure enough time has passed.
1665  */
1666  for (;;)
1667  {
1668  TimeOffset elapsed,
1669  sleep;
1670  int wait_result;
1671 
1672  /* Time elapsed since the last measurement (and possible wake up). */
1673  elapsed = GetCurrentTimestamp() - throttled_last;
1674 
1675  /* sleep if the transfer is faster than it should be */
1676  sleep = elapsed_min - elapsed;
1677  if (sleep <= 0)
1678  break;
1679 
1681 
1682  /* We're eating a potentially set latch, so check for interrupts */
1684 
1685  /*
1686  * (TAR_SEND_SIZE / throttling_sample * elapsed_min_unit) should be
1687  * the maximum time to sleep. Thus the cast to long is safe.
1688  */
1689  wait_result = WaitLatch(MyLatch,
1691  (long) (sleep / 1000),
1693 
1694  if (wait_result & WL_LATCH_SET)
1696 
1697  /* Done waiting? */
1698  if (wait_result & WL_TIMEOUT)
1699  break;
1700  }
1701 
1702  /*
1703  * As we work with integers, only whole multiple of throttling_sample was
1704  * processed. The rest will be done during the next call of this function.
1705  */
1707 
1708  /*
1709  * Time interval for the remaining amount and possible next increments
1710  * starts now.
1711  */
1713 }
#define WL_TIMEOUT
Definition: latch.h:127
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
void ResetLatch(Latch *latch)
Definition: latch.c:519
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:344
int64 TimeOffset
Definition: timestamp.h:40
static TimestampTz throttled_last
Definition: basebackup.c:103
struct Latch * MyLatch
Definition: globals.c:54
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
static int64 throttling_counter
Definition: basebackup.c:97
#define WL_LATCH_SET
Definition: latch.h:124
static uint64 throttling_sample
Definition: basebackup.c:94
static TimeOffset elapsed_min_unit
Definition: basebackup.c:100
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

Variable Documentation

◆ backup_started_in_recovery

bool backup_started_in_recovery = false
static

Definition at line 78 of file basebackup.c.

Referenced by do_pg_start_backup(), do_pg_stop_backup(), perform_base_backup(), and sendDir().

◆ elapsed_min_unit

TimeOffset elapsed_min_unit
static

Definition at line 100 of file basebackup.c.

Referenced by perform_base_backup(), and throttle().

◆ excludeDirContents

const char* excludeDirContents[]
static
Initial value:
=
{
"pg_replslot",
"pg_notify",
"pg_serial",
"pg_snapshots",
"pg_subtrans",
NULL
}
#define PG_DYNSHMEM_DIR
Definition: dsm_impl.h:50
#define PG_STAT_TMP_DIR
Definition: pgstat.h:33

Definition at line 122 of file basebackup.c.

Referenced by sendDir().

◆ excludeFiles

const char* excludeFiles[]
static
Initial value:
=
{
"postmaster.pid",
"postmaster.opts",
NULL
}
#define TABLESPACE_MAP
Definition: xlog.h:362
#define RELCACHE_INIT_FILENAME
Definition: relcache.h:24
#define PG_AUTOCONF_FILENAME
Definition: guc.h:34
#define LOG_METAINFO_DATAFILE_TMP
Definition: syslogger.h:98
#define BACKUP_LABEL_FILE
Definition: xlog.h:359

Definition at line 163 of file basebackup.c.

Referenced by sendDir().

◆ noChecksumFiles

const char* const noChecksumFiles[]
static
Initial value:
= {
"pg_control",
"pg_filenode.map",
"pg_internal.init",
"PG_VERSION",
NULL,
}

Definition at line 196 of file basebackup.c.

Referenced by is_checksummed_file().

◆ noverify_checksums

bool noverify_checksums = false
static

Definition at line 112 of file basebackup.c.

Referenced by parse_basebackup_options(), and sendFile().

◆ startptr

◆ statrelpath

char* statrelpath = NULL
static

Definition at line 81 of file basebackup.c.

Referenced by perform_base_backup(), and sendDir().

◆ throttled_last

TimestampTz throttled_last
static

Definition at line 103 of file basebackup.c.

Referenced by perform_base_backup(), and throttle().

◆ throttling_counter

int64 throttling_counter
static

Definition at line 97 of file basebackup.c.

Referenced by perform_base_backup(), and throttle().

◆ throttling_sample

uint64 throttling_sample
static

Definition at line 94 of file basebackup.c.

Referenced by perform_base_backup(), and throttle().

◆ total_checksum_failures

long long int total_checksum_failures
static

Definition at line 109 of file basebackup.c.

Referenced by perform_base_backup(), and sendFile().