1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-02-08 14:28:36 +02:00

Fix for 9c471aa0e042b1a56ae4a07b98d321c33da74db8.

pgdata_exclude[] doesn't exclude files. Add pgdata_exclude_files[].
This commit is contained in:
Artur Zakirov 2017-02-13 14:11:00 +03:00
parent 9c471aa0e0
commit de2a0d1cde
7 changed files with 97 additions and 49 deletions

View File

@ -205,7 +205,7 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
* mkdirs.sh, then sort them in order of path. Omit $PGDATA.
*/
backup_files_list = parray_new();
dir_list_file(backup_files_list, pgdata, NULL, false, false);
dir_list_file(backup_files_list, pgdata, false, false, false);
if (!check)
{
@ -396,7 +396,7 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
/* Scan backup pg_xlog dir */
list_file = parray_new();
join_path_components(pg_xlog_path, path, "pg_xlog");
dir_list_file(list_file, pg_xlog_path, NULL, true, false);
dir_list_file(list_file, pg_xlog_path, false, true, false);
/* Remove file path root prefix and calc meta */
for (i = 0; i < parray_num(list_file); i++)
@ -1233,7 +1233,7 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
list_file = parray_new();
/* list files with the logical path. omit $PGDATA */
dir_list_file(list_file, root, pgdata_exclude, true, add_root);
dir_list_file(list_file, root, true, true, add_root);
/* mark files that are possible datafile as 'datafile' */
for (i = 0; i < (int) parray_num(list_file); i++)

View File

@ -260,7 +260,7 @@ pgBackupDeleteFiles(pgBackup *backup)
/* list files to be deleted */
files = parray_new();
pgBackupGetPath(backup, path, lengthof(path), NULL);
dir_list_file(files, path, NULL, true, true);
dir_list_file(files, path, false, true, true);
/* delete leaf node first */
parray_qsort(files, pgFileComparePathDesc);

106
dir.c
View File

@ -20,16 +20,21 @@
#include "datapagemap.h"
/* directory exclusion list for backup mode listing */
const char *pgdata_exclude[] =
const char *pgdata_exclude_dir[] =
{
"pg_xlog",
"pg_stat_tmp",
"pgsql_tmp",
NULL, /* arclog_path will be set later */
NULL, /* pg_log will be set later */
NULL
};
static char *pgdata_exclude_files[] =
{
"recovery.conf",
"postmaster.pid",
"postmaster.opts",
NULL, /* arclog_path will be set later */
NULL, /* pg_log will be set later */
NULL
};
@ -249,7 +254,8 @@ BlackListCompare(const void *str1, const void *str2)
* directory llnked to will be listed.
*/
void
dir_list_file(parray *files, const char *root, const char *exclude[], bool omit_symlink, bool add_root)
dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
bool add_root)
{
char path[MAXPGPATH];
char buf[MAXPGPATH * 2];
@ -288,8 +294,8 @@ dir_list_file(parray *files, const char *root, const char *exclude[], bool omit_
}
void
dir_list_file_internal(parray *files, const char *root, const char *exclude[],
bool omit_symlink, bool add_root, parray *black_list)
dir_list_file_internal(parray *files, const char *root, bool exclude,
bool omit_symlink, bool add_root, parray *black_list)
{
pgFile *file;
@ -305,7 +311,33 @@ dir_list_file_internal(parray *files, const char *root, const char *exclude[],
}
if (add_root)
{
/* Skip files */
if (!S_ISDIR(file->mode) && exclude)
{
char *file_name;
int i;
/* Extract file name */
file_name = strrchr(file->path, '/');
if (file_name == NULL)
file_name = file->path;
else
file_name++;
/*
* If the item in the exclude list starts with '/', compare to the
* absolute path of the directory. Otherwise compare to the directory
* name portion.
*/
for (i = 0; pgdata_exclude_files[i]; i++)
if (strcmp(file_name, pgdata_exclude_files[i]) == 0)
/* Skip */
return;
}
parray_append(files, file);
}
/* chase symbolic link chain and find regular file or directory */
while (S_ISLNK(file->mode))
@ -351,45 +383,49 @@ dir_list_file_internal(parray *files, const char *root, const char *exclude[],
*/
while (S_ISDIR(file->mode))
{
int i;
bool skip = false;
DIR *dir;
struct dirent *dent;
char *dirname;
/* skip entry which matches exclude list */
dirname = strrchr(file->path, '/');
if (dirname == NULL)
dirname = file->path;
else
dirname++;
/*
* If the item in the exclude list starts with '/', compare to the
* absolute path of the directory. Otherwise compare to the directory
* name portion.
*/
for (i = 0; exclude && exclude[i]; i++)
if (exclude)
{
if (exclude[i][0] == '/')
{
if (strcmp(file->path, exclude[i]) == 0)
{
skip = true;
break;
}
}
int i;
char *dirname;
/* skip entry which matches exclude list */
dirname = strrchr(file->path, '/');
if (dirname == NULL)
dirname = file->path;
else
dirname++;
/*
* If the item in the exclude list starts with '/', compare to the
* absolute path of the directory. Otherwise compare to the directory
* name portion.
*/
for (i = 0; exclude && pgdata_exclude_dir[i]; i++)
{
if (strcmp(dirname, exclude[i]) == 0)
if (pgdata_exclude_dir[i][0] == '/')
{
skip = true;
break;
if (strcmp(file->path, pgdata_exclude_dir[i]) == 0)
{
skip = true;
break;
}
}
else
{
if (strcmp(dirname, pgdata_exclude_dir[i]) == 0)
{
skip = true;
break;
}
}
}
if (skip)
break;
}
if (skip)
break;
/* open directory and list contents */
dir = opendir(file->path);
@ -636,7 +672,7 @@ dir_copy_files(const char *from_root, const char *to_root)
parray *files = parray_new();
/* don't copy root directory */
dir_list_file(files, from_root, NULL, true, false);
dir_list_file(files, from_root, false, true, false);
for (i = 0; i < parray_num(files); i++)
{

View File

@ -174,12 +174,12 @@ main(int argc, char *argv[])
join_path_components(arclog_path, backup_path, "wal");
/* setup exclusion list for file search */
for (i = 0; pgdata_exclude[i]; i++); /* find first empty slot */
for (i = 0; pgdata_exclude_dir[i]; i++); /* find first empty slot */
pgdata_exclude[i++] = arclog_path;
pgdata_exclude_dir[i++] = arclog_path;
if(!backup_logs)
pgdata_exclude[i++] = "pg_log";
pgdata_exclude_dir[i++] = "pg_log";
if (target_time != NULL && target_xid != NULL)
elog(ERROR, "You can't specify recovery-target-time and recovery-target-xid at the same time");

View File

@ -192,7 +192,7 @@ extern bool check;
extern pgBackup current;
/* exclude directory list for $PGDATA file listing */
extern const char *pgdata_exclude[];
extern const char *pgdata_exclude_dir[];
/* backup file list from non-snapshot */
extern parray *backup_files_list;
@ -284,9 +284,10 @@ extern int pgBackupCompareId(const void *f1, const void *f2);
extern int pgBackupCompareIdDesc(const void *f1, const void *f2);
/* in dir.c */
extern void dir_list_file(parray *files, const char *root, const char *exclude[], bool omit_symlink, bool add_root);
extern void dir_list_file_internal(parray *files, const char *root, const char *exclude[],
bool omit_symlink, bool add_root, parray *black_list);
extern void dir_list_file(parray *files, const char *root, bool exclude,
bool omit_symlink, bool add_root);
extern void dir_list_file_internal(parray *files, const char *root, bool exclude,
bool omit_symlink, bool add_root, parray *black_list);
extern void dir_print_mkdirs_sh(FILE *out, const parray *files, const char *root);
extern void dir_print_file_list(FILE *out, const parray *files, const char *root, const char *prefix);
extern parray *dir_read_file_list(const char *root, const char *file_txt);

View File

@ -160,7 +160,7 @@ base_backup_found:
elog(LOG, "clearing restore destination");
files = parray_new();
dir_list_file(files, pgdata, NULL, false, false);
dir_list_file(files, pgdata, false, false, false);
parray_qsort(files, pgFileComparePathDesc); /* delete from leaf */
for (i = 0; i < parray_num(files); i++)
@ -364,7 +364,7 @@ restore_database(pgBackup *backup)
/* get list of files restored to pgdata */
files_now = parray_new();
dir_list_file(files_now, pgdata, pgdata_exclude, true, false);
dir_list_file(files_now, pgdata, true, true, false);
/* to delete from leaf, sort in reversed order */
parray_qsort(files_now, pgFileComparePathDesc);

View File

@ -1,5 +1,5 @@
import unittest
from os import path
from os import path, listdir
import six
from .pb_lib import ProbackupTest
from testgres import stop_all
@ -35,6 +35,17 @@ class BackupTest(ProbackupTest, unittest.TestCase):
self.assertEqual(show_backup.status, six.b("OK"))
self.assertEqual(show_backup.mode, six.b("FULL"))
# postmaster.pid and postmaster.opts shouldn't be copied
excluded = True
backups_dir = path.join(self.backup_dir(node), "backups")
for backup in listdir(backups_dir):
db_dir = path.join(backups_dir, backup, "database")
for f in listdir(db_dir):
if path.isfile(path.join(db_dir, f)) and \
(f == "postmaster.pid" or f == "postmaster.opts"):
excluded = False
self.assertEqual(excluded, True)
# page backup mode
with open(path.join(node.logs_dir, "backup_page.log"), "wb") as backup_log:
backup_log.write(self.backup_pb(node, backup_type="page", options=["--verbose"]))