LCOV - differential code coverage report
Current view: top level - src/backend/backup - basebackup.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 83.1 % 586 487 30 56 13 29 290 23 145 56 291 1 21
Current Date: 2023-04-08 15:15:32 Functions: 92.3 % 13 12 1 12 1 12
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * basebackup.c
       4                 :  *    code for taking a base backup and streaming it to a standby
       5                 :  *
       6                 :  * Portions Copyright (c) 2010-2023, PostgreSQL Global Development Group
       7                 :  *
       8                 :  * IDENTIFICATION
       9                 :  *    src/backend/backup/basebackup.c
      10                 :  *
      11                 :  *-------------------------------------------------------------------------
      12                 :  */
      13                 : #include "postgres.h"
      14                 : 
      15                 : #include <sys/stat.h>
      16                 : #include <unistd.h>
      17                 : #include <time.h>
      18                 : 
      19                 : #include "access/xlog_internal.h"
      20                 : #include "access/xlogbackup.h"
      21                 : #include "backup/backup_manifest.h"
      22                 : #include "backup/basebackup.h"
      23                 : #include "backup/basebackup_sink.h"
      24                 : #include "backup/basebackup_target.h"
      25                 : #include "commands/defrem.h"
      26                 : #include "common/compression.h"
      27                 : #include "common/file_perm.h"
      28                 : #include "lib/stringinfo.h"
      29                 : #include "miscadmin.h"
      30                 : #include "nodes/pg_list.h"
      31                 : #include "pgstat.h"
      32                 : #include "pgtar.h"
      33                 : #include "port.h"
      34                 : #include "postmaster/syslogger.h"
      35                 : #include "replication/walsender.h"
      36                 : #include "replication/walsender_private.h"
      37                 : #include "storage/bufpage.h"
      38                 : #include "storage/checksum.h"
      39                 : #include "storage/dsm_impl.h"
      40                 : #include "storage/fd.h"
      41                 : #include "storage/ipc.h"
      42                 : #include "storage/reinit.h"
      43                 : #include "utils/builtins.h"
      44                 : #include "utils/guc.h"
      45                 : #include "utils/ps_status.h"
      46                 : #include "utils/relcache.h"
      47                 : #include "utils/resowner.h"
      48                 : #include "utils/timestamp.h"
      49                 : 
      50                 : /*
      51                 :  * How much data do we want to send in one CopyData message? Note that
      52                 :  * this may also result in reading the underlying files in chunks of this
      53                 :  * size.
      54                 :  *
      55                 :  * NB: The buffer size is required to be a multiple of the system block
      56                 :  * size, so use that value instead if it's bigger than our preference.
      57                 :  */
      58                 : #define SINK_BUFFER_LENGTH          Max(32768, BLCKSZ)
      59                 : 
      60                 : typedef struct
      61                 : {
      62                 :     const char *label;
      63                 :     bool        progress;
      64                 :     bool        fastcheckpoint;
      65                 :     bool        nowait;
      66                 :     bool        includewal;
      67                 :     uint32      maxrate;
      68                 :     bool        sendtblspcmapfile;
      69                 :     bool        send_to_client;
      70                 :     bool        use_copytblspc;
      71                 :     BaseBackupTargetHandle *target_handle;
      72                 :     backup_manifest_option manifest;
      73                 :     pg_compress_algorithm compression;
      74                 :     pg_compress_specification compression_specification;
      75                 :     pg_checksum_type manifest_checksum_type;
      76                 : } basebackup_options;
      77                 : 
      78                 : static int64 sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
      79                 :                             struct backup_manifest_info *manifest);
      80                 : static int64 sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
      81                 :                      List *tablespaces, bool sendtblspclinks,
      82                 :                      backup_manifest_info *manifest, const char *spcoid);
      83                 : static bool sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
      84                 :                      struct stat *statbuf, bool missing_ok, Oid dboid,
      85                 :                      backup_manifest_info *manifest, const char *spcoid);
      86                 : static void sendFileWithContent(bbsink *sink, const char *filename,
      87                 :                                 const char *content,
      88                 :                                 backup_manifest_info *manifest);
      89                 : static int64 _tarWriteHeader(bbsink *sink, const char *filename,
      90                 :                              const char *linktarget, struct stat *statbuf,
      91                 :                              bool sizeonly);
      92                 : static void _tarWritePadding(bbsink *sink, int len);
      93                 : static void convert_link_to_directory(const char *pathbuf, struct stat *statbuf);
      94                 : static void perform_base_backup(basebackup_options *opt, bbsink *sink);
      95                 : static void parse_basebackup_options(List *options, basebackup_options *opt);
      96                 : static int  compareWalFileNames(const ListCell *a, const ListCell *b);
      97                 : static bool is_checksummed_file(const char *fullpath, const char *filename);
      98                 : static int  basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
      99                 :                                  const char *filename, bool partial_read_ok);
     100                 : 
     101                 : /* Was the backup currently in-progress initiated in recovery mode? */
     102                 : static bool backup_started_in_recovery = false;
     103                 : 
     104                 : /* Total number of checksum failures during base backup. */
     105                 : static long long int total_checksum_failures;
     106                 : 
     107                 : /* Do not verify checksums. */
     108                 : static bool noverify_checksums = false;
     109                 : 
     110                 : /*
     111                 :  * Definition of one element part of an exclusion list, used for paths part
     112                 :  * of checksum validation or base backups.  "name" is the name of the file
     113                 :  * or path to check for exclusion.  If "match_prefix" is true, any items
     114                 :  * matching the name as prefix are excluded.
     115                 :  */
     116                 : struct exclude_list_item
     117                 : {
     118                 :     const char *name;
     119                 :     bool        match_prefix;
     120                 : };
     121                 : 
     122                 : /*
     123                 :  * The contents of these directories are removed or recreated during server
     124                 :  * start so they are not included in backups.  The directories themselves are
     125                 :  * kept and included as empty to preserve access permissions.
     126                 :  *
     127                 :  * Note: this list should be kept in sync with the filter lists in pg_rewind's
     128                 :  * filemap.c.
     129                 :  */
     130                 : static const char *const excludeDirContents[] =
     131                 : {
     132                 :     /*
     133                 :      * Skip temporary statistics files. PG_STAT_TMP_DIR must be skipped
     134                 :      * because extensions like pg_stat_statements store data there.
     135                 :      */
     136                 :     PG_STAT_TMP_DIR,
     137                 : 
     138                 :     /*
     139                 :      * It is generally not useful to backup the contents of this directory
     140                 :      * even if the intention is to restore to another primary. See backup.sgml
     141                 :      * for a more detailed description.
     142                 :      */
     143                 :     "pg_replslot",
     144                 : 
     145                 :     /* Contents removed on startup, see dsm_cleanup_for_mmap(). */
     146                 :     PG_DYNSHMEM_DIR,
     147                 : 
     148                 :     /* Contents removed on startup, see AsyncShmemInit(). */
     149                 :     "pg_notify",
     150                 : 
     151                 :     /*
     152                 :      * Old contents are loaded for possible debugging but are not required for
     153                 :      * normal operation, see SerialInit().
     154                 :      */
     155                 :     "pg_serial",
     156                 : 
     157                 :     /* Contents removed on startup, see DeleteAllExportedSnapshotFiles(). */
     158                 :     "pg_snapshots",
     159                 : 
     160                 :     /* Contents zeroed on startup, see StartupSUBTRANS(). */
     161                 :     "pg_subtrans",
     162                 : 
     163                 :     /* end of list */
     164                 :     NULL
     165                 : };
     166                 : 
     167                 : /*
     168                 :  * List of files excluded from backups.
     169                 :  */
     170                 : static const struct exclude_list_item excludeFiles[] =
     171                 : {
     172                 :     /* Skip auto conf temporary file. */
     173                 :     {PG_AUTOCONF_FILENAME ".tmp", false},
     174                 : 
     175                 :     /* Skip current log file temporary file */
     176                 :     {LOG_METAINFO_DATAFILE_TMP, false},
     177                 : 
     178                 :     /*
     179                 :      * Skip relation cache because it is rebuilt on startup.  This includes
     180                 :      * temporary files.
     181                 :      */
     182                 :     {RELCACHE_INIT_FILENAME, true},
     183                 : 
     184                 :     /*
     185                 :      * backup_label and tablespace_map should not exist in a running cluster
     186                 :      * capable of doing an online backup, but exclude them just in case.
     187                 :      */
     188                 :     {BACKUP_LABEL_FILE, false},
     189                 :     {TABLESPACE_MAP, false},
     190                 : 
     191                 :     /*
     192                 :      * If there's a backup_manifest, it belongs to a backup that was used to
     193                 :      * start this server. It is *not* correct for this backup. Our
     194                 :      * backup_manifest is injected into the backup separately if users want
     195                 :      * it.
     196                 :      */
     197                 :     {"backup_manifest", false},
     198                 : 
     199                 :     {"postmaster.pid", false},
     200                 :     {"postmaster.opts", false},
     201                 : 
     202                 :     /* end of list */
     203                 :     {NULL, false}
     204                 : };
     205                 : 
     206                 : /*
     207                 :  * List of files excluded from checksum validation.
     208                 :  *
     209                 :  * Note: this list should be kept in sync with what pg_checksums.c
     210                 :  * includes.
     211                 :  */
     212                 : static const struct exclude_list_item noChecksumFiles[] = {
     213                 :     {"pg_control", false},
     214                 :     {"pg_filenode.map", false},
     215                 :     {"pg_internal.init", true},
     216                 :     {"PG_VERSION", false},
     217                 : #ifdef EXEC_BACKEND
     218                 :     {"config_exec_params", true},
     219                 : #endif
     220                 :     {NULL, false}
     221                 : };
     222                 : 
     223                 : /*
     224                 :  * Actually do a base backup for the specified tablespaces.
     225                 :  *
     226                 :  * This is split out mainly to avoid complaints about "variable might be
     227                 :  * clobbered by longjmp" from stupider versions of gcc.
     228                 :  */
     229                 : static void
     230 GIC         126 : perform_base_backup(basebackup_options *opt, bbsink *sink)
     231                 : {
     232 ECB             :     bbsink_state state;
     233                 :     XLogRecPtr  endptr;
     234                 :     TimeLineID  endtli;
     235                 :     backup_manifest_info manifest;
     236                 :     BackupState *backup_state;
     237                 :     StringInfo  tablespace_map;
     238                 : 
     239                 :     /* Initial backup state, insofar as we know it now. */
     240 GIC         126 :     state.tablespaces = NIL;
     241             126 :     state.tablespace_num = 0;
     242 CBC         126 :     state.bytes_done = 0;
     243             126 :     state.bytes_total = 0;
     244             126 :     state.bytes_total_is_valid = false;
     245 ECB             : 
     246                 :     /* we're going to use a BufFile, so we need a ResourceOwner */
     247 GIC         126 :     Assert(CurrentResourceOwner == NULL);
     248             126 :     CurrentResourceOwner = ResourceOwnerCreate(NULL, "base backup");
     249 ECB             : 
     250 CBC         126 :     backup_started_in_recovery = RecoveryInProgress();
     251                 : 
     252             126 :     InitializeBackupManifest(&manifest, opt->manifest,
     253                 :                              opt->manifest_checksum_type);
     254                 : 
     255             126 :     total_checksum_failures = 0;
     256                 : 
     257                 :     /* Allocate backup related varilables. */
     258 GNC         126 :     backup_state = (BackupState *) palloc0(sizeof(BackupState));
     259             126 :     tablespace_map = makeStringInfo();
     260                 : 
     261 GIC         126 :     basebackup_progress_wait_checkpoint();
     262 GNC         126 :     do_pg_backup_start(opt->label, opt->fastcheckpoint, &state.tablespaces,
     263                 :                        backup_state, tablespace_map);
     264                 : 
     265             126 :     state.startptr = backup_state->startpoint;
     266             126 :     state.starttli = backup_state->starttli;
     267 ECB             : 
     268                 :     /*
     269                 :      * Once do_pg_backup_start has been called, ensure that any failure causes
     270                 :      * us to abort the backup so we don't "leak" a backup counter. For this
     271                 :      * reason, *all* functionality between do_pg_backup_start() and the end of
     272                 :      * do_pg_backup_stop() should be inside the error cleanup block!
     273                 :      */
     274                 : 
     275 GIC         126 :     PG_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
     276                 :     {
     277                 :         ListCell   *lc;
     278                 :         tablespaceinfo *newti;
     279                 : 
     280 ECB             :         /* Add a node for the base directory at the end */
     281 GNC         126 :         newti = palloc0(sizeof(tablespaceinfo));
     282             126 :         newti->size = -1;
     283             126 :         state.tablespaces = lappend(state.tablespaces, newti);
     284                 : 
     285                 :         /*
     286 ECB             :          * Calculate the total backup size by summing up the size of each
     287                 :          * tablespace
     288                 :          */
     289 GIC         126 :         if (opt->progress)
     290                 :         {
     291             126 :             basebackup_progress_estimate_backup_size();
     292                 : 
     293             268 :             foreach(lc, state.tablespaces)
     294 ECB             :             {
     295 GIC         142 :                 tablespaceinfo *tmp = (tablespaceinfo *) lfirst(lc);
     296 ECB             : 
     297 GIC         142 :                 if (tmp->path == NULL)
     298 CBC         126 :                     tmp->size = sendDir(sink, ".", 1, true, state.tablespaces,
     299                 :                                         true, NULL, NULL);
     300 ECB             :                 else
     301 GIC          16 :                     tmp->size = sendTablespace(sink, tmp->path, tmp->oid, true,
     302 ECB             :                                                NULL);
     303 CBC         142 :                 state.bytes_total += tmp->size;
     304                 :             }
     305 GIC         126 :             state.bytes_total_is_valid = true;
     306 ECB             :         }
     307                 : 
     308                 :         /* notify basebackup sink about start of backup */
     309 GIC         126 :         bbsink_begin_backup(sink, &state, SINK_BUFFER_LENGTH);
     310 ECB             : 
     311                 :         /* Send off our tablespaces one by one */
     312 GIC         262 :         foreach(lc, state.tablespaces)
     313                 :         {
     314 CBC         142 :             tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc);
     315                 : 
     316 GIC         142 :             if (ti->path == NULL)
     317 ECB             :             {
     318                 :                 struct stat statbuf;
     319 CBC         126 :                 bool        sendtblspclinks = true;
     320                 :                 char       *backup_label;
     321                 : 
     322             126 :                 bbsink_begin_archive(sink, "base.tar");
     323                 : 
     324                 :                 /* In the main tar, include the backup_label first... */
     325 GNC         126 :                 backup_label = build_backup_content(backup_state, false);
     326             126 :                 sendFileWithContent(sink, BACKUP_LABEL_FILE,
     327                 :                                     backup_label, &manifest);
     328             126 :                 pfree(backup_label);
     329                 : 
     330 ECB             :                 /* Then the tablespace_map file, if required... */
     331 GIC         126 :                 if (opt->sendtblspcmapfile)
     332                 :                 {
     333 GNC          24 :                     sendFileWithContent(sink, TABLESPACE_MAP,
     334              24 :                                         tablespace_map->data, &manifest);
     335 GIC          24 :                     sendtblspclinks = false;
     336 ECB             :                 }
     337                 : 
     338                 :                 /* Then the bulk of the files... */
     339 CBC         126 :                 sendDir(sink, ".", 1, false, state.tablespaces,
     340                 :                         sendtblspclinks, &manifest, NULL);
     341 ECB             : 
     342                 :                 /* ... and pg_control after everything else. */
     343 CBC         120 :                 if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0)
     344 UIC           0 :                     ereport(ERROR,
     345                 :                             (errcode_for_file_access(),
     346                 :                              errmsg("could not stat file \"%s\": %m",
     347 ECB             :                                     XLOG_CONTROL_FILE)));
     348 GIC         120 :                 sendFile(sink, XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf,
     349                 :                          false, InvalidOid, &manifest, NULL);
     350                 :             }
     351 ECB             :             else
     352 EUB             :             {
     353 GIC          16 :                 char       *archive_name = psprintf("%s.tar", ti->oid);
     354                 : 
     355              16 :                 bbsink_begin_archive(sink, archive_name);
     356 ECB             : 
     357 GIC          16 :                 sendTablespace(sink, ti->path, ti->oid, false, &manifest);
     358                 :             }
     359                 : 
     360                 :             /*
     361 ECB             :              * If we're including WAL, and this is the main data directory we
     362                 :              * don't treat this as the end of the tablespace. Instead, we will
     363                 :              * include the xlog files below and stop afterwards. This is safe
     364                 :              * since the main data directory is always sent *last*.
     365                 :              */
     366 GIC         136 :             if (opt->includewal && ti->path == NULL)
     367                 :             {
     368              20 :                 Assert(lnext(state.tablespaces, lc) == NULL);
     369                 :             }
     370                 :             else
     371                 :             {
     372                 :                 /* Properly terminate the tarfile. */
     373                 :                 StaticAssertDecl(2 * TAR_BLOCK_SIZE <= BLCKSZ,
     374 ECB             :                                  "BLCKSZ too small for 2 tar blocks");
     375 GIC         116 :                 memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
     376 CBC         116 :                 bbsink_archive_contents(sink, 2 * TAR_BLOCK_SIZE);
     377                 : 
     378                 :                 /* OK, that's the end of the archive. */
     379 GIC         116 :                 bbsink_end_archive(sink);
     380                 :             }
     381                 :         }
     382                 : 
     383 CBC         120 :         basebackup_progress_wait_wal_archive(&state);
     384 GNC         120 :         do_pg_backup_stop(backup_state, !opt->nowait);
     385                 : 
     386             120 :         endptr = backup_state->stoppoint;
     387             120 :         endtli = backup_state->stoptli;
     388                 : 
     389                 :         /* Deallocate backup-related variables. */
     390             120 :         pfree(tablespace_map->data);
     391             120 :         pfree(tablespace_map);
     392             120 :         pfree(backup_state);
     393                 :     }
     394 GIC         121 :     PG_END_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
     395 ECB             : 
     396                 : 
     397 GIC         120 :     if (opt->includewal)
     398                 :     {
     399 ECB             :         /*
     400                 :          * We've left the last tar file "open", so we can now append the
     401                 :          * required WAL files to it.
     402                 :          */
     403                 :         char        pathbuf[MAXPGPATH];
     404                 :         XLogSegNo   segno;
     405                 :         XLogSegNo   startsegno;
     406                 :         XLogSegNo   endsegno;
     407                 :         struct stat statbuf;
     408 CBC          20 :         List       *historyFileList = NIL;
     409 GIC          20 :         List       *walFileList = NIL;
     410 ECB             :         char        firstoff[MAXFNAMELEN];
     411                 :         char        lastoff[MAXFNAMELEN];
     412                 :         DIR        *dir;
     413                 :         struct dirent *de;
     414                 :         ListCell   *lc;
     415                 :         TimeLineID  tli;
     416                 : 
     417 GIC          20 :         basebackup_progress_transfer_wal();
     418                 : 
     419                 :         /*
     420                 :          * I'd rather not worry about timelines here, so scan pg_wal and
     421                 :          * include all WAL files in the range between 'startptr' and 'endptr',
     422                 :          * regardless of the timeline the file is stamped with. If there are
     423                 :          * some spurious WAL files belonging to timelines that don't belong in
     424 ECB             :          * this server's history, they will be included too. Normally there
     425                 :          * shouldn't be such files, but if there are, there's little harm in
     426                 :          * including them.
     427                 :          */
     428 GIC          20 :         XLByteToSeg(state.startptr, startsegno, wal_segment_size);
     429              20 :         XLogFileName(firstoff, state.starttli, startsegno, wal_segment_size);
     430              20 :         XLByteToPrevSeg(endptr, endsegno, wal_segment_size);
     431              20 :         XLogFileName(lastoff, endtli, endsegno, wal_segment_size);
     432                 : 
     433 CBC          20 :         dir = AllocateDir("pg_wal");
     434 GIC         123 :         while ((de = ReadDir(dir, "pg_wal")) != NULL)
     435                 :         {
     436                 :             /* Does it look like a WAL segment, and is it in the range? */
     437             103 :             if (IsXLogFileName(de->d_name) &&
     438              43 :                 strcmp(de->d_name + 8, firstoff + 8) >= 0 &&
     439              43 :                 strcmp(de->d_name + 8, lastoff + 8) <= 0)
     440                 :             {
     441              20 :                 walFileList = lappend(walFileList, pstrdup(de->d_name));
     442                 :             }
     443                 :             /* Does it look like a timeline history file? */
     444 CBC          83 :             else if (IsTLHistoryFileName(de->d_name))
     445 ECB             :             {
     446 LBC           0 :                 historyFileList = lappend(historyFileList, pstrdup(de->d_name));
     447 ECB             :             }
     448                 :         }
     449 CBC          20 :         FreeDir(dir);
     450 ECB             : 
     451                 :         /*
     452                 :          * Before we go any further, check that none of the WAL segments we
     453                 :          * need were removed.
     454                 :          */
     455 CBC          20 :         CheckXLogRemoved(startsegno, state.starttli);
     456                 : 
     457 ECB             :         /*
     458                 :          * Sort the WAL filenames.  We want to send the files in order from
     459                 :          * oldest to newest, to reduce the chance that a file is recycled
     460                 :          * before we get a chance to send it over.
     461                 :          */
     462 GBC          20 :         list_sort(walFileList, compareWalFileNames);
     463                 : 
     464                 :         /*
     465 ECB             :          * There must be at least one xlog file in the pg_wal directory, since
     466                 :          * we are doing backup-including-xlog.
     467                 :          */
     468 GIC          20 :         if (walFileList == NIL)
     469 UIC           0 :             ereport(ERROR,
     470                 :                     (errmsg("could not find any WAL files")));
     471 ECB             : 
     472                 :         /*
     473                 :          * Sanity check: the first and last segment should cover startptr and
     474                 :          * endptr, with no gaps in between.
     475                 :          */
     476 GIC          20 :         XLogFromFileName((char *) linitial(walFileList),
     477                 :                          &tli, &segno, wal_segment_size);
     478 CBC          20 :         if (segno != startsegno)
     479                 :         {
     480                 :             char        startfname[MAXFNAMELEN];
     481                 : 
     482 UIC           0 :             XLogFileName(startfname, state.starttli, startsegno,
     483                 :                          wal_segment_size);
     484 LBC           0 :             ereport(ERROR,
     485 EUB             :                     (errmsg("could not find WAL file \"%s\"", startfname)));
     486                 :         }
     487 GIC          40 :         foreach(lc, walFileList)
     488                 :         {
     489              20 :             char       *walFileName = (char *) lfirst(lc);
     490              20 :             XLogSegNo   currsegno = segno;
     491              20 :             XLogSegNo   nextsegno = segno + 1;
     492 ECB             : 
     493 GIC          20 :             XLogFromFileName(walFileName, &tli, &segno, wal_segment_size);
     494 CBC          20 :             if (!(nextsegno == segno || currsegno == segno))
     495                 :             {
     496                 :                 char        nextfname[MAXFNAMELEN];
     497                 : 
     498 UBC           0 :                 XLogFileName(nextfname, tli, nextsegno, wal_segment_size);
     499 UIC           0 :                 ereport(ERROR,
     500 EUB             :                         (errmsg("could not find WAL file \"%s\"", nextfname)));
     501                 :             }
     502                 :         }
     503 CBC          20 :         if (segno != endsegno)
     504                 :         {
     505 ECB             :             char        endfname[MAXFNAMELEN];
     506                 : 
     507 LBC           0 :             XLogFileName(endfname, endtli, endsegno, wal_segment_size);
     508 UIC           0 :             ereport(ERROR,
     509 ECB             :                     (errmsg("could not find WAL file \"%s\"", endfname)));
     510                 :         }
     511                 : 
     512                 :         /* Ok, we have everything we need. Send the WAL files. */
     513 GIC          40 :         foreach(lc, walFileList)
     514 EUB             :         {
     515 GBC          20 :             char       *walFileName = (char *) lfirst(lc);
     516                 :             int         fd;
     517                 :             size_t      cnt;
     518 GIC          20 :             pgoff_t     len = 0;
     519 ECB             : 
     520 GIC          20 :             snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFileName);
     521              20 :             XLogFromFileName(walFileName, &tli, &segno, wal_segment_size);
     522                 : 
     523 GBC          20 :             fd = OpenTransientFile(pathbuf, O_RDONLY | PG_BINARY);
     524              20 :             if (fd < 0)
     525                 :             {
     526 UIC           0 :                 int         save_errno = errno;
     527                 : 
     528                 :                 /*
     529 ECB             :                  * Most likely reason for this is that the file was already
     530                 :                  * removed by a checkpoint, so check for that to get a better
     531                 :                  * error message.
     532                 :                  */
     533 UIC           0 :                 CheckXLogRemoved(segno, tli);
     534 ECB             : 
     535 UIC           0 :                 errno = save_errno;
     536 LBC           0 :                 ereport(ERROR,
     537 ECB             :                         (errcode_for_file_access(),
     538                 :                          errmsg("could not open file \"%s\": %m", pathbuf)));
     539                 :             }
     540                 : 
     541 GIC          20 :             if (fstat(fd, &statbuf) != 0)
     542 UBC           0 :                 ereport(ERROR,
     543                 :                         (errcode_for_file_access(),
     544                 :                          errmsg("could not stat file \"%s\": %m",
     545                 :                                 pathbuf)));
     546 GIC          20 :             if (statbuf.st_size != wal_segment_size)
     547                 :             {
     548 UIC           0 :                 CheckXLogRemoved(segno, tli);
     549 UBC           0 :                 ereport(ERROR,
     550                 :                         (errcode_for_file_access(),
     551 EUB             :                          errmsg("unexpected WAL file size \"%s\"", walFileName)));
     552                 :             }
     553                 : 
     554                 :             /* send the WAL file itself */
     555 GIC          20 :             _tarWriteHeader(sink, pathbuf, NULL, &statbuf, false);
     556                 : 
     557 CBC          20 :             while ((cnt = basebackup_read_file(fd, sink->bbs_buffer,
     558 GBC       10240 :                                                Min(sink->bbs_buffer_length,
     559                 :                                                    wal_segment_size - len),
     560 GIC       10240 :                                                len, pathbuf, true)) > 0)
     561                 :             {
     562 CBC       10240 :                 CheckXLogRemoved(segno, tli);
     563 GIC       10240 :                 bbsink_archive_contents(sink, cnt);
     564 EUB             : 
     565 GBC       10240 :                 len += cnt;
     566                 : 
     567 GIC       10240 :                 if (len == wal_segment_size)
     568              20 :                     break;
     569                 :             }
     570                 : 
     571 CBC          20 :             if (len != wal_segment_size)
     572                 :             {
     573 LBC           0 :                 CheckXLogRemoved(segno, tli);
     574               0 :                 ereport(ERROR,
     575                 :                         (errcode_for_file_access(),
     576 ECB             :                          errmsg("unexpected WAL file size \"%s\"", walFileName)));
     577                 :             }
     578                 : 
     579                 :             /*
     580                 :              * wal_segment_size is a multiple of TAR_BLOCK_SIZE, so no need
     581                 :              * for padding.
     582                 :              */
     583 CBC          20 :             Assert(wal_segment_size % TAR_BLOCK_SIZE == 0);
     584 ECB             : 
     585 GIC          20 :             CloseTransientFile(fd);
     586                 : 
     587 ECB             :             /*
     588                 :              * Mark file as archived, otherwise files can get archived again
     589 EUB             :              * after promotion of a new node. This is in line with
     590                 :              * walreceiver.c always doing an XLogArchiveForceDone() after a
     591                 :              * complete segment.
     592                 :              */
     593 GIC          20 :             StatusFilePath(pathbuf, walFileName, ".done");
     594              20 :             sendFileWithContent(sink, pathbuf, "", &manifest);
     595                 :         }
     596                 : 
     597                 :         /*
     598                 :          * Send timeline history files too. Only the latest timeline history
     599 ECB             :          * file is required for recovery, and even that only if there happens
     600                 :          * to be a timeline switch in the first WAL segment that contains the
     601                 :          * checkpoint record, or if we're taking a base backup from a standby
     602                 :          * server and the target timeline changes while the backup is taken.
     603                 :          * But they are small and highly useful for debugging purposes, so
     604                 :          * better include them all, always.
     605                 :          */
     606 GIC          20 :         foreach(lc, historyFileList)
     607                 :         {
     608 UIC           0 :             char       *fname = lfirst(lc);
     609 ECB             : 
     610 LBC           0 :             snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", fname);
     611                 : 
     612 UIC           0 :             if (lstat(pathbuf, &statbuf) != 0)
     613               0 :                 ereport(ERROR,
     614                 :                         (errcode_for_file_access(),
     615                 :                          errmsg("could not stat file \"%s\": %m", pathbuf)));
     616                 : 
     617               0 :             sendFile(sink, pathbuf, pathbuf, &statbuf, false, InvalidOid,
     618                 :                      &manifest, NULL);
     619                 : 
     620                 :             /* unconditionally mark file as archived */
     621               0 :             StatusFilePath(pathbuf, fname, ".done");
     622 LBC           0 :             sendFileWithContent(sink, pathbuf, "", &manifest);
     623                 :         }
     624 EUB             : 
     625                 :         /* Properly terminate the tar file. */
     626                 :         StaticAssertStmt(2 * TAR_BLOCK_SIZE <= BLCKSZ,
     627                 :                          "BLCKSZ too small for 2 tar blocks");
     628 GBC          20 :         memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
     629              20 :         bbsink_archive_contents(sink, 2 * TAR_BLOCK_SIZE);
     630                 : 
     631                 :         /* OK, that's the end of the archive. */
     632 GIC          20 :         bbsink_end_archive(sink);
     633 EUB             :     }
     634                 : 
     635 GIC         120 :     AddWALInfoToBackupManifest(&manifest, state.startptr, state.starttli,
     636                 :                                endptr, endtli);
     637 EUB             : 
     638 GBC         120 :     SendBackupManifest(&manifest, sink);
     639                 : 
     640 GIC         120 :     bbsink_end_backup(sink, endptr, endtli);
     641                 : 
     642             120 :     if (total_checksum_failures)
     643                 :     {
     644 CBC           3 :         if (total_checksum_failures > 1)
     645               2 :             ereport(WARNING,
     646                 :                     (errmsg_plural("%lld total checksum verification failure",
     647                 :                                    "%lld total checksum verification failures",
     648 ECB             :                                    total_checksum_failures,
     649                 :                                    total_checksum_failures)));
     650                 : 
     651 CBC           3 :         ereport(ERROR,
     652                 :                 (errcode(ERRCODE_DATA_CORRUPTED),
     653                 :                  errmsg("checksum verification failure during base backup")));
     654 ECB             :     }
     655                 : 
     656                 :     /*
     657                 :      * Make sure to free the manifest before the resource owners as manifests
     658                 :      * use cryptohash contexts that may depend on resource owners (like
     659                 :      * OpenSSL).
     660                 :      */
     661 CBC         117 :     FreeBackupManifest(&manifest);
     662                 : 
     663                 :     /* clean up the resource owner we created */
     664 GIC         117 :     WalSndResourceCleanup(true);
     665                 : 
     666             117 :     basebackup_progress_done();
     667 CBC         117 : }
     668                 : 
     669                 : /*
     670                 :  * list_sort comparison function, to compare log/seg portion of WAL segment
     671                 :  * filenames, ignoring the timeline portion.
     672                 :  */
     673                 : static int
     674 UIC           0 : compareWalFileNames(const ListCell *a, const ListCell *b)
     675                 : {
     676               0 :     char       *fna = (char *) lfirst(a);
     677 LBC           0 :     char       *fnb = (char *) lfirst(b);
     678                 : 
     679 UIC           0 :     return strcmp(fna + 8, fnb + 8);
     680 ECB             : }
     681                 : 
     682                 : /*
     683                 :  * Parse the base backup options passed down by the parser
     684                 :  */
     685                 : static void
     686 GIC         142 : parse_basebackup_options(List *options, basebackup_options *opt)
     687                 : {
     688                 :     ListCell   *lopt;
     689             142 :     bool        o_label = false;
     690 GBC         142 :     bool        o_progress = false;
     691 GIC         142 :     bool        o_checkpoint = false;
     692 GBC         142 :     bool        o_nowait = false;
     693             142 :     bool        o_wal = false;
     694 GIC         142 :     bool        o_maxrate = false;
     695 GBC         142 :     bool        o_tablespace_map = false;
     696 GIC         142 :     bool        o_noverify_checksums = false;
     697             142 :     bool        o_manifest = false;
     698             142 :     bool        o_manifest_checksums = false;
     699             142 :     bool        o_target = false;
     700             142 :     bool        o_target_detail = false;
     701             142 :     char       *target_str = NULL;
     702 CBC         142 :     char       *target_detail_str = NULL;
     703 GIC         142 :     bool        o_compression = false;
     704             142 :     bool        o_compression_detail = false;
     705 CBC         142 :     char       *compression_detail_str = NULL;
     706 ECB             : 
     707 CBC        1562 :     MemSet(opt, 0, sizeof(*opt));
     708             142 :     opt->manifest = MANIFEST_OPTION_NO;
     709             142 :     opt->manifest_checksum_type = CHECKSUM_TYPE_CRC32C;
     710             142 :     opt->compression = PG_COMPRESSION_NONE;
     711             142 :     opt->compression_specification.algorithm = PG_COMPRESSION_NONE;
     712 ECB             : 
     713 CBC        1087 :     foreach(lopt, options)
     714 ECB             :     {
     715 CBC         947 :         DefElem    *defel = (DefElem *) lfirst(lopt);
     716 ECB             : 
     717 CBC         947 :         if (strcmp(defel->defname, "label") == 0)
     718 ECB             :         {
     719 CBC         142 :             if (o_label)
     720 LBC           0 :                 ereport(ERROR,
     721 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     722                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
     723 CBC         142 :             opt->label = defGetString(defel);
     724             142 :             o_label = true;
     725 ECB             :         }
     726 CBC         805 :         else if (strcmp(defel->defname, "progress") == 0)
     727 ECB             :         {
     728 GIC         142 :             if (o_progress)
     729 LBC           0 :                 ereport(ERROR,
     730                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     731 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     732 GIC         142 :             opt->progress = defGetBoolean(defel);
     733 CBC         142 :             o_progress = true;
     734                 :         }
     735             663 :         else if (strcmp(defel->defname, "checkpoint") == 0)
     736 EUB             :         {
     737 GIC         132 :             char       *optval = defGetString(defel);
     738                 : 
     739 CBC         132 :             if (o_checkpoint)
     740 LBC           0 :                 ereport(ERROR,
     741                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     742 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     743 GIC         132 :             if (pg_strcasecmp(optval, "fast") == 0)
     744 CBC         132 :                 opt->fastcheckpoint = true;
     745 UBC           0 :             else if (pg_strcasecmp(optval, "spread") == 0)
     746 UIC           0 :                 opt->fastcheckpoint = false;
     747                 :             else
     748 LBC           0 :                 ereport(ERROR,
     749 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     750                 :                          errmsg("unrecognized checkpoint type: \"%s\"",
     751                 :                                 optval)));
     752 GIC         132 :             o_checkpoint = true;
     753 ECB             :         }
     754 GIC         531 :         else if (strcmp(defel->defname, "wait") == 0)
     755 ECB             :         {
     756 GBC         135 :             if (o_nowait)
     757 UIC           0 :                 ereport(ERROR,
     758                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     759 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     760 CBC         135 :             opt->nowait = !defGetBoolean(defel);
     761 GBC         135 :             o_nowait = true;
     762 EUB             :         }
     763 GIC         396 :         else if (strcmp(defel->defname, "wal") == 0)
     764 EUB             :         {
     765 GIC          24 :             if (o_wal)
     766 UIC           0 :                 ereport(ERROR,
     767                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     768 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     769 GIC          24 :             opt->includewal = defGetBoolean(defel);
     770 CBC          24 :             o_wal = true;
     771                 :         }
     772             372 :         else if (strcmp(defel->defname, "max_rate") == 0)
     773 EUB             :         {
     774                 :             int64       maxrate;
     775                 : 
     776 CBC           1 :             if (o_maxrate)
     777 LBC           0 :                 ereport(ERROR,
     778                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     779 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     780                 : 
     781 CBC           1 :             maxrate = defGetInt64(defel);
     782 GBC           1 :             if (maxrate < MAX_RATE_LOWER || maxrate > MAX_RATE_UPPER)
     783 UIC           0 :                 ereport(ERROR,
     784                 :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     785 ECB             :                          errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
     786                 :                                 (int) maxrate, "MAX_RATE", MAX_RATE_LOWER, MAX_RATE_UPPER)));
     787                 : 
     788 CBC           1 :             opt->maxrate = (uint32) maxrate;
     789 GIC           1 :             o_maxrate = true;
     790                 :         }
     791             371 :         else if (strcmp(defel->defname, "tablespace_map") == 0)
     792 ECB             :         {
     793 GBC          29 :             if (o_tablespace_map)
     794 UIC           0 :                 ereport(ERROR,
     795                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     796                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
     797 CBC          29 :             opt->sendtblspcmapfile = defGetBoolean(defel);
     798              29 :             o_tablespace_map = true;
     799 EUB             :         }
     800 GIC         342 :         else if (strcmp(defel->defname, "verify_checksums") == 0)
     801                 :         {
     802               1 :             if (o_noverify_checksums)
     803 UIC           0 :                 ereport(ERROR,
     804 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     805                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
     806 GIC           1 :             noverify_checksums = !defGetBoolean(defel);
     807 CBC           1 :             o_noverify_checksums = true;
     808                 :         }
     809             341 :         else if (strcmp(defel->defname, "manifest") == 0)
     810 EUB             :         {
     811 GIC         141 :             char       *optval = defGetString(defel);
     812                 :             bool        manifest_bool;
     813 ECB             : 
     814 CBC         141 :             if (o_manifest)
     815 UIC           0 :                 ereport(ERROR,
     816 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     817                 :                          errmsg("duplicate option \"%s\"", defel->defname)));
     818 CBC         141 :             if (parse_bool(optval, &manifest_bool))
     819 EUB             :             {
     820 GIC         140 :                 if (manifest_bool)
     821             140 :                     opt->manifest = MANIFEST_OPTION_YES;
     822 ECB             :                 else
     823 LBC           0 :                     opt->manifest = MANIFEST_OPTION_NO;
     824                 :             }
     825 CBC           1 :             else if (pg_strcasecmp(optval, "force-encode") == 0)
     826 GIC           1 :                 opt->manifest = MANIFEST_OPTION_FORCE_ENCODE;
     827 ECB             :             else
     828 UIC           0 :                 ereport(ERROR,
     829                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     830 ECB             :                          errmsg("unrecognized manifest option: \"%s\"",
     831 EUB             :                                 optval)));
     832 GIC         141 :             o_manifest = true;
     833                 :         }
     834 CBC         200 :         else if (strcmp(defel->defname, "manifest_checksums") == 0)
     835                 :         {
     836               7 :             char       *optval = defGetString(defel);
     837 ECB             : 
     838 GIC           7 :             if (o_manifest_checksums)
     839 UBC           0 :                 ereport(ERROR,
     840                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     841 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     842 CBC           7 :             if (!pg_checksum_parse_type(optval,
     843                 :                                         &opt->manifest_checksum_type))
     844 GBC           1 :                 ereport(ERROR,
     845                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     846                 :                          errmsg("unrecognized checksum algorithm: \"%s\"",
     847                 :                                 optval)));
     848 CBC           6 :             o_manifest_checksums = true;
     849                 :         }
     850             193 :         else if (strcmp(defel->defname, "target") == 0)
     851                 :         {
     852             141 :             if (o_target)
     853 UIC           0 :                 ereport(ERROR,
     854 ECB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     855 EUB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     856 GIC         141 :             target_str = defGetString(defel);
     857             141 :             o_target = true;
     858 ECB             :         }
     859 GIC          52 :         else if (strcmp(defel->defname, "target_detail") == 0)
     860 ECB             :         {
     861 GIC           9 :             char       *optval = defGetString(defel);
     862                 : 
     863               9 :             if (o_target_detail)
     864 LBC           0 :                 ereport(ERROR,
     865                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     866 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     867 GIC           9 :             target_detail_str = optval;
     868 CBC           9 :             o_target_detail = true;
     869 EUB             :         }
     870 GIC          43 :         else if (strcmp(defel->defname, "compression") == 0)
     871                 :         {
     872 CBC          29 :             char       *optval = defGetString(defel);
     873 ECB             : 
     874 GIC          29 :             if (o_compression)
     875 LBC           0 :                 ereport(ERROR,
     876                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     877 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     878 GIC          29 :             if (!parse_compress_algorithm(optval, &opt->compression))
     879 CBC           1 :                 ereport(ERROR,
     880 EUB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
     881                 :                          errmsg("unrecognized compression algorithm: \"%s\"",
     882                 :                                 optval)));
     883 CBC          28 :             o_compression = true;
     884 ECB             :         }
     885 GIC          14 :         else if (strcmp(defel->defname, "compression_detail") == 0)
     886 ECB             :         {
     887 GIC          14 :             if (o_compression_detail)
     888 LBC           0 :                 ereport(ERROR,
     889                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
     890 ECB             :                          errmsg("duplicate option \"%s\"", defel->defname)));
     891 GBC          14 :             compression_detail_str = defGetString(defel);
     892 GIC          14 :             o_compression_detail = true;
     893                 :         }
     894 ECB             :         else
     895 LBC           0 :             ereport(ERROR,
     896                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
     897                 :                      errmsg("unrecognized base backup option: \"%s\"",
     898                 :                             defel->defname)));
     899 ECB             :     }
     900                 : 
     901 CBC         140 :     if (opt->label == NULL)
     902 UIC           0 :         opt->label = "base backup";
     903 CBC         140 :     if (opt->manifest == MANIFEST_OPTION_NO)
     904 EUB             :     {
     905 GIC           1 :         if (o_manifest_checksums)
     906 UIC           0 :             ereport(ERROR,
     907 ECB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
     908                 :                      errmsg("manifest checksums require a backup manifest")));
     909 GIC           1 :         opt->manifest_checksum_type = CHECKSUM_TYPE_NONE;
     910                 :     }
     911 EUB             : 
     912 GIC         140 :     if (target_str == NULL)
     913                 :     {
     914 UIC           0 :         if (target_detail_str != NULL)
     915               0 :             ereport(ERROR,
     916                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
     917 ECB             :                      errmsg("target detail cannot be used without target")));
     918 UBC           0 :         opt->use_copytblspc = true;
     919 LBC           0 :         opt->send_to_client = true;
     920                 :     }
     921 CBC         140 :     else if (strcmp(target_str, "client") == 0)
     922 EUB             :     {
     923 GIC         125 :         if (target_detail_str != NULL)
     924 UIC           0 :             ereport(ERROR,
     925 ECB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
     926                 :                      errmsg("target \"%s\" does not accept a target detail",
     927                 :                             target_str)));
     928 CBC         125 :         opt->send_to_client = true;
     929                 :     }
     930 EUB             :     else
     931 GBC          13 :         opt->target_handle =
     932 GIC          15 :             BaseBackupGetTargetHandle(target_str, target_detail_str);
     933                 : 
     934 GBC         138 :     if (o_compression_detail && !o_compression)
     935 UBC           0 :         ereport(ERROR,
     936                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
     937 ECB             :                  errmsg("compression detail cannot be specified unless compression is enabled")));
     938                 : 
     939 CBC         138 :     if (o_compression)
     940 EUB             :     {
     941                 :         char       *error_detail;
     942                 : 
     943 GIC          26 :         parse_compress_specification(opt->compression, compression_detail_str,
     944 ECB             :                                      &opt->compression_specification);
     945                 :         error_detail =
     946 GIC          26 :             validate_compress_specification(&opt->compression_specification);
     947 CBC          26 :         if (error_detail != NULL)
     948               9 :             ereport(ERROR,
     949                 :                     errcode(ERRCODE_SYNTAX_ERROR),
     950 ECB             :                     errmsg("invalid compression specification: %s",
     951 EUB             :                            error_detail));
     952                 :     }
     953 GIC         129 : }
     954                 : 
     955 ECB             : 
     956                 : /*
     957                 :  * SendBaseBackup() - send a complete base backup.
     958                 :  *
     959                 :  * The function will put the system into backup mode like pg_backup_start()
     960                 :  * does, so that the backup is consistent even though we read directly from
     961                 :  * the filesystem, bypassing the buffer cache.
     962                 :  */
     963                 : void
     964 CBC         143 : SendBaseBackup(BaseBackupCmd *cmd)
     965                 : {
     966                 :     basebackup_options opt;
     967                 :     bbsink     *sink;
     968 GIC         143 :     SessionBackupState status = get_backup_status();
     969 ECB             : 
     970 GIC         143 :     if (status == SESSION_BACKUP_RUNNING)
     971               1 :         ereport(ERROR,
     972                 :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
     973                 :                  errmsg("a backup is already in progress in this session")));
     974                 : 
     975             142 :     parse_basebackup_options(cmd->options, &opt);
     976                 : 
     977             129 :     WalSndSetState(WALSNDSTATE_BACKUP);
     978                 : 
     979             129 :     if (update_process_title)
     980 ECB             :     {
     981                 :         char        activitymsg[50];
     982                 : 
     983 GIC         129 :         snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"",
     984 ECB             :                  opt.label);
     985 GIC         129 :         set_ps_display(activitymsg);
     986 ECB             :     }
     987                 : 
     988                 :     /*
     989                 :      * If the target is specifically 'client' then set up to stream the backup
     990                 :      * to the client; otherwise, it's being sent someplace else and should not
     991                 :      * be sent to the client. BaseBackupGetSink has the job of setting up a
     992                 :      * sink to send the backup data wherever it needs to go.
     993                 :      */
     994 GIC         129 :     sink = bbsink_copystream_new(opt.send_to_client);
     995 CBC         129 :     if (opt.target_handle != NULL)
     996 GIC          13 :         sink = BaseBackupGetSink(opt.target_handle, sink);
     997                 : 
     998                 :     /* Set up network throttling, if client requested it */
     999 CBC         126 :     if (opt.maxrate > 0)
    1000 GIC           1 :         sink = bbsink_throttle_new(sink, opt.maxrate);
    1001 ECB             : 
    1002                 :     /* Set up server-side compression, if client requested it */
    1003 GIC         126 :     if (opt.compression == PG_COMPRESSION_GZIP)
    1004               2 :         sink = bbsink_gzip_new(sink, &opt.compression_specification);
    1005             124 :     else if (opt.compression == PG_COMPRESSION_LZ4)
    1006               2 :         sink = bbsink_lz4_new(sink, &opt.compression_specification);
    1007             122 :     else if (opt.compression == PG_COMPRESSION_ZSTD)
    1008               4 :         sink = bbsink_zstd_new(sink, &opt.compression_specification);
    1009                 : 
    1010 ECB             :     /* Set up progress reporting. */
    1011 CBC         126 :     sink = bbsink_progress_new(sink, opt.progress);
    1012 ECB             : 
    1013                 :     /*
    1014                 :      * Perform the base backup, but make sure we clean up the bbsink even if
    1015                 :      * an error occurs.
    1016                 :      */
    1017 GIC         126 :     PG_TRY();
    1018                 :     {
    1019 CBC         126 :         perform_base_backup(&opt, sink);
    1020 ECB             :     }
    1021 CBC           4 :     PG_FINALLY();
    1022 ECB             :     {
    1023 CBC         121 :         bbsink_cleanup(sink);
    1024 ECB             :     }
    1025 GIC         121 :     PG_END_TRY();
    1026             117 : }
    1027 ECB             : 
    1028                 : /*
    1029                 :  * Inject a file with given name and content in the output tar stream.
    1030                 :  */
    1031                 : static void
    1032 GIC         170 : sendFileWithContent(bbsink *sink, const char *filename, const char *content,
    1033 ECB             :                     backup_manifest_info *manifest)
    1034                 : {
    1035                 :     struct stat statbuf;
    1036 GIC         170 :     int         bytes_done = 0,
    1037 ECB             :                 len;
    1038                 :     pg_checksum_context checksum_ctx;
    1039                 : 
    1040 GIC         170 :     if (pg_checksum_init(&checksum_ctx, manifest->checksum_type) < 0)
    1041 LBC           0 :         elog(ERROR, "could not initialize checksum of file \"%s\"",
    1042 ECB             :              filename);
    1043                 : 
    1044 GIC         170 :     len = strlen(content);
    1045                 : 
    1046                 :     /*
    1047                 :      * Construct a stat struct for the backup_label file we're injecting in
    1048 ECB             :      * the tar.
    1049                 :      */
    1050                 :     /* Windows doesn't have the concept of uid and gid */
    1051                 : #ifdef WIN32
    1052                 :     statbuf.st_uid = 0;
    1053                 :     statbuf.st_gid = 0;
    1054                 : #else
    1055 GIC         170 :     statbuf.st_uid = geteuid();
    1056 CBC         170 :     statbuf.st_gid = getegid();
    1057 EUB             : #endif
    1058 GIC         170 :     statbuf.st_mtime = time(NULL);
    1059             170 :     statbuf.st_mode = pg_file_create_mode;
    1060 CBC         170 :     statbuf.st_size = len;
    1061                 : 
    1062 GIC         170 :     _tarWriteHeader(sink, filename, NULL, &statbuf, false);
    1063                 : 
    1064             170 :     if (pg_checksum_update(&checksum_ctx, (uint8 *) content, len) < 0)
    1065 UIC           0 :         elog(ERROR, "could not update checksum of file \"%s\"",
    1066                 :              filename);
    1067                 : 
    1068 GIC         298 :     while (bytes_done < len)
    1069                 :     {
    1070             128 :         size_t      remaining = len - bytes_done;
    1071 CBC         128 :         size_t      nbytes = Min(sink->bbs_buffer_length, remaining);
    1072 ECB             : 
    1073 GIC         128 :         memcpy(sink->bbs_buffer, content, nbytes);
    1074 CBC         128 :         bbsink_archive_contents(sink, nbytes);
    1075             128 :         bytes_done += nbytes;
    1076             128 :         content += nbytes;
    1077                 :     }
    1078 ECB             : 
    1079 GIC         170 :     _tarWritePadding(sink, len);
    1080 ECB             : 
    1081 GBC         170 :     AddFileToBackupManifest(manifest, NULL, filename, len,
    1082 GIC         170 :                             (pg_time_t) statbuf.st_mtime, &checksum_ctx);
    1083             170 : }
    1084 ECB             : 
    1085                 : /*
    1086                 :  * Include the tablespace directory pointed to by 'path' in the output tar
    1087                 :  * stream.  If 'sizeonly' is true, we just calculate a total length and return
    1088                 :  * it, without actually sending anything.
    1089                 :  *
    1090                 :  * Only used to send auxiliary tablespaces, not PGDATA.
    1091                 :  */
    1092                 : static int64
    1093 GIC          32 : sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
    1094                 :                backup_manifest_info *manifest)
    1095 ECB             : {
    1096                 :     int64       size;
    1097                 :     char        pathbuf[MAXPGPATH];
    1098                 :     struct stat statbuf;
    1099                 : 
    1100                 :     /*
    1101                 :      * 'path' points to the tablespace location, but we only want to include
    1102                 :      * the version directory in it that belongs to us.
    1103                 :      */
    1104 GIC          32 :     snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path,
    1105                 :              TABLESPACE_VERSION_DIRECTORY);
    1106                 : 
    1107                 :     /*
    1108                 :      * Store a directory entry in the tar file so we get the permissions
    1109 ECB             :      * right.
    1110                 :      */
    1111 GIC          32 :     if (lstat(pathbuf, &statbuf) != 0)
    1112                 :     {
    1113 UIC           0 :         if (errno != ENOENT)
    1114               0 :             ereport(ERROR,
    1115                 :                     (errcode_for_file_access(),
    1116                 :                      errmsg("could not stat file or directory \"%s\": %m",
    1117                 :                             pathbuf)));
    1118                 : 
    1119                 :         /* If the tablespace went away while scanning, it's no error. */
    1120 LBC           0 :         return 0;
    1121                 :     }
    1122                 : 
    1123 GIC          32 :     size = _tarWriteHeader(sink, TABLESPACE_VERSION_DIRECTORY, NULL, &statbuf,
    1124                 :                            sizeonly);
    1125                 : 
    1126                 :     /* Send all the files in the tablespace version directory */
    1127 CBC          32 :     size += sendDir(sink, pathbuf, strlen(path), sizeonly, NIL, true, manifest,
    1128                 :                     spcoid);
    1129 EUB             : 
    1130 GBC          32 :     return size;
    1131                 : }
    1132                 : 
    1133                 : /*
    1134                 :  * Include all files from the given directory in the output tar stream. If
    1135                 :  * 'sizeonly' is true, we just calculate a total length and return it, without
    1136 EUB             :  * actually sending anything.
    1137                 :  *
    1138                 :  * Omit any directory in the tablespaces list, to avoid backing up
    1139 ECB             :  * tablespaces twice when they were created inside PGDATA.
    1140                 :  *
    1141                 :  * If sendtblspclinks is true, we need to include symlink
    1142                 :  * information in the tar file. If not, we can skip that
    1143                 :  * as it will be sent separately in the tablespace_map file.
    1144                 :  */
    1145                 : static int64
    1146 CBC        4316 : sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
    1147                 :         List *tablespaces, bool sendtblspclinks, backup_manifest_info *manifest,
    1148                 :         const char *spcoid)
    1149                 : {
    1150                 :     DIR        *dir;
    1151                 :     struct dirent *de;
    1152                 :     char        pathbuf[MAXPGPATH * 2];
    1153                 :     struct stat statbuf;
    1154 GIC        4316 :     int64       size = 0;
    1155                 :     const char *lastDir;        /* Split last dir from parent path. */
    1156            4316 :     bool        isDbDir = false;    /* Does this directory contain relations? */
    1157                 : 
    1158                 :     /*
    1159                 :      * Determine if the current path is a database directory that can contain
    1160                 :      * relations.
    1161                 :      *
    1162 ECB             :      * Start by finding the location of the delimiter between the parent path
    1163                 :      * and the current path.
    1164                 :      */
    1165 GIC        4316 :     lastDir = last_dir_separator(path);
    1166                 : 
    1167                 :     /* Does this path look like a database path (i.e. all digits)? */
    1168            4316 :     if (lastDir != NULL &&
    1169            4064 :         strspn(lastDir + 1, "0123456789") == strlen(lastDir + 1))
    1170 ECB             :     {
    1171                 :         /* Part of path that contains the parent directory. */
    1172 CBC         811 :         int         parentPathLen = lastDir - path;
    1173                 : 
    1174                 :         /*
    1175                 :          * Mark path as a database directory if the parent path is either
    1176                 :          * $PGDATA/base or a tablespace version path.
    1177                 :          */
    1178 GIC         811 :         if (strncmp(path, "./base", parentPathLen) == 0 ||
    1179              54 :             (parentPathLen >= (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) &&
    1180              32 :              strncmp(lastDir - (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1),
    1181 ECB             :                      TABLESPACE_VERSION_DIRECTORY,
    1182                 :                      sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) == 0))
    1183 GIC         789 :             isDbDir = true;
    1184 ECB             :     }
    1185                 : 
    1186 GIC        4316 :     dir = AllocateDir(path);
    1187          263588 :     while ((de = ReadDir(dir, path)) != NULL)
    1188 ECB             :     {
    1189                 :         int         excludeIdx;
    1190                 :         bool        excludeFound;
    1191                 :         ForkNumber  relForkNum; /* Type of fork if file is a relation */
    1192                 :         int         relnumchars;    /* Chars in filename that are the
    1193                 :                                      * relnumber */
    1194                 : 
    1195                 :         /* Skip special stuff */
    1196 CBC      259286 :         if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
    1197           12211 :             continue;
    1198                 : 
    1199                 :         /* Skip temporary files */
    1200          250667 :         if (strncmp(de->d_name,
    1201                 :                     PG_TEMP_FILE_PREFIX,
    1202                 :                     strlen(PG_TEMP_FILE_PREFIX)) == 0)
    1203             247 :             continue;
    1204 ECB             : 
    1205                 :         /*
    1206                 :          * Check if the postmaster has signaled us to exit, and abort with an
    1207                 :          * error in that case. The error handler further up will call
    1208                 :          * do_pg_abort_backup() for us. Also check that if the backup was
    1209                 :          * started while still in recovery, the server wasn't promoted.
    1210                 :          * do_pg_backup_stop() will check that too, but it's better to stop
    1211                 :          * the backup early than continue to the end and fail there.
    1212                 :          */
    1213 CBC      250420 :         CHECK_FOR_INTERRUPTS();
    1214          250415 :         if (RecoveryInProgress() != backup_started_in_recovery)
    1215 UIC           0 :             ereport(ERROR,
    1216                 :                     (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
    1217 ECB             :                      errmsg("the standby was promoted during online backup"),
    1218                 :                      errhint("This means that the backup being taken is corrupt "
    1219                 :                              "and should not be used. "
    1220                 :                              "Try taking another online backup.")));
    1221                 : 
    1222                 :         /* Scan for files that should be excluded */
    1223 GIC      250415 :         excludeFound = false;
    1224         2249800 :         for (excludeIdx = 0; excludeFiles[excludeIdx].name != NULL; excludeIdx++)
    1225                 :         {
    1226         2000384 :             int         cmplen = strlen(excludeFiles[excludeIdx].name);
    1227                 : 
    1228         2000384 :             if (!excludeFiles[excludeIdx].match_prefix)
    1229         1750103 :                 cmplen++;
    1230 CBC     2000384 :             if (strncmp(de->d_name, excludeFiles[excludeIdx].name, cmplen) == 0)
    1231 ECB             :             {
    1232 GBC         999 :                 elog(DEBUG1, "file \"%s\" excluded from backup", de->d_name);
    1233 GIC         999 :                 excludeFound = true;
    1234             999 :                 break;
    1235                 :             }
    1236                 :         }
    1237                 : 
    1238          250415 :         if (excludeFound)
    1239             999 :             continue;
    1240 ECB             : 
    1241                 :         /* Exclude all forks for unlogged tables except the init fork */
    1242 GIC      475116 :         if (isDbDir &&
    1243 GNC      225700 :             parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
    1244                 :                                                 &relForkNum))
    1245 ECB             :         {
    1246                 :             /* Never exclude init forks */
    1247 CBC      224148 :             if (relForkNum != INIT_FORKNUM)
    1248                 :             {
    1249 ECB             :                 char        initForkFile[MAXPGPATH];
    1250                 :                 char        relNumber[OIDCHARS + 1];
    1251                 : 
    1252                 :                 /*
    1253                 :                  * If any other type of fork, check if there is an init fork
    1254                 :                  * with the same RelFileNumber. If so, the file can be
    1255                 :                  * excluded.
    1256                 :                  */
    1257 GNC      224079 :                 memcpy(relNumber, de->d_name, relnumchars);
    1258          224079 :                 relNumber[relnumchars] = '\0';
    1259 GIC      224079 :                 snprintf(initForkFile, sizeof(initForkFile), "%s/%s_init",
    1260                 :                          path, relNumber);
    1261 ECB             : 
    1262 GIC      224079 :                 if (lstat(initForkFile, &statbuf) == 0)
    1263                 :                 {
    1264              69 :                     elog(DEBUG2,
    1265 ECB             :                          "unlogged relation file \"%s\" excluded from backup",
    1266                 :                          de->d_name);
    1267                 : 
    1268 GIC          69 :                     continue;
    1269                 :                 }
    1270                 :             }
    1271                 :         }
    1272                 : 
    1273                 :         /* Exclude temporary relations */
    1274          249347 :         if (isDbDir && looks_like_temp_rel_name(de->d_name))
    1275 ECB             :         {
    1276 CBC          40 :             elog(DEBUG2,
    1277 ECB             :                  "temporary relation file \"%s\" excluded from backup",
    1278                 :                  de->d_name);
    1279                 : 
    1280 CBC          40 :             continue;
    1281                 :         }
    1282 ECB             : 
    1283 GIC      249307 :         snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
    1284                 : 
    1285                 :         /* Skip pg_control here to back up it last */
    1286 CBC      249307 :         if (strcmp(pathbuf, "./global/pg_control") == 0)
    1287 GIC         247 :             continue;
    1288                 : 
    1289          249060 :         if (lstat(pathbuf, &statbuf) != 0)
    1290                 :         {
    1291 UIC           0 :             if (errno != ENOENT)
    1292 LBC           0 :                 ereport(ERROR,
    1293                 :                         (errcode_for_file_access(),
    1294 ECB             :                          errmsg("could not stat file or directory \"%s\": %m",
    1295                 :                                 pathbuf)));
    1296                 : 
    1297                 :             /* If the file went away while scanning, it's not an error. */
    1298 LBC           0 :             continue;
    1299                 :         }
    1300                 : 
    1301 ECB             :         /* Scan for directories whose contents should be excluded */
    1302 GIC      249060 :         excludeFound = false;
    1303         1985521 :         for (excludeIdx = 0; excludeDirContents[excludeIdx] != NULL; excludeIdx++)
    1304 ECB             :         {
    1305 CBC     1738199 :             if (strcmp(de->d_name, excludeDirContents[excludeIdx]) == 0)
    1306                 :             {
    1307            1738 :                 elog(DEBUG1, "contents of directory \"%s\" excluded from backup", de->d_name);
    1308 GIC        1738 :                 convert_link_to_directory(pathbuf, &statbuf);
    1309 GBC        1738 :                 size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, NULL,
    1310 EUB             :                                         &statbuf, sizeonly);
    1311 GIC        1738 :                 excludeFound = true;
    1312            1738 :                 break;
    1313                 :             }
    1314                 :         }
    1315                 : 
    1316 GBC      249060 :         if (excludeFound)
    1317 GIC        1738 :             continue;
    1318                 : 
    1319                 :         /*
    1320 ECB             :          * We can skip pg_wal, the WAL segments need to be fetched from the
    1321                 :          * WAL archive anyway. But include it as an empty directory anyway, so
    1322                 :          * we get permissions right.
    1323                 :          */
    1324 GIC      247322 :         if (strcmp(pathbuf, "./pg_wal") == 0)
    1325 ECB             :         {
    1326                 :             /* If pg_wal is a symlink, write it as a directory anyway */
    1327 CBC         252 :             convert_link_to_directory(pathbuf, &statbuf);
    1328 GIC         252 :             size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, NULL,
    1329 ECB             :                                     &statbuf, sizeonly);
    1330                 : 
    1331                 :             /*
    1332                 :              * Also send archive_status directory (by hackishly reusing
    1333                 :              * statbuf from above ...).
    1334                 :              */
    1335 CBC         252 :             size += _tarWriteHeader(sink, "./pg_wal/archive_status", NULL,
    1336                 :                                     &statbuf, sizeonly);
    1337                 : 
    1338 GIC         252 :             continue;           /* don't recurse into pg_wal */
    1339                 :         }
    1340                 : 
    1341                 :         /* Allow symbolic links in pg_tblspc only */
    1342 GNC      247070 :         if (strcmp(path, "./pg_tblspc") == 0 && S_ISLNK(statbuf.st_mode))
    1343 GIC          29 :         {
    1344                 :             char        linkpath[MAXPGPATH];
    1345                 :             int         rllen;
    1346 ECB             : 
    1347 GIC          29 :             rllen = readlink(pathbuf, linkpath, sizeof(linkpath));
    1348              29 :             if (rllen < 0)
    1349 LBC           0 :                 ereport(ERROR,
    1350                 :                         (errcode_for_file_access(),
    1351                 :                          errmsg("could not read symbolic link \"%s\": %m",
    1352                 :                                 pathbuf)));
    1353 CBC          29 :             if (rllen >= sizeof(linkpath))
    1354 LBC           0 :                 ereport(ERROR,
    1355                 :                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
    1356                 :                          errmsg("symbolic link \"%s\" target is too long",
    1357                 :                                 pathbuf)));
    1358 CBC          29 :             linkpath[rllen] = '\0';
    1359 ECB             : 
    1360 GBC          29 :             size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, linkpath,
    1361                 :                                     &statbuf, sizeonly);
    1362 ECB             :         }
    1363 GIC      247041 :         else if (S_ISDIR(statbuf.st_mode))
    1364 ECB             :         {
    1365 GIC        4056 :             bool        skip_this_dir = false;
    1366                 :             ListCell   *lc;
    1367                 : 
    1368                 :             /*
    1369                 :              * Store a directory entry in the tar file so we can get the
    1370                 :              * permissions right.
    1371 ECB             :              */
    1372 GIC        4056 :             size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, NULL, &statbuf,
    1373                 :                                     sizeonly);
    1374                 : 
    1375                 :             /*
    1376                 :              * Call ourselves recursively for a directory, unless it happens
    1377                 :              * to be a separate tablespace located within PGDATA.
    1378 ECB             :              */
    1379 GIC        8580 :             foreach(lc, tablespaces)
    1380 ECB             :             {
    1381 GIC        4524 :                 tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc);
    1382                 : 
    1383                 :                 /*
    1384                 :                  * ti->rpath is the tablespace relative path within PGDATA, or
    1385                 :                  * NULL if the tablespace has been properly located somewhere
    1386                 :                  * else.
    1387                 :                  *
    1388                 :                  * Skip past the leading "./" in pathbuf when comparing.
    1389 ECB             :                  */
    1390 GIC        4524 :                 if (ti->rpath && strcmp(ti->rpath, pathbuf + 2) == 0)
    1391 EUB             :                 {
    1392 UBC           0 :                     skip_this_dir = true;
    1393 UIC           0 :                     break;
    1394                 :                 }
    1395                 :             }
    1396                 : 
    1397                 :             /*
    1398                 :              * skip sending directories inside pg_tblspc, if not required.
    1399 ECB             :              */
    1400 CBC        4056 :             if (strcmp(pathbuf, "./pg_tblspc") == 0 && !sendtblspclinks)
    1401 GIC          24 :                 skip_this_dir = true;
    1402 ECB             : 
    1403 CBC        4056 :             if (!skip_this_dir)
    1404 GIC        4032 :                 size += sendDir(sink, pathbuf, basepathlen, sizeonly, tablespaces,
    1405                 :                                 sendtblspclinks, manifest, spcoid);
    1406 ECB             :         }
    1407 GIC      242985 :         else if (S_ISREG(statbuf.st_mode))
    1408 ECB             :         {
    1409 GIC      242985 :             bool        sent = false;
    1410 ECB             : 
    1411 CBC      242985 :             if (!sizeonly)
    1412          229966 :                 sent = sendFile(sink, pathbuf, pathbuf + basepathlen + 1, &statbuf,
    1413 GIC      110721 :                                 true, isDbDir ? atooid(lastDir + 1) : InvalidOid,
    1414                 :                                 manifest, spcoid);
    1415 ECB             : 
    1416 GIC      242984 :             if (sent || sizeonly)
    1417                 :             {
    1418 ECB             :                 /* Add size. */
    1419 GIC      242984 :                 size += statbuf.st_size;
    1420                 : 
    1421 ECB             :                 /* Pad to a multiple of the tar block size. */
    1422 GIC      242984 :                 size += tarPaddingBytesRequired(statbuf.st_size);
    1423                 : 
    1424 ECB             :                 /* Size of the header for the file. */
    1425 GIC      242984 :                 size += TAR_BLOCK_SIZE;
    1426                 :             }
    1427                 :         }
    1428 EUB             :         else
    1429 UIC           0 :             ereport(WARNING,
    1430                 :                     (errmsg("skipping special file \"%s\"", pathbuf)));
    1431 ECB             :     }
    1432 CBC        4302 :     FreeDir(dir);
    1433 GIC        4302 :     return size;
    1434                 : }
    1435                 : 
    1436                 : /*
    1437                 :  * Check if a file should have its checksum validated.
    1438                 :  * We validate checksums on files in regular tablespaces
    1439                 :  * (including global and default) only, and in those there
    1440                 :  * are some files that are explicitly excluded.
    1441                 :  */
    1442 ECB             : static bool
    1443 GIC       28387 : is_checksummed_file(const char *fullpath, const char *filename)
    1444                 : {
    1445 ECB             :     /* Check that the file is in a tablespace */
    1446 CBC       28387 :     if (strncmp(fullpath, "./global/", 9) == 0 ||
    1447           26618 :         strncmp(fullpath, "./base/", 7) == 0 ||
    1448 GIC         329 :         strncmp(fullpath, "/", 1) == 0)
    1449                 :     {
    1450                 :         int         excludeIdx;
    1451                 : 
    1452 ECB             :         /* Compare file against noChecksumFiles skip list */
    1453 GIC      139874 :         for (excludeIdx = 0; noChecksumFiles[excludeIdx].name != NULL; excludeIdx++)
    1454 ECB             :         {
    1455 GIC      112016 :             int         cmplen = strlen(noChecksumFiles[excludeIdx].name);
    1456 ECB             : 
    1457 CBC      112016 :             if (!noChecksumFiles[excludeIdx].match_prefix)
    1458           84071 :                 cmplen++;
    1459 GIC      112016 :             if (strncmp(filename, noChecksumFiles[excludeIdx].name,
    1460 ECB             :                         cmplen) == 0)
    1461 GIC         205 :                 return false;
    1462                 :         }
    1463 ECB             : 
    1464 GIC       27858 :         return true;
    1465                 :     }
    1466 ECB             :     else
    1467 GIC         324 :         return false;
    1468                 : }
    1469                 : 
    1470                 : /*
    1471                 :  * Given the member, write the TAR header & send the file.
    1472                 :  *
    1473                 :  * If 'missing_ok' is true, will not throw an error if the file is not found.
    1474 ECB             :  *
    1475                 :  * If dboid is anything other than InvalidOid then any checksum failures
    1476                 :  * detected will get reported to the cumulative stats system.
    1477                 :  *
    1478                 :  * Returns true if the file was successfully sent, false if 'missing_ok',
    1479                 :  * and the file did not exist.
    1480                 :  */
    1481                 : static bool
    1482 CBC      119365 : sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
    1483                 :          struct stat *statbuf, bool missing_ok, Oid dboid,
    1484                 :          backup_manifest_info *manifest, const char *spcoid)
    1485 ECB             : {
    1486                 :     int         fd;
    1487 GIC      119365 :     BlockNumber blkno = 0;
    1488 CBC      119365 :     bool        block_retry = false;
    1489                 :     uint16      checksum;
    1490          119365 :     int         checksum_failures = 0;
    1491                 :     off_t       cnt;
    1492                 :     int         i;
    1493          119365 :     pgoff_t     len = 0;
    1494 EUB             :     char       *page;
    1495                 :     PageHeader  phdr;
    1496 GIC      119365 :     int         segmentno = 0;
    1497 ECB             :     char       *segmentpath;
    1498 CBC      119365 :     bool        verify_checksum = false;
    1499                 :     pg_checksum_context checksum_ctx;
    1500 EUB             : 
    1501 GBC      119365 :     if (pg_checksum_init(&checksum_ctx, manifest->checksum_type) < 0)
    1502 UBC           0 :         elog(ERROR, "could not initialize checksum of file \"%s\"",
    1503                 :              readfilename);
    1504                 : 
    1505 GIC      119365 :     fd = OpenTransientFile(readfilename, O_RDONLY | PG_BINARY);
    1506          119365 :     if (fd < 0)
    1507 ECB             :     {
    1508 UIC           0 :         if (errno == ENOENT && missing_ok)
    1509 LBC           0 :             return false;
    1510 UIC           0 :         ereport(ERROR,
    1511                 :                 (errcode_for_file_access(),
    1512                 :                  errmsg("could not open file \"%s\": %m", readfilename)));
    1513                 :     }
    1514                 : 
    1515 GIC      119365 :     _tarWriteHeader(sink, tarfilename, NULL, statbuf, false);
    1516                 : 
    1517          119364 :     if (!noverify_checksums && DataChecksumsEnabled())
    1518 ECB             :     {
    1519                 :         char       *filename;
    1520                 : 
    1521                 :         /*
    1522                 :          * Get the filename (excluding path).  As last_dir_separator()
    1523                 :          * includes the last directory separator, we chop that off by
    1524                 :          * incrementing the pointer.
    1525                 :          */
    1526 GIC       28387 :         filename = last_dir_separator(readfilename) + 1;
    1527                 : 
    1528 CBC       28387 :         if (is_checksummed_file(readfilename, filename))
    1529 ECB             :         {
    1530 GIC       27858 :             verify_checksum = true;
    1531 EUB             : 
    1532                 :             /*
    1533                 :              * Cut off at the segment boundary (".") to get the segment number
    1534                 :              * in order to mix it into the checksum.
    1535                 :              */
    1536 GIC       27858 :             segmentpath = strstr(filename, ".");
    1537           27858 :             if (segmentpath != NULL)
    1538                 :             {
    1539 UIC           0 :                 segmentno = atoi(segmentpath + 1);
    1540               0 :                 if (segmentno == 0)
    1541               0 :                     ereport(ERROR,
    1542                 :                             (errmsg("invalid segment number %d in file \"%s\"",
    1543                 :                                     segmentno, filename)));
    1544                 :             }
    1545                 :         }
    1546 ECB             :     }
    1547                 : 
    1548                 :     /*
    1549                 :      * Loop until we read the amount of data the caller told us to expect. The
    1550                 :      * file could be longer, if it was extended while we were sending it, but
    1551                 :      * for a base backup we can ignore such extended data. It will be restored
    1552                 :      * from WAL.
    1553                 :      */
    1554 GIC      265468 :     while (len < statbuf->st_size)
    1555                 :     {
    1556          146104 :         size_t      remaining = statbuf->st_size - len;
    1557                 : 
    1558                 :         /* Try to read some more data. */
    1559          292208 :         cnt = basebackup_read_file(fd, sink->bbs_buffer,
    1560          146104 :                                    Min(sink->bbs_buffer_length, remaining),
    1561 ECB             :                                    len, readfilename, true);
    1562                 : 
    1563                 :         /*
    1564                 :          * The checksums are verified at block level, so we iterate over the
    1565 EUB             :          * buffer in chunks of BLCKSZ, after making sure that
    1566                 :          * TAR_SEND_SIZE/buf is divisible by BLCKSZ and we read a multiple of
    1567                 :          * BLCKSZ bytes.
    1568                 :          */
    1569 GIC      146104 :         Assert((sink->bbs_buffer_length % BLCKSZ) == 0);
    1570 EUB             : 
    1571 GIC      146104 :         if (verify_checksum && (cnt % BLCKSZ != 0))
    1572                 :         {
    1573 LBC           0 :             ereport(WARNING,
    1574                 :                     (errmsg("could not verify checksum in file \"%s\", block "
    1575 ECB             :                             "%u: read buffer size %d and page size %d "
    1576                 :                             "differ",
    1577                 :                             readfilename, blkno, (int) cnt, BLCKSZ)));
    1578 UIC           0 :             verify_checksum = false;
    1579                 :         }
    1580                 : 
    1581 GIC      146104 :         if (verify_checksum)
    1582                 :         {
    1583          118694 :             for (i = 0; i < cnt / BLCKSZ; i++)
    1584                 :             {
    1585           84496 :                 page = sink->bbs_buffer + BLCKSZ * i;
    1586                 : 
    1587 ECB             :                 /*
    1588                 :                  * Only check pages which have not been modified since the
    1589                 :                  * start of the base backup. Otherwise, they might have been
    1590                 :                  * written only halfway and the checksum would not be valid.
    1591                 :                  * However, replaying WAL would reinstate the correct page in
    1592                 :                  * this case. We also skip completely new pages, since they
    1593                 :                  * don't have a checksum yet.
    1594                 :                  */
    1595 GIC       84496 :                 if (!PageIsNew(page) && PageGetLSN(page) < sink->bbs_state->startptr)
    1596                 :                 {
    1597           84496 :                     checksum = pg_checksum_page((char *) page, blkno + segmentno * RELSEG_SIZE);
    1598           84496 :                     phdr = (PageHeader) page;
    1599           84496 :                     if (phdr->pd_checksum != checksum)
    1600                 :                     {
    1601                 :                         /*
    1602                 :                          * Retry the block on the first failure.  It's
    1603                 :                          * possible that we read the first 4K page of the
    1604                 :                          * block just before postgres updated the entire block
    1605                 :                          * so it ends up looking torn to us. If, before we
    1606                 :                          * retry the read, the concurrent write of the block
    1607                 :                          * finishes, the page LSN will be updated and we'll
    1608                 :                          * realize that we should ignore this block.
    1609                 :                          *
    1610                 :                          * There's no guarantee that this will actually
    1611                 :                          * happen, though: the torn write could take an
    1612                 :                          * arbitrarily long time to complete. Retrying multiple
    1613                 :                          * times wouldn't fix this problem, either, though
    1614                 :                          * it would reduce the chances of it happening in
    1615                 :                          * practice. The only real fix here seems to be to
    1616                 :                          * have some kind of interlock that allows us to wait
    1617                 :                          * until we can be certain that no write to the block
    1618                 :                          * is in progress. Since we don't have any such thing
    1619                 :                          * right now, we just do this and hope for the best.
    1620                 :                          */
    1621              28 :                         if (block_retry == false)
    1622              14 :                         {
    1623 ECB             :                             int         reread_cnt;
    1624                 : 
    1625                 :                             /* Reread the failed block */
    1626                 :                             reread_cnt =
    1627 GIC          14 :                                 basebackup_read_file(fd,
    1628              14 :                                                      sink->bbs_buffer + BLCKSZ * i,
    1629 CBC          14 :                                                      BLCKSZ, len + BLCKSZ * i,
    1630 ECB             :                                                      readfilename,
    1631                 :                                                      false);
    1632 GIC          14 :                             if (reread_cnt == 0)
    1633                 :                             {
    1634 ECB             :                                 /*
    1635                 :                                  * If we hit end-of-file, a concurrent
    1636                 :                                  * truncation must have occurred, so break out
    1637                 :                                  * of this loop just as if the initial fread()
    1638                 :                                  * returned 0. We'll drop through to the same
    1639                 :                                  * code that handles that case. (We must fix
    1640                 :                                  * up cnt first, though.)
    1641                 :                                  */
    1642 UIC           0 :                                 cnt = BLCKSZ * i;
    1643               0 :                                 break;
    1644 EUB             :                             }
    1645                 : 
    1646                 :                             /* Set flag so we know a retry was attempted */
    1647 GIC          14 :                             block_retry = true;
    1648                 : 
    1649 ECB             :                             /* Reset loop to validate the block again */
    1650 GIC          14 :                             i--;
    1651              14 :                             continue;
    1652 ECB             :                         }
    1653                 : 
    1654 GIC          14 :                         checksum_failures++;
    1655                 : 
    1656 CBC          14 :                         if (checksum_failures <= 5)
    1657 GIC          12 :                             ereport(WARNING,
    1658 ECB             :                                     (errmsg("checksum verification failed in "
    1659                 :                                             "file \"%s\", block %u: calculated "
    1660                 :                                             "%X but expected %X",
    1661                 :                                             readfilename, blkno, checksum,
    1662                 :                                             phdr->pd_checksum)));
    1663 GIC          14 :                         if (checksum_failures == 5)
    1664               2 :                             ereport(WARNING,
    1665 ECB             :                                     (errmsg("further checksum verification "
    1666                 :                                             "failures in file \"%s\" will not "
    1667                 :                                             "be reported", readfilename)));
    1668                 :                     }
    1669                 :                 }
    1670 GIC       84482 :                 block_retry = false;
    1671           84482 :                 blkno++;
    1672 ECB             :             }
    1673                 :         }
    1674                 : 
    1675                 :         /*
    1676                 :          * If we hit end-of-file, a concurrent truncation must have occurred.
    1677                 :          * That's not an error condition, because WAL replay will fix things
    1678                 :          * up.
    1679                 :          */
    1680 GIC      146104 :         if (cnt == 0)
    1681 UIC           0 :             break;
    1682 ECB             : 
    1683 EUB             :         /* Archive the data we just read. */
    1684 GIC      146104 :         bbsink_archive_contents(sink, cnt);
    1685                 : 
    1686 ECB             :         /* Also feed it to the checksum machinery. */
    1687 GIC      146104 :         if (pg_checksum_update(&checksum_ctx,
    1688          146104 :                                (uint8 *) sink->bbs_buffer, cnt) < 0)
    1689 LBC           0 :             elog(ERROR, "could not update checksum of base backup");
    1690 ECB             : 
    1691 GBC      146104 :         len += cnt;
    1692                 :     }
    1693 ECB             : 
    1694                 :     /* If the file was truncated while we were sending it, pad it with zeros */
    1695 GIC      119364 :     while (len < statbuf->st_size)
    1696                 :     {
    1697 LBC           0 :         size_t      remaining = statbuf->st_size - len;
    1698 UIC           0 :         size_t      nbytes = Min(sink->bbs_buffer_length, remaining);
    1699 EUB             : 
    1700 UBC           0 :         MemSet(sink->bbs_buffer, 0, nbytes);
    1701 UIC           0 :         if (pg_checksum_update(&checksum_ctx,
    1702 UBC           0 :                                (uint8 *) sink->bbs_buffer,
    1703 EUB             :                                nbytes) < 0)
    1704 UBC           0 :             elog(ERROR, "could not update checksum of base backup");
    1705 UIC           0 :         bbsink_archive_contents(sink, nbytes);
    1706 UBC           0 :         len += nbytes;
    1707 EUB             :     }
    1708                 : 
    1709                 :     /*
    1710                 :      * Pad to a block boundary, per tar format requirements. (This small piece
    1711                 :      * of data is probably not worth throttling, and is not checksummed
    1712                 :      * because it's not actually part of the file.)
    1713                 :      */
    1714 GIC      119364 :     _tarWritePadding(sink, len);
    1715                 : 
    1716 CBC      119364 :     CloseTransientFile(fd);
    1717                 : 
    1718          119364 :     if (checksum_failures > 1)
    1719                 :     {
    1720               2 :         ereport(WARNING,
    1721                 :                 (errmsg_plural("file \"%s\" has a total of %d checksum verification failure",
    1722 ECB             :                                "file \"%s\" has a total of %d checksum verification failures",
    1723                 :                                checksum_failures,
    1724                 :                                readfilename, checksum_failures)));
    1725                 : 
    1726 GIC           2 :         pgstat_report_checksum_failures_in_db(dboid, checksum_failures);
    1727                 :     }
    1728 ECB             : 
    1729 GIC      119364 :     total_checksum_failures += checksum_failures;
    1730                 : 
    1731 CBC      119364 :     AddFileToBackupManifest(manifest, spcoid, tarfilename, statbuf->st_size,
    1732 GIC      119364 :                             (pg_time_t) statbuf->st_mtime, &checksum_ctx);
    1733 ECB             : 
    1734 CBC      119364 :     return true;
    1735                 : }
    1736 ECB             : 
    1737                 : static int64
    1738 GIC      125914 : _tarWriteHeader(bbsink *sink, const char *filename, const char *linktarget,
    1739                 :                 struct stat *statbuf, bool sizeonly)
    1740 ECB             : {
    1741                 :     enum tarError rc;
    1742                 : 
    1743 GIC      125914 :     if (!sizeonly)
    1744                 :     {
    1745 ECB             :         /*
    1746                 :          * As of this writing, the smallest supported block size is 1kB, which
    1747                 :          * is twice TAR_BLOCK_SIZE. Since the buffer size is required to be a
    1748                 :          * multiple of BLCKSZ, it should be safe to assume that the buffer is
    1749                 :          * large enough to fit an entire tar block. We double-check by means
    1750                 :          * of these assertions.
    1751                 :          */
    1752                 :         StaticAssertDecl(TAR_BLOCK_SIZE <= BLCKSZ,
    1753                 :                          "BLCKSZ too small for tar block");
    1754 GIC      122684 :         Assert(sink->bbs_buffer_length >= TAR_BLOCK_SIZE);
    1755                 : 
    1756 CBC      122684 :         rc = tarCreateHeader(sink->bbs_buffer, filename, linktarget,
    1757                 :                              statbuf->st_size, statbuf->st_mode,
    1758 ECB             :                              statbuf->st_uid, statbuf->st_gid,
    1759                 :                              statbuf->st_mtime);
    1760                 : 
    1761 GIC      122684 :         switch (rc)
    1762                 :         {
    1763 CBC      122683 :             case TAR_OK:
    1764 GIC      122683 :                 break;
    1765 CBC           1 :             case TAR_NAME_TOO_LONG:
    1766               1 :                 ereport(ERROR,
    1767 ECB             :                         (errmsg("file name too long for tar format: \"%s\"",
    1768                 :                                 filename)));
    1769                 :                 break;
    1770 UIC           0 :             case TAR_SYMLINK_TOO_LONG:
    1771               0 :                 ereport(ERROR,
    1772 EUB             :                         (errmsg("symbolic link target too long for tar format: "
    1773                 :                                 "file name \"%s\", target \"%s\"",
    1774                 :                                 filename, linktarget)));
    1775                 :                 break;
    1776 UIC           0 :             default:
    1777               0 :                 elog(ERROR, "unrecognized tar error: %d", rc);
    1778 EUB             :         }
    1779                 : 
    1780 GIC      122683 :         bbsink_archive_contents(sink, TAR_BLOCK_SIZE);
    1781                 :     }
    1782 ECB             : 
    1783 GIC      125913 :     return TAR_BLOCK_SIZE;
    1784                 : }
    1785 ECB             : 
    1786                 : /*
    1787                 :  * Pad with zero bytes out to a multiple of TAR_BLOCK_SIZE.
    1788                 :  */
    1789                 : static void
    1790 GIC      119534 : _tarWritePadding(bbsink *sink, int len)
    1791                 : {
    1792 CBC      119534 :     int         pad = tarPaddingBytesRequired(len);
    1793                 : 
    1794 ECB             :     /*
    1795                 :      * As in _tarWriteHeader, it should be safe to assume that the buffer is
    1796                 :      * large enough that we don't need to do this in multiple chunks.
    1797                 :      */
    1798 GIC      119534 :     Assert(sink->bbs_buffer_length >= TAR_BLOCK_SIZE);
    1799          119534 :     Assert(pad <= TAR_BLOCK_SIZE);
    1800 ECB             : 
    1801 CBC      119534 :     if (pad > 0)
    1802                 :     {
    1803           22769 :         MemSet(sink->bbs_buffer, 0, pad);
    1804 GIC        1768 :         bbsink_archive_contents(sink, pad);
    1805 ECB             :     }
    1806 CBC      119534 : }
    1807                 : 
    1808 ECB             : /*
    1809                 :  * If the entry in statbuf is a link, then adjust statbuf to make it look like a
    1810                 :  * directory, so that it will be written that way.
    1811                 :  */
    1812                 : static void
    1813 GIC        1990 : convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
    1814                 : {
    1815 ECB             :     /* If symlink, write it as a directory anyway */
    1816 GIC        1990 :     if (S_ISLNK(statbuf->st_mode))
    1817              66 :         statbuf->st_mode = S_IFDIR | pg_dir_create_mode;
    1818            1990 : }
    1819                 : 
    1820                 : /*
    1821                 :  * Read some data from a file, setting a wait event and reporting any error
    1822                 :  * encountered.
    1823                 :  *
    1824                 :  * If partial_read_ok is false, also report an error if the number of bytes
    1825                 :  * read is not equal to the number of bytes requested.
    1826                 :  *
    1827                 :  * Returns the number of bytes read.
    1828 ECB             :  */
    1829                 : static int
    1830 GIC      156358 : basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
    1831                 :                      const char *filename, bool partial_read_ok)
    1832                 : {
    1833 ECB             :     int         rc;
    1834                 : 
    1835 CBC      156358 :     pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
    1836 GIC      156358 :     rc = pg_pread(fd, buf, nbytes, offset);
    1837 CBC      156358 :     pgstat_report_wait_end();
    1838 EUB             : 
    1839 GIC      156358 :     if (rc < 0)
    1840 UIC           0 :         ereport(ERROR,
    1841 ECB             :                 (errcode_for_file_access(),
    1842 EUB             :                  errmsg("could not read file \"%s\": %m", filename)));
    1843 GIC      156358 :     if (!partial_read_ok && rc > 0 && rc != nbytes)
    1844 UIC           0 :         ereport(ERROR,
    1845                 :                 (errcode_for_file_access(),
    1846                 :                  errmsg("could not read file \"%s\": read %d of %zu",
    1847 ECB             :                         filename, rc, nbytes)));
    1848                 : 
    1849 GIC      156358 :     return rc;
    1850                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a