26#include "catalog/pg_tablespace_d.h"
60#define SINK_BUFFER_LENGTH Max(32768, BLCKSZ)
81#define TAR_NUM_TERMINATION_BLOCKS 2
100 unsigned truncation_block_length);
103 off_t offset,
size_t length,
105 bool verify_checksum,
106 int *checksum_failures);
108 size_t *bytes_done,
void *
data,
size_t length);
113 const char *content,
int len,
223 {
"backup_manifest",
false},
225 {
"postmaster.pid",
false},
226 {
"postmaster.opts",
false},
251 state.tablespace_num = 0;
252 state.bytes_done = 0;
253 state.bytes_total = 0;
254 state.bytes_total_is_valid =
false;
321 state.bytes_total_is_valid =
true;
362 errmsg(
"could not stat file \"%s\": %m",
370 char *archive_name =
psprintf(
"%u.tar",
ti->oid);
484 (
errmsg(
"could not find any WAL files")));
558 errmsg(
"could not stat file \"%s\": %m",
660 "%lld total checksum verification failures",
666 errmsg(
"checksum verification failure during base backup")));
721 MemSet(opt, 0,
sizeof(*opt));
736 errmsg(
"duplicate option \"%s\"",
defel->defname)));
745 errmsg(
"duplicate option \"%s\"",
defel->defname)));
749 else if (
strcmp(
defel->defname,
"checkpoint") == 0)
756 errmsg(
"duplicate option \"%s\"",
defel->defname)));
764 errmsg(
"unrecognized checkpoint type: \"%s\"",
773 errmsg(
"duplicate option \"%s\"",
defel->defname)));
782 errmsg(
"duplicate option \"%s\"",
defel->defname)));
786 else if (
strcmp(
defel->defname,
"incremental") == 0)
791 errmsg(
"duplicate option \"%s\"",
defel->defname)));
796 errmsg(
"incremental backups cannot be taken unless WAL summarization is enabled")));
806 errmsg(
"duplicate option \"%s\"",
defel->defname)));
812 errmsg(
"%" PRId64 " is outside the valid range for parameter \"%s\" (%d .. %d)",
818 else if (
strcmp(
defel->defname,
"tablespace_map") == 0)
823 errmsg(
"duplicate option \"%s\"",
defel->defname)));
827 else if (
strcmp(
defel->defname,
"verify_checksums") == 0)
832 errmsg(
"duplicate option \"%s\"",
defel->defname)));
844 errmsg(
"duplicate option \"%s\"",
defel->defname)));
857 errmsg(
"unrecognized manifest option: \"%s\"",
861 else if (
strcmp(
defel->defname,
"manifest_checksums") == 0)
868 errmsg(
"duplicate option \"%s\"",
defel->defname)));
873 errmsg(
"unrecognized checksum algorithm: \"%s\"",
882 errmsg(
"duplicate option \"%s\"",
defel->defname)));
886 else if (
strcmp(
defel->defname,
"target_detail") == 0)
893 errmsg(
"duplicate option \"%s\"",
defel->defname)));
897 else if (
strcmp(
defel->defname,
"compression") == 0)
904 errmsg(
"duplicate option \"%s\"",
defel->defname)));
908 errmsg(
"unrecognized compression algorithm: \"%s\"",
912 else if (
strcmp(
defel->defname,
"compression_detail") == 0)
917 errmsg(
"duplicate option \"%s\"",
defel->defname)));
924 errmsg(
"unrecognized base backup option: \"%s\"",
929 opt->
label =
"base backup";
935 errmsg(
"manifest checksums require a backup manifest")));
944 errmsg(
"target detail cannot be used without target")));
953 errmsg(
"target \"%s\" does not accept a target detail",
964 errmsg(
"compression detail cannot be specified unless compression is enabled")));
977 errmsg(
"invalid compression specification: %s",
1000 errmsg(
"a backup is already in progress in this session")));
1027 errmsg(
"must UPLOAD_MANIFEST before performing an incremental BASE_BACKUP")));
1084 elog(
ERROR,
"could not initialize checksum of file \"%s\"",
1109 elog(
ERROR,
"could not update checksum of file \"%s\"",
1112 while (bytes_done <
len)
1119 bytes_done += nbytes;
1160 errmsg(
"could not stat file or directory \"%s\": %m",
1242 else if (
strcmp(path,
"./global") == 0)
1269 if (
strcmp(
de->d_name,
".DS_Store") == 0)
1284 errmsg(
"the standby was promoted during online backup"),
1285 errhint(
"This means that the backup being taken is corrupt "
1286 "and should not be used. "
1287 "Try taking another online backup.")));
1299 elog(
DEBUG1,
"file \"%s\" excluded from backup",
de->d_name);
1328 path, relfilenumber);
1333 "unlogged relation file \"%s\" excluded from backup",
1344 "temporary relation file \"%s\" excluded from backup",
1361 errmsg(
"could not stat file or directory \"%s\": %m",
1374 elog(
DEBUG1,
"contents of directory \"%s\" excluded from backup",
de->d_name);
1420 errmsg(
"could not read symbolic link \"%s\": %m",
1425 errmsg(
"symbolic link \"%s\" target is too long",
1448 foreach(
lc, tablespaces)
1480 unsigned truncation_block_length = 0;
1509 relative_block_numbers,
1510 &truncation_block_length);
1516 "%s/INCREMENTAL.%s",
1531 truncation_block_length);
1550 if (relative_block_numbers !=
NULL)
1551 pfree(relative_block_numbers);
1583 int checksum_failures = 0;
1586 bool verify_checksum =
false;
1591 elog(
ERROR,
"could not initialize checksum of file \"%s\"",
1619 verify_checksum =
true;
1633 &magic,
sizeof(magic));
1637 &truncation_block_length,
sizeof(truncation_block_length));
1667 elog(
ERROR,
"could not update checksum of base backup");
1671 bytes_done +=
sizeof(magic);
1673 bytes_done +=
sizeof(truncation_block_length);
1697 if (bytes_done >=
statbuf->st_size)
1708 &checksum_failures);
1730 &checksum_failures);
1751 if (verify_checksum && (cnt %
BLCKSZ != 0))
1754 (
errmsg(
"could not verify checksum in file \"%s\", block "
1755 "%u: read buffer size %d and page size %d "
1758 verify_checksum =
false;
1778 (bytes_done %
BLCKSZ != 0)));
1786 elog(
ERROR,
"could not update checksum of base backup");
1799 elog(
ERROR,
"could not update checksum of base backup");
1801 bytes_done += nbytes;
1813 if (checksum_failures > 1)
1816 (
errmsg_plural(
"file \"%s\" has a total of %d checksum verification failure",
1817 "file \"%s\" has a total of %d checksum verification failures",
1853 bool verify_checksum,
int *checksum_failures)
1861 Min(
sink->bbs_buffer_length, length),
1865 if (!verify_checksum || (cnt %
BLCKSZ) != 0)
1918 (*checksum_failures)++;
1919 if (*checksum_failures <= 5)
1921 (
errmsg(
"checksum verification failed in "
1922 "file \"%s\", block %u: calculated "
1923 "%X but expected %X",
1926 if (*checksum_failures == 5)
1928 (
errmsg(
"further checksum verification "
1929 "failures in file \"%s\" will not "
1955 size_t *bytes_done,
void *
data,
size_t length)
1969 *bytes_done += length;
1980 sink->bbs_buffer_length) < 0)
1981 elog(
ERROR,
"could not update checksum");
2038 "BLCKSZ too small for tar block");
2053 errmsg(
"file name too long for tar format: \"%s\"",
2059 errmsg(
"symbolic link target too long for tar format: "
2060 "file name \"%s\", target \"%s\"",
2064 elog(
ERROR,
"unrecognized tar error: %d", rc);
2133 errmsg(
"could not read file \"%s\": read %zd of %zu",
void InitializeBackupManifest(backup_manifest_info *manifest, backup_manifest_option want_manifest, pg_checksum_type manifest_checksum_type)
void AddFileToBackupManifest(backup_manifest_info *manifest, Oid spcoid, const char *pathname, size_t size, pg_time_t mtime, pg_checksum_context *checksum_ctx)
void AddWALInfoToBackupManifest(backup_manifest_info *manifest, XLogRecPtr startptr, TimeLineID starttli, XLogRecPtr endptr, TimeLineID endtli)
void SendBackupManifest(backup_manifest_info *manifest, bbsink *sink)
void FreeBackupManifest(backup_manifest_info *manifest)
@ MANIFEST_OPTION_FORCE_ENCODE
enum manifest_option backup_manifest_option
static bool sendFile(bbsink *sink, const char *readfilename, const char *tarfilename, struct stat *statbuf, bool missing_ok, Oid dboid, Oid spcoid, RelFileNumber relfilenumber, unsigned segno, backup_manifest_info *manifest, unsigned num_incremental_blocks, BlockNumber *incremental_blocks, unsigned truncation_block_length)
static const struct exclude_list_item excludeFiles[]
static int compareWalFileNames(const ListCell *a, const ListCell *b)
static void sendFileWithContent(bbsink *sink, const char *filename, const char *content, int len, backup_manifest_info *manifest)
static off_t read_file_data_into_buffer(bbsink *sink, const char *readfilename, int fd, off_t offset, size_t length, BlockNumber blkno, bool verify_checksum, int *checksum_failures)
static void push_to_sink(bbsink *sink, pg_checksum_context *checksum_ctx, size_t *bytes_done, void *data, size_t length)
static int64 sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly, List *tablespaces, bool sendtblspclinks, backup_manifest_info *manifest, Oid spcoid, IncrementalBackupInfo *ib)
#define SINK_BUFFER_LENGTH
static void parse_basebackup_options(List *options, basebackup_options *opt)
static const char *const excludeDirContents[]
static void convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
void SendBaseBackup(BaseBackupCmd *cmd, IncrementalBackupInfo *ib)
static bool backup_started_in_recovery
static int64 _tarWriteHeader(bbsink *sink, const char *filename, const char *linktarget, struct stat *statbuf, bool sizeonly)
static void perform_base_backup(basebackup_options *opt, bbsink *sink, IncrementalBackupInfo *ib)
static int64 sendTablespace(bbsink *sink, char *path, Oid spcoid, bool sizeonly, struct backup_manifest_info *manifest, IncrementalBackupInfo *ib)
static bool noverify_checksums
static void _tarWritePadding(bbsink *sink, int len)
static bool verify_page_checksum(Page page, XLogRecPtr start_lsn, BlockNumber blkno, uint16 *expected_checksum)
static ssize_t basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset, const char *filename, bool partial_read_ok)
#define TAR_NUM_TERMINATION_BLOCKS
static long long int total_checksum_failures
bbsink * bbsink_copystream_new(bool send_to_client)
bbsink * bbsink_gzip_new(bbsink *next, pg_compress_specification *compress)
size_t GetIncrementalFileSize(unsigned num_blocks_required)
FileBackupMethod GetFileBackupMethod(IncrementalBackupInfo *ib, const char *path, Oid dboid, Oid spcoid, RelFileNumber relfilenumber, ForkNumber forknum, unsigned segno, size_t size, unsigned *num_blocks_required, BlockNumber *relative_block_numbers, unsigned *truncation_block_length)
void PrepareForIncrementalBackup(IncrementalBackupInfo *ib, BackupState *backup_state)
#define INCREMENTAL_MAGIC
@ BACK_UP_FILE_INCREMENTALLY
bbsink * bbsink_lz4_new(bbsink *next, pg_compress_specification *compress)
void basebackup_progress_wait_checkpoint(void)
bbsink * bbsink_progress_new(bbsink *next, bool estimate_backup_size, bool incremental)
void basebackup_progress_wait_wal_archive(bbsink_state *state)
void basebackup_progress_done(void)
void basebackup_progress_transfer_wal(void)
void basebackup_progress_estimate_backup_size(void)
static void bbsink_begin_backup(bbsink *sink, bbsink_state *state, int buffer_length)
static void bbsink_begin_archive(bbsink *sink, const char *archive_name)
static void bbsink_end_archive(bbsink *sink)
static void bbsink_end_backup(bbsink *sink, XLogRecPtr endptr, TimeLineID endtli)
static void bbsink_cleanup(bbsink *sink)
static void bbsink_archive_contents(bbsink *sink, size_t len)
BaseBackupTargetHandle * BaseBackupGetTargetHandle(char *target, char *target_detail)
bbsink * BaseBackupGetSink(BaseBackupTargetHandle *handle, bbsink *next_sink)
bbsink * bbsink_throttle_new(bbsink *next, uint32 maxrate)
bbsink * bbsink_zstd_new(bbsink *next, pg_compress_specification *compress)
bool parse_bool(const char *value, bool *result)
PageHeaderData * PageHeader
static bool PageIsNew(const PageData *page)
static XLogRecPtr PageGetLSN(const PageData *page)
#define Assert(condition)
#define MemSet(start, val, len)
#define StaticAssertDecl(condition, errmessage)
#define OidIsValid(objectId)
uint16 pg_checksum_page(char *page, BlockNumber blkno)
bool pg_checksum_parse_type(char *name, pg_checksum_type *type)
int pg_checksum_update(pg_checksum_context *context, const uint8 *input, size_t len)
int pg_checksum_init(pg_checksum_context *context, pg_checksum_type type)
char * validate_compress_specification(pg_compress_specification *spec)
bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm)
void parse_compress_specification(pg_compress_algorithm algorithm, char *specification, pg_compress_specification *result)
char * defGetString(DefElem *def)
bool defGetBoolean(DefElem *def)
int64 defGetInt64(DefElem *def)
int errcode_for_file_access(void)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
int errhint(const char *fmt,...) pg_attribute_printf(1
int int int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define ereport(elevel,...)
int CloseTransientFile(int fd)
DIR * AllocateDir(const char *dirname)
struct dirent * ReadDir(DIR *dir, const char *dirname)
bool looks_like_temp_rel_name(const char *name)
int OpenTransientFile(const char *fileName, int fileFlags)
#define palloc_array(type, count)
#define palloc0_object(type)
#define PG_TEMP_FILE_PREFIX
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
List * lappend(List *list, void *datum)
void list_sort(List *list, list_sort_comparator cmp)
char * pstrdup(const char *in)
void pfree(void *pointer)
#define CHECK_FOR_INTERRUPTS()
#define ERRCODE_DATA_CORRUPTED
#define PG_AUTOCONF_FILENAME
static ListCell * lnext(const List *l, const ListCell *c)
static char buf[DEFAULT_XLOG_SEG_SIZE]
void pgstat_prepare_report_checksum_failure(Oid dboid)
void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount)
static size_t tarPaddingBytesRequired(size_t len)
enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime)
char * last_dir_separator(const char *filename)
int pg_strcasecmp(const char *s1, const char *s2)
static Datum BoolGetDatum(bool X)
static int fd(const char *x, int i)
bool update_process_title
static void set_ps_display(const char *activity)
char * psprintf(const char *fmt,...)
bool parse_filename_for_nontemp_relation(const char *name, RelFileNumber *relnumber, ForkNumber *fork, unsigned *segno)
#define RELCACHE_INIT_FILENAME
#define InvalidRelFileNumber
#define TABLESPACE_VERSION_DIRECTORY
#define RelFileNumberIsValid(relnumber)
void ReleaseAuxProcessResources(bool isCommit)
ResourceOwner CurrentResourceOwner
ResourceOwner AuxProcessResourceOwner
void initStringInfo(StringInfo str)
pg_compress_specification compression_specification
pg_checksum_type manifest_checksum_type
pg_compress_algorithm compression
backup_manifest_option manifest
BaseBackupTargetHandle * target_handle
pg_compress_algorithm algorithm
#define LOG_METAINFO_DATAFILE_TMP
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)
void WalSndSetState(WalSndState state)
#define readlink(path, buf, size)
bool RecoveryInProgress(void)
void do_pg_abort_backup(int code, Datum arg)
SessionBackupState get_backup_status(void)
void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli)
bool DataChecksumsEnabled(void)
void do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces, BackupState *state, StringInfo tblspcmapfile)
void do_pg_backup_stop(BackupState *state, bool waitforarchive)
#define BACKUP_LABEL_FILE
#define XLOG_CONTROL_FILE
static bool IsXLogFileName(const char *fname)
static void XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
static bool IsTLHistoryFileName(const char *fname)
static void StatusFilePath(char *path, const char *xlog, const char *suffix)
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
char * build_backup_content(BackupState *state, bool ishistoryfile)
static BackupState * backup_state
static StringInfo tablespace_map