Skip to content

Commit 269ca37

Browse files
committed
[Issue #66] support external directories, handle timeline mismatch
1 parent 8497cf6 commit 269ca37

File tree

6 files changed

+172
-65
lines changed

6 files changed

+172
-65
lines changed

src/catalog.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ catalog_get_timelines(InstanceConfig *instance)
10481048
TimeLineHistoryEntry *tln;
10491049

10501050
sscanf(file->name, "%08X.history", &tli);
1051-
timelines = read_timeline_history(arclog_path, tli);
1051+
timelines = read_timeline_history(arclog_path, tli, true);
10521052

10531053
if (!tlinfo || tlinfo->tli != tli)
10541054
{

src/data.c

+11-6
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,8 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out,
933933
from_fullpath, to_fullpath, dest_file->n_blocks,
934934
use_bitmap ? &(dest_file)->pagemap : NULL,
935935
checksum_map, backup->checksum_version,
936-
backup->start_lsn <= horizonLsn ? lsn_map : NULL);
936+
/* shiftmap can be used only if backup state precedes the shift */
937+
backup->stop_lsn <= horizonLsn ? lsn_map : NULL);
937938

938939
if (fclose(in) != 0)
939940
elog(ERROR, "Cannot close file \"%s\": %s", from_fullpath,
@@ -1026,7 +1027,7 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10261027
* special value PageIsTruncated is encountered.
10271028
* It was inefficient.
10281029
*
1029-
* Nowadays every backup type has n_blocks, so instead
1030+
* Nowadays every backup type has n_blocks, so instead of
10301031
* writing and then truncating redundant data, writing
10311032
* is not happening in the first place.
10321033
* TODO: remove in 3.0.0
@@ -1097,7 +1098,9 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10971098
}
10981099

10991100
/* Incremental restore
1100-
* TODO: move to another function
1101+
* TODO: move to separate function,
1102+
* TODO: move BackupPageHeader headers to some separate storage,
1103+
* so they can be accessed without reading through whole file.
11011104
*/
11021105
if (checksum_map && checksum_map[blknum].checksum != 0)
11031106
{
@@ -1110,7 +1113,7 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
11101113
char uncompressed_buf[BLCKSZ];
11111114
fio_decompress(uncompressed_buf, page.data, compressed_size, file->compress_alg);
11121115

1113-
/* If checksumms are enabled, then we can trust checksumm in header */
1116+
/* If checksums are enabled, then we can trust checksum in header */
11141117
if (checksum_version)
11151118
page_crc = ((PageHeader) uncompressed_buf)->pd_checksum;
11161119
else
@@ -1143,6 +1146,8 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
11431146
datapagemap_add(map, blknum);
11441147
continue;
11451148
}
1149+
1150+
// elog(INFO, "Replace blknum %u in file %s", blknum, to_fullpath);
11461151
}
11471152

11481153
/*
@@ -1313,7 +1318,7 @@ restore_non_data_file(parray *parent_chain, pgBackup *dest_backup,
13131318

13141319
if (file_crc == tmp_file->crc)
13151320
{
1316-
elog(VERBOSE, "Remote nondata file \"%s\" is unchanged, skip restore",
1321+
elog(VERBOSE, "Remote nonedata file \"%s\" is unchanged, skip restore",
13171322
to_fullpath);
13181323
return 0;
13191324
}
@@ -1820,7 +1825,7 @@ check_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
18201825

18211826
/* read local data file and construct map with block checksums */
18221827
PageState *get_checksum_map(const char *fullpath, uint32 checksum_version,
1823-
int n_blocks, XLogRecPtr dest_stop_lsn, BlockNumber segmentno)
1828+
int n_blocks, XLogRecPtr dest_stop_lsn, BlockNumber segmentno)
18241829
{
18251830
PageState *checksum_map = NULL;
18261831
FILE *in = NULL;

src/dir.c

+23-24
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ typedef struct TablespaceCreatedList
123123

124124
static int pgCompareString(const void *str1, const void *str2);
125125

126-
static char dir_check_file(pgFile *file);
126+
static char dir_check_file(pgFile *file, bool backup_logs);
127127

128128
static void dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
129-
bool exclude, bool follow_symlink, bool skip_hidden,
130-
int external_dir_num, fio_location location);
129+
bool exclude, bool follow_symlink, bool backup_logs,
130+
bool skip_hidden, int external_dir_num, fio_location location);
131131
static void opt_path_map(ConfigOption *opt, const char *arg,
132132
TablespaceList *list, const char *type);
133133

@@ -561,17 +561,6 @@ dir_list_file(parray *files, const char *root, bool exclude, bool follow_symlink
561561
return;
562562
}
563563

564-
/* setup exclusion list for file search */
565-
if (!backup_logs)
566-
{
567-
int i;
568-
569-
for (i = 0; pgdata_exclude_dir[i]; i++); /* find first empty slot */
570-
571-
/* Set 'pg_log' in first empty slot */
572-
pgdata_exclude_dir[i] = PG_LOG_DIR;
573-
}
574-
575564
if (!S_ISDIR(file->mode))
576565
{
577566
if (external_dir_num > 0)
@@ -585,7 +574,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool follow_symlink
585574
parray_append(files, file);
586575

587576
dir_list_file_internal(files, file, root, exclude, follow_symlink,
588-
skip_hidden, external_dir_num, location);
577+
backup_logs, skip_hidden, external_dir_num, location);
589578

590579
if (!add_root)
591580
pgFileFree(file);
@@ -609,7 +598,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool follow_symlink
609598
* - datafiles
610599
*/
611600
static char
612-
dir_check_file(pgFile *file)
601+
dir_check_file(pgFile *file, bool backup_logs)
613602
{
614603
int i;
615604
int sscanf_res;
@@ -623,7 +612,7 @@ dir_check_file(pgFile *file)
623612
if (!exclusive_backup)
624613
{
625614
for (i = 0; pgdata_exclude_files_non_exclusive[i]; i++)
626-
if (strcmp(file->name,
615+
if (strcmp(file->rel_path,
627616
pgdata_exclude_files_non_exclusive[i]) == 0)
628617
{
629618
/* Skip */
@@ -633,7 +622,7 @@ dir_check_file(pgFile *file)
633622
}
634623

635624
for (i = 0; pgdata_exclude_files[i]; i++)
636-
if (strcmp(file->name, pgdata_exclude_files[i]) == 0)
625+
if (strcmp(file->rel_path, pgdata_exclude_files[i]) == 0)
637626
{
638627
/* Skip */
639628
elog(VERBOSE, "Excluding file: %s", file->name);
@@ -660,6 +649,16 @@ dir_check_file(pgFile *file)
660649
return CHECK_EXCLUDE_FALSE;
661650
}
662651
}
652+
653+
if (!backup_logs)
654+
{
655+
if (strcmp(file->rel_path, PG_LOG_DIR) == 0)
656+
{
657+
/* Skip */
658+
elog(VERBOSE, "Excluding directory content: %s", file->rel_path);
659+
return CHECK_EXCLUDE_FALSE;
660+
}
661+
}
663662
}
664663

665664
/*
@@ -807,8 +806,8 @@ dir_check_file(pgFile *file)
807806
*/
808807
static void
809808
dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
810-
bool exclude, bool follow_symlink, bool skip_hidden,
811-
int external_dir_num, fio_location location)
809+
bool exclude, bool follow_symlink, bool backup_logs,
810+
bool skip_hidden, int external_dir_num, fio_location location)
812811
{
813812
DIR *dir;
814813
struct dirent *dent;
@@ -874,7 +873,7 @@ dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
874873

875874
if (exclude)
876875
{
877-
check_res = dir_check_file(file);
876+
check_res = dir_check_file(file, backup_logs);
878877
if (check_res == CHECK_FALSE)
879878
{
880879
/* Skip */
@@ -897,7 +896,7 @@ dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
897896
*/
898897
if (S_ISDIR(file->mode))
899898
dir_list_file_internal(files, file, child, exclude, follow_symlink,
900-
skip_hidden, external_dir_num, location);
899+
backup_logs, skip_hidden, external_dir_num, location);
901900
}
902901

903902
if (errno && errno != ENOENT)
@@ -1288,7 +1287,7 @@ check_tablespace_mapping(pgBackup *backup, bool incremental, bool *tblspaces_are
12881287
}
12891288

12901289
void
1291-
check_external_dir_mapping(pgBackup *backup)
1290+
check_external_dir_mapping(pgBackup *backup, bool incremental)
12921291
{
12931292
TablespaceListCell *cell;
12941293
parray *external_dirs_to_restore;
@@ -1341,7 +1340,7 @@ check_external_dir_mapping(pgBackup *backup)
13411340
char *external_dir = (char *) parray_get(external_dirs_to_restore,
13421341
i);
13431342

1344-
if (!dir_is_empty(external_dir, FIO_DB_HOST))
1343+
if (!incremental && !dir_is_empty(external_dir, FIO_DB_HOST))
13451344
elog(ERROR, "External directory is not empty: \"%s\"",
13461345
external_dir);
13471346
}

src/pg_probackup.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,8 @@ extern parray *get_dbOid_exclude_list(pgBackup *backup, parray *datname_list,
740740
PartialRestoreType partial_restore_type);
741741

742742
extern parray *get_backup_filelist(pgBackup *backup, bool strict);
743-
extern parray *read_timeline_history(const char *arclog_path, TimeLineID targetTLI);
743+
extern parray *read_timeline_history(const char *arclog_path, TimeLineID targetTLI, bool strict);
744+
extern bool tliIsPartOfHistory(const parray *timelines, TimeLineID tli);
744745

745746
/* in merge.c */
746747
extern void do_merge(time_t backup_id);
@@ -888,7 +889,7 @@ extern void read_tablespace_map(parray *files, const char *backup_dir);
888889
extern void opt_tablespace_map(ConfigOption *opt, const char *arg);
889890
extern void opt_externaldir_map(ConfigOption *opt, const char *arg);
890891
extern void check_tablespace_mapping(pgBackup *backup, bool incremental, bool *tblspaces_are_empty);
891-
extern void check_external_dir_mapping(pgBackup *backup);
892+
extern void check_external_dir_mapping(pgBackup *backup, bool incremental);
892893
extern char *get_external_remap(char *current_dir);
893894

894895
extern void print_database_map(FILE *out, parray *database_list);

0 commit comments

Comments
 (0)