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)
 
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 void *a, const void *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 int64 total_checksum_failures
 
static bool noverify_checksums = false
 
static const char * excludeDirContents []
 
static const char * excludeFiles []
 
static const char * 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 1623 of file basebackup.c.

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

Referenced by sendDir().

1625 {
1626  /* If symlink, write it as a directory anyway */
1627 #ifndef WIN32
1628  if (S_ISLNK(statbuf->st_mode))
1629 #else
1630  if (pgwin32_is_junction(pathbuf))
1631 #endif
1632  statbuf->st_mode = S_IFDIR | pg_dir_create_mode;
1633 
1634  return _tarWriteHeader(pathbuf + basepathlen + 1, NULL, statbuf, sizeonly);
1635 }
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1581
int pg_dir_create_mode
Definition: file_perm.c:19
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 1581 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().

1583 {
1584  char h[512];
1585  enum tarError rc;
1586 
1587  if (!sizeonly)
1588  {
1589  rc = tarCreateHeader(h, filename, linktarget, statbuf->st_size,
1590  statbuf->st_mode, statbuf->st_uid, statbuf->st_gid,
1591  statbuf->st_mtime);
1592 
1593  switch (rc)
1594  {
1595  case TAR_OK:
1596  break;
1597  case TAR_NAME_TOO_LONG:
1598  ereport(ERROR,
1599  (errmsg("file name too long for tar format: \"%s\"",
1600  filename)));
1601  break;
1602  case TAR_SYMLINK_TOO_LONG:
1603  ereport(ERROR,
1604  (errmsg("symbolic link target too long for tar format: "
1605  "file name \"%s\", target \"%s\"",
1606  filename, linktarget)));
1607  break;
1608  default:
1609  elog(ERROR, "unrecognized tar error: %d", rc);
1610  }
1611 
1612  pq_putmessage('d', h, sizeof(h));
1613  }
1614 
1615  return sizeof(h);
1616 }
Definition: pgtar.h:17
tarError
Definition: pgtar.h:15
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
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:87
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#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 207 of file basebackup.c.

References do_pg_abort_backup().

Referenced by perform_base_backup().

208 {
210 }
void do_pg_abort_backup(void)
Definition: xlog.c:11166

◆ compareWalFileNames()

static int compareWalFileNames ( const void *  a,
const void *  b 
)
static

Definition at line 620 of file basebackup.c.

Referenced by perform_base_backup().

621 {
622  char *fna = *((char **) a);
623  char *fnb = *((char **) b);
624 
625  return strcmp(fna + 8, fnb + 8);
626 }

◆ is_checksummed_file()

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

Definition at line 1319 of file basebackup.c.

References noChecksumFiles.

Referenced by sendFile().

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

◆ parse_basebackup_options()

static void parse_basebackup_options ( List options,
basebackup_options opt 
)
static

Definition at line 632 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().

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

◆ perform_base_backup()

static void perform_base_backup ( basebackup_options opt)
static

Definition at line 219 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(), i, basebackup_options::includewal, INT64_FORMAT, is_absolute_path, IsTLHistoryFileName, IsXLogFileName, basebackup_options::label, lappend(), lfirst, list_length(), lnext, lstat, makeStringInfo(), MAXFNAMELEN, MAXPGPATH, basebackup_options::maxrate, Min, NIL, basebackup_options::nowait, palloc(), 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(), qsort, 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().

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

◆ send_int8_string()

static void send_int8_string ( StringInfoData buf,
int64  intval 
)
static

Definition at line 769 of file basebackup.c.

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

Referenced by SendBackupHeader().

770 {
771  char is[32];
772 
773  sprintf(is, INT64_FORMAT, intval);
774  pq_sendint32(buf, strlen(is));
775  pq_sendbytes(buf, is, strlen(is));
776 }
static void pq_sendint32(StringInfo buf, int32 i)
Definition: pqformat.h:148
#define INT64_FORMAT
Definition: c.h:367
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125

◆ SendBackupHeader()

static void SendBackupHeader ( List tablespaces)
static

Definition at line 779 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().

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

749 {
750  basebackup_options opt;
751 
752  parse_basebackup_options(cmd->options, &opt);
753 
755 
757  {
758  char activitymsg[50];
759 
760  snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"",
761  opt.label);
762  set_ps_display(activitymsg, false);
763  }
764 
765  perform_base_backup(&opt);
766 }
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:326
static void parse_basebackup_options(List *options, basebackup_options *opt)
Definition: basebackup.c:632
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
const char * label
Definition: basebackup.c:48
static void perform_base_backup(basebackup_options *opt)
Definition: basebackup.c:219
void WalSndSetState(WalSndState state)
Definition: walsender.c:3113

◆ sendDir()

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

Definition at line 1010 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, last_dir_separator(), lfirst, looks_like_temp_rel_name(), lstat, MAXPGPATH, OIDCHARS, parse_filename_for_nontemp_relation(), 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().

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

◆ sendFile()

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

Definition at line 1355 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, pq_putmessage, startptr, TAR_SEND_SIZE, throttle(), total_checksum_failures, and WARNING.

Referenced by perform_base_backup(), and sendDir().

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

◆ sendFileWithContent()

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

Definition at line 912 of file basebackup.c.

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

Referenced by perform_base_backup().

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

◆ sendTablespace()

int64 sendTablespace ( char *  path,
bool  sizeonly 
)

Definition at line 959 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().

960 {
961  int64 size;
962  char pathbuf[MAXPGPATH];
963  struct stat statbuf;
964 
965  /*
966  * 'path' points to the tablespace location, but we only want to include
967  * the version directory in it that belongs to us.
968  */
969  snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path,
971 
972  /*
973  * Store a directory entry in the tar file so we get the permissions
974  * right.
975  */
976  if (lstat(pathbuf, &statbuf) != 0)
977  {
978  if (errno != ENOENT)
979  ereport(ERROR,
981  errmsg("could not stat file or directory \"%s\": %m",
982  pathbuf)));
983 
984  /* If the tablespace went away while scanning, it's no error. */
985  return 0;
986  }
987 
988  size = _tarWriteHeader(TABLESPACE_VERSION_DIRECTORY, NULL, &statbuf,
989  sizeonly);
990 
991  /* Send all the files in the tablespace version directory */
992  size += sendDir(pathbuf, strlen(path), sizeonly, NIL, true);
993 
994  return size;
995 }
#define NIL
Definition: pg_list.h:69
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#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:598
static int64 _tarWriteHeader(const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
Definition: basebackup.c:1581
#define ereport(elevel, rest)
Definition: elog.h:122
#define stat(a, b)
Definition: win32_port.h:266
#define lstat(path, sb)
Definition: win32_port.h:255
static int64 sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, bool sendtblspclinks)
Definition: basebackup.c:1010
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ SendXlogRecPtrResult()

static void SendXlogRecPtrResult ( XLogRecPtr  ptr,
TimeLineID  tli 
)
static

Definition at line 857 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().

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

◆ throttle()

static void throttle ( size_t  increment)
static

Definition at line 1643 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_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by perform_base_backup(), and sendFile().

1644 {
1645  TimeOffset elapsed_min;
1646 
1647  if (throttling_counter < 0)
1648  return;
1649 
1650  throttling_counter += increment;
1652  return;
1653 
1654  /* How much time should have elapsed at minimum? */
1655  elapsed_min = elapsed_min_unit *
1657 
1658  /*
1659  * Since the latch could be set repeatedly because of concurrently WAL
1660  * activity, sleep in a loop to ensure enough time has passed.
1661  */
1662  for (;;)
1663  {
1664  TimeOffset elapsed,
1665  sleep;
1666  int wait_result;
1667 
1668  /* Time elapsed since the last measurement (and possible wake up). */
1669  elapsed = GetCurrentTimestamp() - throttled_last;
1670 
1671  /* sleep if the transfer is faster than it should be */
1672  sleep = elapsed_min - elapsed;
1673  if (sleep <= 0)
1674  break;
1675 
1677 
1678  /* We're eating a potentially set latch, so check for interrupts */
1680 
1681  /*
1682  * (TAR_SEND_SIZE / throttling_sample * elapsed_min_unit) should be
1683  * the maximum time to sleep. Thus the cast to long is safe.
1684  */
1685  wait_result = WaitLatch(MyLatch,
1687  (long) (sleep / 1000),
1689 
1690  if (wait_result & WL_LATCH_SET)
1692 
1693  /* Done waiting? */
1694  if (wait_result & WL_TIMEOUT)
1695  break;
1696  }
1697 
1698  /*
1699  * As we work with integers, only whole multiple of throttling_sample was
1700  * processed. The rest will be done during the next call of this function.
1701  */
1703 
1704  /*
1705  * Time interval for the remaining amount and possible next increments
1706  * starts now.
1707  */
1709 }
#define WL_TIMEOUT
Definition: latch.h:127
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
void ResetLatch(volatile Latch *latch)
Definition: latch.c:497
int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:336
int64 TimeOffset
Definition: timestamp.h:40
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
static TimestampTz throttled_last
Definition: basebackup.c:103
struct Latch * MyLatch
Definition: globals.c:55
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
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

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:51
#define PG_STAT_TMP_DIR
Definition: pgstat.h:34

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:325
#define RELCACHE_INIT_FILENAME
Definition: relcache.h:24
#define PG_AUTOCONF_FILENAME
Definition: guc.h:34
#define LOG_METAINFO_DATAFILE_TMP
Definition: syslogger.h:95
#define BACKUP_LABEL_FILE
Definition: xlog.h:322

Definition at line 163 of file basebackup.c.

Referenced by sendDir().

◆ noChecksumFiles

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

Definition at line 193 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

int64 total_checksum_failures
static

Definition at line 109 of file basebackup.c.

Referenced by perform_base_backup(), and sendFile().