From 33472260f4a961af84a614969c5078b27d7f0b5f Mon Sep 17 00:00:00 2001 From: Grigory Smolkin Date: Mon, 20 Apr 2020 18:56:19 +0300 Subject: [PATCH] [Issue #177] treat files with '.gz.partial', '.part' and '.gz.part' siffixes as WAL segments --- src/catalog.c | 27 +++++++++++++++++++++++++-- src/delete.c | 2 ++ src/pg_probackup.h | 28 ++++++++++++++++++++++------ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/catalog.c b/src/catalog.c index 118ba669..05fe4814 100644 --- a/src/catalog.c +++ b/src/catalog.c @@ -853,7 +853,8 @@ pgBackupCreateDir(pgBackup *backup) } /* - * Create list of timelines + * Create list of timelines. + * TODO: '.partial' and '.part' segno information should be added to tlinfo. */ parray * catalog_get_timelines(InstanceConfig *instance) @@ -933,7 +934,8 @@ catalog_get_timelines(InstanceConfig *instance) continue; } /* partial WAL segment */ - else if (IsPartialXLogFileName(file->name)) + else if (IsPartialXLogFileName(file->name) || + IsPartialCompressXLogFileName(file->name)) { elog(VERBOSE, "partial WAL file \"%s\"", file->name); @@ -952,6 +954,27 @@ catalog_get_timelines(InstanceConfig *instance) parray_append(tlinfo->xlog_filelist, wal_file); continue; } + /* temp WAL segment */ + else if (IsTempXLogFileName(file->name) || + IsTempCompressXLogFileName(file->name)) + { + elog(VERBOSE, "temp WAL file \"%s\"", file->name); + + if (!tlinfo || tlinfo->tli != tli) + { + tlinfo = timelineInfoNew(tli); + parray_append(timelineinfos, tlinfo); + } + + /* append file to xlog file list */ + wal_file = palloc(sizeof(xlogFile)); + wal_file->file = *file; + wal_file->segno = segno; + wal_file->type = TEMP_SEGMENT; + wal_file->keep = false; + parray_append(tlinfo->xlog_filelist, wal_file); + continue; + } /* we only expect compressed wal files with .gz suffix */ else if (strcmp(suffix, "gz") != 0) { diff --git a/src/delete.c b/src/delete.c index 7ecdaf1d..be7dba9d 100644 --- a/src/delete.c +++ b/src/delete.c @@ -942,6 +942,8 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo, { if (wal_file->type == SEGMENT) elog(VERBOSE, "Removed WAL segment \"%s\"", wal_file->file.path); + else if (wal_file->type == TEMP_SEGMENT) + elog(VERBOSE, "Removed temp WAL segment \"%s\"", wal_file->file.path); else if (wal_file->type == PARTIAL_SEGMENT) elog(VERBOSE, "Removed partial WAL segment \"%s\"", wal_file->file.path); else if (wal_file->type == BACKUP_HISTORY_FILE) diff --git a/src/pg_probackup.h b/src/pg_probackup.h index 01768acc..96c79982 100644 --- a/src/pg_probackup.h +++ b/src/pg_probackup.h @@ -46,7 +46,7 @@ extern const char *PROGRAM_URL; extern const char *PROGRAM_EMAIL; /* Directory/File names */ -#define DATABASE_DIR "database" +#define DATABASE_DIR "database" #define BACKUPS_DIR "backups" #if PG_VERSION_NUM >= 100000 #define PG_XLOG_DIR "pg_wal" @@ -90,6 +90,7 @@ extern const char *PROGRAM_EMAIL; /* retry attempts */ #define PAGE_READ_ATTEMPTS 100 +/* max size of note, that can be added to backup */ #define MAX_NOTE_SIZE 1024 /* Check if an XLogRecPtr value is pointed to 0 offset */ @@ -514,18 +515,18 @@ typedef struct lsnInterval typedef enum xlogFileType { SEGMENT, + TEMP_SEGMENT, PARTIAL_SEGMENT, BACKUP_HISTORY_FILE } xlogFileType; typedef struct xlogFile { - pgFile file; - XLogSegNo segno; + pgFile file; + XLogSegNo segno; xlogFileType type; - bool keep; /* Used to prevent removal of WAL segments - * required by ARCHIVE backups. - */ + bool keep; /* Used to prevent removal of WAL segments + * required by ARCHIVE backups. */ } xlogFile; @@ -607,6 +608,21 @@ typedef struct BackupPageHeader XLogFromFileName(fname, tli, logSegNo) #endif +#define IsPartialCompressXLogFileName(fname) \ + (strlen(fname) == XLOG_FNAME_LEN + strlen(".gz.partial") && \ + strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ + strcmp((fname) + XLOG_FNAME_LEN, ".gz.partial") == 0) + +#define IsTempXLogFileName(fname) \ + (strlen(fname) == XLOG_FNAME_LEN + strlen(".part") && \ + strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ + strcmp((fname) + XLOG_FNAME_LEN, ".part") == 0) + +#define IsTempCompressXLogFileName(fname) \ + (strlen(fname) == XLOG_FNAME_LEN + strlen(".gz.part") && \ + strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ + strcmp((fname) + XLOG_FNAME_LEN, ".gz.part") == 0) + #define IsSshProtocol() (instance_config.remote.host && strcmp(instance_config.remote.proto, "ssh") == 0) /* directory options */