Skip to content

Commit 1825426

Browse files
committed
[Issue #449] improve backward compatibility
1 parent 35a5f84 commit 1825426

File tree

4 files changed

+132
-43
lines changed

4 files changed

+132
-43
lines changed

src/archive.c

+54-10
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static int push_file(WALSegno *xlogfile, const char *archive_status_dir,
105105

106106
static parray *setup_push_filelist(const char *archive_status_dir,
107107
const char *first_file, int batch_size);
108+
static parray *setup_archive_subdirs(parray *batch_files, const char *archive_dir);
108109

109110
static xlogFileType
110111
get_xlogFileType(const char *filename)
@@ -165,6 +166,7 @@ do_archive_push(InstanceState *instanceState, InstanceConfig *instance, char *wa
165166

166167
/* files to push in multi-thread mode */
167168
parray *batch_files = NULL;
169+
parray *archive_subdirs = NULL;
168170
int n_threads;
169171

170172
if (wal_file_name == NULL)
@@ -211,7 +213,19 @@ do_archive_push(InstanceState *instanceState, InstanceConfig *instance, char *wa
211213
parray_num(batch_files), batch_size,
212214
is_compress ? "zlib" : "none");
213215

214-
/* TODO: create subdirectories here, not in internal functions */
216+
/* Extract subdirectories */
217+
archive_subdirs = setup_archive_subdirs(batch_files, instanceState->instance_wal_subdir_path);
218+
if (archive_subdirs)
219+
{
220+
for (i = 0; i < parray_num(archive_subdirs); i++)
221+
{
222+
char *subdir = (char *) parray_get(archive_subdirs, i);
223+
if (fio_mkdir(subdir, DIR_PERMISSION, FIO_BACKUP_HOST) != 0)
224+
elog(ERROR, "Cannot create subdirectory in WAL archive: '%s'", subdir);
225+
pg_free(subdir);
226+
}
227+
parray_free(archive_subdirs);
228+
}
215229

216230
num_threads = n_threads;
217231

@@ -460,10 +474,6 @@ push_file_internal_uncompressed(const char *wal_file_name, const char *pg_xlog_d
460474
/* calculate subdir in WAL archive */
461475
get_archive_subdir(archive_subdir, archive_dir, wal_file_name, type);
462476

463-
/* create subdirectory */
464-
if (fio_mkdir(archive_subdir, DIR_PERMISSION, FIO_BACKUP_HOST) != 0)
465-
elog(ERROR, "Cannot create subdirectory in WAL archive: '%s'", archive_subdir);
466-
467477
/* to path */
468478
join_path_components(to_fullpath, archive_subdir, wal_file_name);
469479
canonicalize_path(to_fullpath);
@@ -711,10 +721,6 @@ push_file_internal_gz(const char *wal_file_name, const char *pg_xlog_dir,
711721
/* calculate subdir in WAL archive */
712722
get_archive_subdir(archive_subdir, archive_dir, wal_file_name, type);
713723

714-
/* create subdirectory */
715-
if (fio_mkdir(archive_subdir, DIR_PERMISSION, FIO_BACKUP_HOST) != 0)
716-
elog(ERROR, "Cannot create subdirectory in WAL archive: '%s'", archive_subdir);
717-
718724
/* to path */
719725
join_path_components(to_fullpath, archive_subdir, wal_file_name);
720726
canonicalize_path(to_fullpath);
@@ -1863,4 +1869,42 @@ get_archive_subdir(char *archive_subdir, const char *archive_dir, const char *wa
18631869

18641870
/* for all other files just use root directory of WAL archive */
18651871
strcpy(archive_subdir, archive_dir);
1866-
}
1872+
}
1873+
1874+
/* Extract array of WAL archive subdirs using push filelist */
1875+
parray*
1876+
setup_archive_subdirs(parray *batch_files, const char *archive_dir)
1877+
{
1878+
int i;
1879+
parray *subdirs = NULL;
1880+
char *cur_subdir = NULL;
1881+
1882+
/*
1883+
* - Do we need to sort batch_files?
1884+
* - No, we rely on sorting of status files
1885+
*/
1886+
1887+
for (i = 0; i < parray_num(batch_files); i++)
1888+
{
1889+
WALSegno *xlogfile = (WALSegno *) parray_get(batch_files, i);
1890+
1891+
if (xlogfile->type == SEGMENT || xlogfile->type == PARTIAL_SEGMENT || xlogfile->type == BACKUP_HISTORY_FILE)
1892+
{
1893+
char subdir[MAXPGPATH];
1894+
1895+
if (!subdirs)
1896+
subdirs = parray_new();
1897+
1898+
get_archive_subdir(subdir, archive_dir, xlogfile->name, xlogfile->type);
1899+
1900+
/* do not append the same subdir twice */
1901+
if (cur_subdir && strcmp(cur_subdir, subdir) == 0)
1902+
continue;
1903+
1904+
cur_subdir = pgut_strdup(subdir);
1905+
parray_append(subdirs, cur_subdir);
1906+
}
1907+
}
1908+
1909+
return subdirs;
1910+
}

src/backup.c

+15-31
Original file line numberDiff line numberDiff line change
@@ -1238,16 +1238,15 @@ wait_wal_lsn(const char *wal_segment_dir, XLogRecPtr target_lsn, bool is_start_l
12381238
{
12391239
XLogSegNo targetSegNo;
12401240
char wal_segment_path[MAXPGPATH],
1241-
wal_segment_subdir[MAXPGPATH], // used only to check file existence, not actual parsing
1241+
// wal_segment_subdir[MAXPGPATH], // used only to check file existence, not actual parsing
12421242
wal_segment[MAXFNAMELEN];
1243-
bool file_exists = false;
12441243
uint32 try_count = 0,
12451244
timeout;
12461245
char *wal_delivery_str = in_stream_dir ? "streamed":"archived";
12471246

1248-
#ifdef HAVE_LIBZ
1249-
char gz_wal_segment_path[MAXPGPATH];
1250-
#endif
1247+
//#ifdef HAVE_LIBZ
1248+
// char gz_wal_segment_path[MAXPGPATH];
1249+
//#endif
12511250

12521251
/* Compute the name of the WAL file containing requested LSN */
12531252
GetXLogSegNo(target_lsn, targetSegNo, instance_config.xlog_seg_size);
@@ -1257,12 +1256,12 @@ wait_wal_lsn(const char *wal_segment_dir, XLogRecPtr target_lsn, bool is_start_l
12571256
instance_config.xlog_seg_size);
12581257

12591258
// obtain WAL archive subdir for ARCHIVE backup
1260-
if (in_stream_dir)
1261-
strcpy(wal_segment_subdir, wal_segment_dir);
1262-
else
1263-
get_archive_subdir(wal_segment_subdir, wal_segment_dir, wal_segment, SEGMENT);
1264-
1265-
join_path_components(wal_segment_path, wal_segment_subdir, wal_segment);
1259+
// if (in_stream_dir)
1260+
// strcpy(wal_segment_subdir, wal_segment_dir);
1261+
// else
1262+
// get_archive_subdir(wal_segment_subdir, wal_segment_dir, wal_segment, SEGMENT);
1263+
//
1264+
// join_path_components(wal_segment_path, wal_segment_subdir, wal_segment);
12661265
/*
12671266
* In pg_start_backup we wait for 'target_lsn' in 'pg_wal' directory if it is
12681267
* stream and non-page backup. Page backup needs archived WAL files, so we
@@ -1283,30 +1282,15 @@ wait_wal_lsn(const char *wal_segment_dir, XLogRecPtr target_lsn, bool is_start_l
12831282
elog(LOG, "Looking for LSN %X/%X in segment: %s",
12841283
(uint32) (target_lsn >> 32), (uint32) target_lsn, wal_segment);
12851284

1286-
#ifdef HAVE_LIBZ
1287-
snprintf(gz_wal_segment_path, sizeof(gz_wal_segment_path), "%s.gz",
1288-
wal_segment_path);
1289-
#endif
1285+
//#ifdef HAVE_LIBZ
1286+
// snprintf(gz_wal_segment_path, sizeof(gz_wal_segment_path), "%s.gz",
1287+
// wal_segment_path);
1288+
//#endif
12901289

12911290
/* Wait until target LSN is archived or streamed */
12921291
while (true)
12931292
{
1294-
if (!file_exists)
1295-
{
1296-
file_exists = fileExists(wal_segment_path, FIO_BACKUP_HOST);
1297-
1298-
/* Try to find compressed WAL file */
1299-
if (!file_exists)
1300-
{
1301-
#ifdef HAVE_LIBZ
1302-
file_exists = fileExists(gz_wal_segment_path, FIO_BACKUP_HOST);
1303-
if (file_exists)
1304-
elog(LOG, "Found compressed WAL segment: %s", wal_segment_path);
1305-
#endif
1306-
}
1307-
else
1308-
elog(LOG, "Found WAL segment: %s", wal_segment_path);
1309-
}
1293+
bool file_exists = IsWalFileExists(wal_segment, wal_segment_dir, in_stream_dir);
13101294

13111295
if (file_exists)
13121296
{

src/parsexlog.c

+61-1
Original file line numberDiff line numberDiff line change
@@ -2047,4 +2047,64 @@ static XLogReaderState* WalReaderAllocate(uint32 wal_seg_size, XLogReaderData *r
20472047
#else
20482048
return XLogReaderAllocate(&SimpleXLogPageRead, reader_data);
20492049
#endif
2050-
}
2050+
}
2051+
2052+
/*
2053+
* Is WAL file exists in archive directory
2054+
* first check subdirectory, then fallback to archive directory
2055+
*/
2056+
bool IsWalFileExists(const char *wal_segment_name, const char *wal_root_dir, bool in_stream_dir)
2057+
{
2058+
char wal_file_fullpath[MAXPGPATH];
2059+
char wal_file_fullpath_gz[MAXPGPATH];
2060+
char wal_segment_subdir[MAXPGPATH];
2061+
2062+
if (in_stream_dir)
2063+
{
2064+
join_path_components(wal_file_fullpath, wal_root_dir, wal_segment_name);
2065+
if (fileExists(wal_file_fullpath, FIO_BACKUP_HOST))
2066+
goto found_uncompressed_file;
2067+
2068+
goto not_found;
2069+
}
2070+
2071+
/* obtain subdir in WAL archive */
2072+
get_archive_subdir(wal_segment_subdir, wal_root_dir, wal_segment_name, SEGMENT);
2073+
2074+
/* first try uncompressed segment in WAL archive subdir ... */
2075+
join_path_components(wal_file_fullpath, wal_segment_subdir, wal_segment_name);
2076+
if (fileExists(wal_file_fullpath, FIO_BACKUP_HOST))
2077+
goto found_uncompressed_file;
2078+
2079+
#ifdef HAVE_LIBZ
2080+
/* ... fallback to compressed segment in WAL archive subdir ... */
2081+
snprintf(wal_file_fullpath_gz, MAXPGPATH, "%s.gz", wal_file_fullpath);
2082+
if (fileExists(wal_file_fullpath_gz, FIO_BACKUP_HOST))
2083+
goto found_compressed_file;
2084+
#endif
2085+
2086+
/* ... fallback to uncompressed segment in archive dir ... */
2087+
join_path_components(wal_file_fullpath, wal_root_dir, wal_segment_name);
2088+
if (fileExists(wal_file_fullpath, FIO_BACKUP_HOST))
2089+
goto found_uncompressed_file;
2090+
2091+
/* ... fallback to compressed segment in archive dir */
2092+
#ifdef HAVE_LIBZ
2093+
snprintf(wal_file_fullpath_gz, MAXPGPATH, "%s.gz", wal_file_fullpath);
2094+
if (fileExists(wal_file_fullpath_gz, FIO_BACKUP_HOST))
2095+
goto found_compressed_file;
2096+
#endif
2097+
2098+
goto not_found;
2099+
2100+
found_compressed_file:
2101+
elog(LOG, "Found WAL segment: %s", wal_file_fullpath);
2102+
return true;
2103+
2104+
found_uncompressed_file:
2105+
elog(LOG, "Found compressed WAL segment: %s", wal_file_fullpath_gz);
2106+
return true;
2107+
2108+
not_found:
2109+
return false;
2110+
}

src/pg_probackup.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ typedef enum xlogFileType
649649
{
650650
UNKNOWN,
651651
SEGMENT,
652-
TEMP_SEGMENT, // '.part' segment created by archive-push
652+
TEMP_SEGMENT, // '.part' segment created by archive-push
653653
PARTIAL_SEGMENT,
654654
HISTORY_FILE,
655655
BACKUP_HISTORY_FILE
@@ -1053,6 +1053,7 @@ extern int dir_create_dir(const char *path, mode_t mode, bool strict);
10531053
extern bool dir_is_empty(const char *path, fio_location location);
10541054

10551055
extern bool fileExists(const char *path, fio_location location);
1056+
extern bool IsWalFileExists(const char *wal_segment_name, const char *archive_dir, bool in_stream_dir);
10561057
extern size_t pgFileSize(const char *path);
10571058

10581059
extern pgFile *pgFileNew(const char *path, const char *rel_path,

0 commit comments

Comments
 (0)