mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-02-03 14:01:57 +02:00
Remove the limit on the number of extra directories.
Save extra directories separately to eliminate name collisions.
This commit is contained in:
parent
07c7c14df6
commit
863486be7e
45
src/backup.c
45
src/backup.c
@ -463,8 +463,7 @@ do_backup_instance(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char database_path[MAXPGPATH];
|
char database_path[MAXPGPATH];
|
||||||
char extra_path[MAXPGPATH];
|
char extra_path[MAXPGPATH]; /* Temp value. Used as template */
|
||||||
char *extradirs[] = { NULL, NULL, NULL, NULL };
|
|
||||||
char dst_backup_path[MAXPGPATH];
|
char dst_backup_path[MAXPGPATH];
|
||||||
char label[1024];
|
char label[1024];
|
||||||
XLogRecPtr prev_backup_start_lsn = InvalidXLogRecPtr;
|
XLogRecPtr prev_backup_start_lsn = InvalidXLogRecPtr;
|
||||||
@ -478,23 +477,22 @@ do_backup_instance(void)
|
|||||||
pgBackup *prev_backup = NULL;
|
pgBackup *prev_backup = NULL;
|
||||||
parray *prev_backup_filelist = NULL;
|
parray *prev_backup_filelist = NULL;
|
||||||
parray *backup_list = NULL;
|
parray *backup_list = NULL;
|
||||||
|
parray *extra_dirs = NULL;
|
||||||
|
|
||||||
pgFile *pg_control = NULL;
|
pgFile *pg_control = NULL;
|
||||||
|
|
||||||
elog(LOG, "Database backup start");
|
elog(LOG, "Database backup start");
|
||||||
i = 0;
|
extra_dirs = parray_new();
|
||||||
|
/* TODO: Add path validation */
|
||||||
if(extradir)
|
if(extradir)
|
||||||
{
|
{
|
||||||
p = strtok(extradir,":");
|
p = strtok(extradir,":");
|
||||||
while(p!=NULL)
|
while(p!=NULL)
|
||||||
{
|
{
|
||||||
extradirs[i] = (char *)palloc(strlen(p) + 1);
|
char * dir = (char *)palloc(strlen(p) + 1);
|
||||||
strcpy(extradirs[i],p);
|
strcpy(dir,p);
|
||||||
elog(WARNING,"%s",extradirs[i]);
|
parray_append(extra_dirs, dir);
|
||||||
i++;
|
|
||||||
p=strtok(NULL,":");
|
p=strtok(NULL,":");
|
||||||
if (i==3)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,11 +652,10 @@ do_backup_instance(void)
|
|||||||
parse_backup_filelist_filenames(backup_files_list, pgdata);
|
parse_backup_filelist_filenames(backup_files_list, pgdata);
|
||||||
|
|
||||||
/* Append to backup list all files dirictories from extra dirictory option */
|
/* Append to backup list all files dirictories from extra dirictory option */
|
||||||
for (i = 0; extradirs[i]; i++)
|
for (i = 0; i < parray_num(extra_dirs); i++)
|
||||||
{
|
/* Extra dirs numeration starts with 1. 0 value is not extra dir */
|
||||||
elog(WARNING,"%s",extradirs[i]);
|
dir_list_file(backup_files_list, (char *) parray_get(extra_dirs, i),
|
||||||
dir_list_file(backup_files_list, extradirs[i], true, true, true, true);
|
true, true, true, i+1);
|
||||||
}
|
|
||||||
|
|
||||||
if (current.backup_mode != BACKUP_MODE_FULL)
|
if (current.backup_mode != BACKUP_MODE_FULL)
|
||||||
{
|
{
|
||||||
@ -714,8 +711,12 @@ do_backup_instance(void)
|
|||||||
|
|
||||||
elog(VERBOSE, "Create directory \"%s\" NAME %s", dir_name, file->name);
|
elog(VERBOSE, "Create directory \"%s\" NAME %s", dir_name, file->name);
|
||||||
|
|
||||||
if (file->is_extra)
|
if (file->extra_dir_num)
|
||||||
join_path_components(dirpath, extra_path, dir_name);
|
{
|
||||||
|
char temp[MAXPGPATH];
|
||||||
|
sprintf(temp, "%s%d", extra_path, file->extra_dir_num);
|
||||||
|
join_path_components(dirpath, temp, dir_name);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
join_path_components(dirpath, database_path, dir_name);
|
join_path_components(dirpath, database_path, dir_name);
|
||||||
dir_create_dir(dirpath, DIR_PERMISSION);
|
dir_create_dir(dirpath, DIR_PERMISSION);
|
||||||
@ -783,6 +784,12 @@ do_backup_instance(void)
|
|||||||
parray_walk(prev_backup_filelist, pgFileFree);
|
parray_walk(prev_backup_filelist, pgFileFree);
|
||||||
parray_free(prev_backup_filelist);
|
parray_free(prev_backup_filelist);
|
||||||
}
|
}
|
||||||
|
/* clean extra directories list */
|
||||||
|
if (extra_dirs)
|
||||||
|
{
|
||||||
|
parray_walk(extra_dirs, pfree);
|
||||||
|
parray_free(extra_dirs);
|
||||||
|
}
|
||||||
|
|
||||||
/* In case of backup from replica >= 9.6 we must fix minRecPoint,
|
/* In case of backup from replica >= 9.6 we must fix minRecPoint,
|
||||||
* First we must find pg_control in backup_files_list.
|
* First we must find pg_control in backup_files_list.
|
||||||
@ -2237,10 +2244,12 @@ backup_files(void *arg)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (file->is_extra)
|
else if (file->extra_dir_num)
|
||||||
{
|
{
|
||||||
|
char temp[MAXPGPATH];
|
||||||
|
sprintf(temp, "%s%d", arguments->extra, file->extra_dir_num);
|
||||||
if (!copy_file(file->extradir,
|
if (!copy_file(file->extradir,
|
||||||
arguments->extra,
|
temp,
|
||||||
file))
|
file))
|
||||||
{
|
{
|
||||||
file->write_size = BYTES_INVALID;
|
file->write_size = BYTES_INVALID;
|
||||||
|
@ -406,7 +406,7 @@ pgBackupCreateDir(pgBackup *backup)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
char *subdirs[] = { DATABASE_DIR, EXTRA_DIR, NULL };
|
char *subdirs[] = { DATABASE_DIR, NULL };
|
||||||
|
|
||||||
pgBackupGetPath(backup, path, lengthof(path), NULL);
|
pgBackupGetPath(backup, path, lengthof(path), NULL);
|
||||||
|
|
||||||
|
38
src/dir.c
38
src/dir.c
@ -120,7 +120,8 @@ static int BlackListCompare(const void *str1, const void *str2);
|
|||||||
static bool dir_check_file(const char *root, pgFile *file);
|
static bool dir_check_file(const char *root, pgFile *file);
|
||||||
static void dir_list_file_internal(parray *files, const char *root,
|
static void dir_list_file_internal(parray *files, const char *root,
|
||||||
pgFile *parent, bool exclude,
|
pgFile *parent, bool exclude,
|
||||||
bool omit_symlink, parray *black_list, bool is_extra);
|
bool omit_symlink, parray *black_list,
|
||||||
|
int extra_dir_num);
|
||||||
|
|
||||||
static void list_data_directories(parray *files, const char *path, bool is_root,
|
static void list_data_directories(parray *files, const char *path, bool is_root,
|
||||||
bool exclude);
|
bool exclude);
|
||||||
@ -156,7 +157,7 @@ dir_create_dir(const char *dir, mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pgFile *
|
pgFile *
|
||||||
pgFileNew(const char *path, bool omit_symlink, bool is_extra)
|
pgFileNew(const char *path, bool omit_symlink, int extra_dir_num)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
pgFile *file;
|
pgFile *file;
|
||||||
@ -174,7 +175,8 @@ pgFileNew(const char *path, bool omit_symlink, bool is_extra)
|
|||||||
file = pgFileInit(path);
|
file = pgFileInit(path);
|
||||||
file->size = st.st_size;
|
file->size = st.st_size;
|
||||||
file->mode = st.st_mode;
|
file->mode = st.st_mode;
|
||||||
file->is_extra = is_extra;
|
file->is_extra = extra_dir_num > 0;
|
||||||
|
file->extra_dir_num = extra_dir_num;
|
||||||
file->extradir = NULL;
|
file->extradir = NULL;
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
@ -374,7 +376,7 @@ BlackListCompare(const void *str1, const void *str2)
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
|
dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
|
||||||
bool add_root, bool is_extra)
|
bool add_root, int extra_dir_num)
|
||||||
{
|
{
|
||||||
pgFile *file;
|
pgFile *file;
|
||||||
parray *black_list = NULL;
|
parray *black_list = NULL;
|
||||||
@ -411,7 +413,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
|
|||||||
parray_qsort(black_list, BlackListCompare);
|
parray_qsort(black_list, BlackListCompare);
|
||||||
}
|
}
|
||||||
|
|
||||||
file = pgFileNew(root, false, is_extra);
|
file = pgFileNew(root, false, extra_dir_num);
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -427,7 +429,8 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
|
|||||||
parray_append(files, file);
|
parray_append(files, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
dir_list_file_internal(files, root, file, exclude, omit_symlink, black_list, is_extra);
|
dir_list_file_internal(files, root, file, exclude, omit_symlink, black_list,
|
||||||
|
extra_dir_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -615,7 +618,7 @@ dir_check_file(const char *root, pgFile *file)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dir_list_file_internal(parray *files, const char *root, pgFile *parent,
|
dir_list_file_internal(parray *files, const char *root, pgFile *parent,
|
||||||
bool exclude, bool omit_symlink, parray *black_list, bool is_extra)
|
bool exclude, bool omit_symlink, parray *black_list, int extra_dir_num)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
@ -644,7 +647,7 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
|
|||||||
|
|
||||||
join_path_components(child, parent->path, dent->d_name);
|
join_path_components(child, parent->path, dent->d_name);
|
||||||
|
|
||||||
file = pgFileNew(child, omit_symlink, is_extra);
|
file = pgFileNew(child, omit_symlink, extra_dir_num);
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -677,7 +680,7 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If it is extra dir, remember it */
|
/* If it is extra dir, remember it */
|
||||||
if (is_extra)
|
if (extra_dir_num)
|
||||||
{
|
{
|
||||||
file->extradir = pgut_strdup(root);
|
file->extradir = pgut_strdup(root);
|
||||||
dirname(file->extradir);
|
dirname(file->extradir);
|
||||||
@ -705,7 +708,7 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
|
|||||||
*/
|
*/
|
||||||
if (S_ISDIR(file->mode))
|
if (S_ISDIR(file->mode))
|
||||||
dir_list_file_internal(files, root, file, exclude, omit_symlink,
|
dir_list_file_internal(files, root, file, exclude, omit_symlink,
|
||||||
black_list, is_extra);
|
black_list, extra_dir_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno && errno != ENOENT)
|
if (errno && errno != ENOENT)
|
||||||
@ -1201,11 +1204,12 @@ print_file_list(FILE *out, const parray *files, const char *root)
|
|||||||
fprintf(out, "{\"path\":\"%s\", \"size\":\"" INT64_FORMAT "\", "
|
fprintf(out, "{\"path\":\"%s\", \"size\":\"" INT64_FORMAT "\", "
|
||||||
"\"mode\":\"%u\", \"is_datafile\":\"%u\", "
|
"\"mode\":\"%u\", \"is_datafile\":\"%u\", "
|
||||||
"\"is_cfs\":\"%u\", \"crc\":\"%u\", "
|
"\"is_cfs\":\"%u\", \"crc\":\"%u\", "
|
||||||
"\"compress_alg\":\"%s\", \"is_extra\":\"%u\"",
|
"\"compress_alg\":\"%s\", \"is_extra\":\"%u\""
|
||||||
|
", \"extra_dir_num\":\"%u\"",
|
||||||
path, file->write_size, file->mode,
|
path, file->write_size, file->mode,
|
||||||
file->is_datafile ? 1 : 0, file->is_cfs ? 1 : 0, file->crc,
|
file->is_datafile ? 1 : 0, file->is_cfs ? 1 : 0, file->crc,
|
||||||
deparse_compress_alg(file->compress_alg),
|
deparse_compress_alg(file->compress_alg),
|
||||||
file->is_extra ? 1 : 0);
|
file->is_extra ? 1 : 0, file->extra_dir_num);
|
||||||
|
|
||||||
if (file->extradir)
|
if (file->extradir)
|
||||||
fprintf(out, ",\"extradir\":\"%s\"", file->extradir);
|
fprintf(out, ",\"extradir\":\"%s\"", file->extradir);
|
||||||
@ -1399,6 +1403,7 @@ dir_read_file_list(const char *root, const char *extra_path, const char *file_tx
|
|||||||
is_datafile,
|
is_datafile,
|
||||||
is_cfs,
|
is_cfs,
|
||||||
is_extra,
|
is_extra,
|
||||||
|
extra_dir_num,
|
||||||
crc,
|
crc,
|
||||||
segno,
|
segno,
|
||||||
n_blocks;
|
n_blocks;
|
||||||
@ -1412,10 +1417,15 @@ dir_read_file_list(const char *root, const char *extra_path, const char *file_tx
|
|||||||
get_control_value(buf, "crc", NULL, &crc, true);
|
get_control_value(buf, "crc", NULL, &crc, true);
|
||||||
get_control_value(buf, "compress_alg", compress_alg_string, NULL, false);
|
get_control_value(buf, "compress_alg", compress_alg_string, NULL, false);
|
||||||
get_control_value(buf, "is_extra", NULL, &is_extra, false);
|
get_control_value(buf, "is_extra", NULL, &is_extra, false);
|
||||||
|
get_control_value(buf, "extra_dir_num", NULL, &extra_dir_num, false);
|
||||||
|
|
||||||
if (root)
|
if (root)
|
||||||
if (is_extra)
|
if (extra_dir_num)
|
||||||
join_path_components(filepath, extra_path, path);
|
{
|
||||||
|
char temp[MAXPGPATH];
|
||||||
|
sprintf(temp, "%s%ld", extra_path, extra_dir_num);
|
||||||
|
join_path_components(filepath, temp, path);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
join_path_components(filepath, root, path);
|
join_path_components(filepath, root, path);
|
||||||
else
|
else
|
||||||
|
@ -117,6 +117,7 @@ typedef struct pgFile
|
|||||||
bool is_cfs; /* Flag to distinguish files compressed by CFS*/
|
bool is_cfs; /* Flag to distinguish files compressed by CFS*/
|
||||||
bool is_database;
|
bool is_database;
|
||||||
bool is_extra;
|
bool is_extra;
|
||||||
|
bool extra_dir_num; /* Number of extra directory. 0 if not extra */
|
||||||
char *extradir; /* File from extra directory */
|
char *extradir; /* File from extra directory */
|
||||||
bool exists_in_prev; /* Mark files, both data and regular, that exists in previous backup */
|
bool exists_in_prev; /* Mark files, both data and regular, that exists in previous backup */
|
||||||
CompressAlg compress_alg; /* compression algorithm applied to the file */
|
CompressAlg compress_alg; /* compression algorithm applied to the file */
|
||||||
@ -516,7 +517,7 @@ extern const char* deparse_compress_alg(int alg);
|
|||||||
|
|
||||||
/* in dir.c */
|
/* in dir.c */
|
||||||
extern void dir_list_file(parray *files, const char *root, bool exclude,
|
extern void dir_list_file(parray *files, const char *root, bool exclude,
|
||||||
bool omit_symlink, bool add_root, bool is_extra);
|
bool omit_symlink, bool add_root, int extra_dir_num);
|
||||||
extern void create_data_directories(const char *data_dir,
|
extern void create_data_directories(const char *data_dir,
|
||||||
const char *backup_dir,
|
const char *backup_dir,
|
||||||
bool extract_tablespaces);
|
bool extract_tablespaces);
|
||||||
@ -534,7 +535,7 @@ extern bool dir_is_empty(const char *path);
|
|||||||
extern bool fileExists(const char *path);
|
extern bool fileExists(const char *path);
|
||||||
extern size_t pgFileSize(const char *path);
|
extern size_t pgFileSize(const char *path);
|
||||||
|
|
||||||
extern pgFile *pgFileNew(const char *path, bool omit_symlink, bool is_extra);
|
extern pgFile *pgFileNew(const char *path, bool omit_symlink, int extra_dir_num);
|
||||||
extern pgFile *pgFileInit(const char *path);
|
extern pgFile *pgFileInit(const char *path);
|
||||||
extern void pgFileDelete(pgFile *file);
|
extern void pgFileDelete(pgFile *file);
|
||||||
extern void pgFileFree(void *file);
|
extern void pgFileFree(void *file);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user