mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2024-12-13 11:53:59 +02:00
Add extra directories remapping on restore
This commit is contained in:
parent
da20711987
commit
91c4572bbd
91
src/dir.c
91
src/dir.c
@ -124,10 +124,13 @@ static void dir_list_file_internal(parray *files, const char *root,
|
||||
|
||||
static void list_data_directories(parray *files, const char *path, bool is_root,
|
||||
bool exclude);
|
||||
static void free_extra_remap_list(void *cell);
|
||||
|
||||
/* Tablespace mapping */
|
||||
static TablespaceList tablespace_dirs = {NULL, NULL};
|
||||
static TablespaceCreatedList tablespace_created_dirs = {NULL, NULL};
|
||||
/* Extra directories mapping */
|
||||
static parray *extra_remap_list = NULL;
|
||||
|
||||
/*
|
||||
* Create directory, also create parent directories if necessary.
|
||||
@ -949,6 +952,57 @@ opt_tablespace_map(ConfigOption *opt, const char *arg)
|
||||
tablespace_dirs.tail = cell;
|
||||
}
|
||||
|
||||
void
|
||||
opt_extradir_map(ConfigOption *opt, const char *arg)
|
||||
{
|
||||
TablespaceListCell *cell = pgut_new(TablespaceListCell);
|
||||
char *dst;
|
||||
char *dst_ptr;
|
||||
const char *arg_ptr;
|
||||
|
||||
extra_remap_list = parray_new();
|
||||
dst_ptr = dst = cell->old_dir;
|
||||
for (arg_ptr = arg; *arg_ptr; arg_ptr++)
|
||||
{
|
||||
if (dst_ptr - dst >= MAXPGPATH)
|
||||
elog(ERROR, "directory name too long");
|
||||
|
||||
if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
|
||||
; /* skip backslash escaping = */
|
||||
else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
|
||||
{
|
||||
if (*cell->new_dir)
|
||||
elog(ERROR, "multiple \"=\" signs in extra directory mapping\n");
|
||||
else
|
||||
dst = dst_ptr = cell->new_dir;
|
||||
}
|
||||
else
|
||||
*dst_ptr++ = *arg_ptr;
|
||||
}
|
||||
|
||||
if (!*cell->old_dir || !*cell->new_dir)
|
||||
elog(ERROR, "invalid extra directory mapping format \"%s\", "
|
||||
"must be \"OLDDIR=NEWDIR\"", arg);
|
||||
|
||||
/*
|
||||
* This check isn't absolutely necessary. But all tablespaces are created
|
||||
* with absolute directories, so specifying a non-absolute path here would
|
||||
* just never match, possibly confusing users. It's also good to be
|
||||
* consistent with the new_dir check.
|
||||
*/
|
||||
if (!is_absolute_path(cell->old_dir))
|
||||
elog(ERROR, "old directory is not an absolute path "
|
||||
"in extra directory mapping: %s\n",
|
||||
cell->old_dir);
|
||||
|
||||
if (!is_absolute_path(cell->new_dir))
|
||||
elog(ERROR, "new directory is not an absolute path "
|
||||
"in extra directory mapping: %s\n",
|
||||
cell->new_dir);
|
||||
|
||||
parray_append(extra_remap_list, cell);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create backup directories from **backup_dir** to **data_dir**. Doesn't raise
|
||||
* an error if target directories exist.
|
||||
@ -1219,6 +1273,43 @@ check_tablespace_mapping(pgBackup *backup)
|
||||
parray_free(links);
|
||||
}
|
||||
|
||||
char *
|
||||
check_extra_dir_mapping(char *current_dir)
|
||||
{
|
||||
if (!extra_remap_list)
|
||||
return current_dir;
|
||||
|
||||
for (int i = 0; i < parray_num(extra_remap_list); i++)
|
||||
{
|
||||
TablespaceListCell *cell = parray_get(extra_remap_list, i);
|
||||
char *old_dir = cell->old_dir;
|
||||
|
||||
if (strcmp(old_dir, current_dir) == 0)
|
||||
return cell->new_dir;
|
||||
}
|
||||
return current_dir;
|
||||
}
|
||||
|
||||
static void
|
||||
free_extra_remap_list(void *cell)
|
||||
{
|
||||
TablespaceListCell *cell_ptr;
|
||||
if (cell == NULL)
|
||||
return;
|
||||
cell_ptr = (TablespaceListCell *)cell;
|
||||
pfree(cell_ptr);
|
||||
}
|
||||
|
||||
void
|
||||
clean_extra_dirs_remap_list(void)
|
||||
{
|
||||
if (extra_remap_list)
|
||||
{
|
||||
parray_walk(extra_remap_list, free_extra_remap_list);
|
||||
parray_free(extra_remap_list);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print backup content list.
|
||||
*/
|
||||
|
@ -137,7 +137,8 @@ static ConfigOption cmd_options[] =
|
||||
{ 's', 'S', "slot", &replication_slot, SOURCE_CMD_STRICT },
|
||||
{ 'b', 134, "delete-wal", &delete_wal, SOURCE_CMD_STRICT },
|
||||
{ 'b', 135, "delete-expired", &delete_expired, SOURCE_CMD_STRICT },
|
||||
{ 's', 155, "extra-directory", &extradir, SOURCE_CMD_STRICT },
|
||||
{ 's', 155, "extra-directory", &extradir, SOURCE_CMD_STRICT },
|
||||
{ 'f', 'E', "extra-mapping", opt_extradir_map, SOURCE_CMD_STRICT },
|
||||
/* TODO not completed feature. Make it unavailiable from user level
|
||||
{ 'b', 18, "remote", &is_remote_backup, SOURCE_CMD_STRICT, }, */
|
||||
/* restore options */
|
||||
|
@ -509,7 +509,10 @@ extern void create_data_directories(const char *data_dir,
|
||||
|
||||
extern void read_tablespace_map(parray *files, const char *backup_dir);
|
||||
extern void opt_tablespace_map(ConfigOption *opt, const char *arg);
|
||||
extern void opt_extradir_map(ConfigOption *opt, const char *arg);
|
||||
extern void check_tablespace_mapping(pgBackup *backup);
|
||||
extern char* check_extra_dir_mapping(char *current_dir);
|
||||
extern void clean_extra_dirs_remap_list(void);
|
||||
|
||||
extern void print_file_list(FILE *out, const parray *files, const char *root,
|
||||
const char *extra_prefix, parray *extra_list);
|
||||
|
@ -463,7 +463,9 @@ restore_backup(pgBackup *backup, const char *extra_dir_str)
|
||||
requested_extra_dirs = make_extra_directory_list(extra_dir_str);
|
||||
for (int i = 0; i < parray_num(requested_extra_dirs); i++)
|
||||
{
|
||||
dir_create_dir(parray_get(requested_extra_dirs, i), DIR_PERMISSION);
|
||||
char *extra_path = parray_get(requested_extra_dirs, i);
|
||||
extra_path = check_extra_dir_mapping(extra_path);
|
||||
dir_create_dir(extra_path, DIR_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
@ -504,6 +506,8 @@ restore_backup(pgBackup *backup, const char *extra_dir_str)
|
||||
if (backup_contains_extra(extra_path, requested_extra_dirs))
|
||||
{
|
||||
char container_dir[MAXPGPATH];
|
||||
|
||||
extra_path = check_extra_dir_mapping(extra_path);
|
||||
makeExtraDirPathByNum(container_dir, extra_prefix,
|
||||
file->extra_dir_num);
|
||||
dir_name = GetRelativePath(file->path, container_dir);
|
||||
@ -554,6 +558,8 @@ restore_backup(pgBackup *backup, const char *extra_dir_str)
|
||||
parray_walk(files, pgFileFree);
|
||||
parray_free(files);
|
||||
|
||||
clean_extra_dirs_remap_list();
|
||||
|
||||
if (logger_config.log_level_console <= LOG ||
|
||||
logger_config.log_level_file <= LOG)
|
||||
elog(LOG, "restore %s backup completed", base36enc(backup->start_time));
|
||||
@ -693,7 +699,10 @@ restore_files(void *arg)
|
||||
char *extra_path = parray_get(arguments->cur_extra_dirs,
|
||||
file->extra_dir_num - 1);
|
||||
if (backup_contains_extra(extra_path, arguments->req_extra_dirs))
|
||||
{
|
||||
extra_path = check_extra_dir_mapping(extra_path);
|
||||
copy_file(arguments->extra_prefix, extra_path, file);
|
||||
}
|
||||
}
|
||||
else
|
||||
copy_file(from_root, instance_config.pgdata, file);
|
||||
|
Loading…
Reference in New Issue
Block a user