From effe01d18464f612a1622b7ff8a12c4691d35cad Mon Sep 17 00:00:00 2001 From: Masahiro Ikeda Date: Thu, 21 Oct 2021 15:54:16 +0900 Subject: [PATCH] Fix the fail if a tablespace path has PGDATA(#141) Previously, if the server has a tablespace and its path has PGDATA's path, the restore fails because mkdirs.sh doesn't work. For example, the following case fails to restore. * PGDATA path: /tmp/pgdata * tablespace path: /tmp/pgdata_tblspc So, this patch fixes the case. The root cause is the logic checking whether the file taking backup is in tablespace or PGDATA. Because it only considers their prefix, if the prefix path of tablespace is the same as PGDATA, it decides the file is in PGDATA. So, this patch changes the logic to check it has '/' after the prefix. --- dir.c | 3 ++- expected/restore.out | 5 +++++ expected/restore_checksum.out | 5 +++++ sql/restore.sh | 31 +++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/dir.c b/dir.c index 5861f610..85c71614 100644 --- a/dir.c +++ b/dir.c @@ -457,7 +457,8 @@ dir_print_mkdirs_sh(FILE *out, const parray *files, const char *root) pgFile *file = (pgFile *) parray_get(files, i); if (S_ISDIR(file->mode)) { - if (strstr(file->path, root) == file->path) + /* Check if the path is tablespace's path or not. */ + if (strstr(file->path, root) == file->path && file->path[strlen(root)] == '/') fprintf(out, "mkdir -m 700 -p %s\n", file->path + strlen(root) + 1); else fprintf(out, "mkdir -m 700 -p %s\n", file->path); diff --git a/expected/restore.out b/expected/restore.out index dfada501..94cfde0e 100644 --- a/expected/restore.out +++ b/expected/restore.out @@ -117,3 +117,8 @@ OK: new value is configured for recovery_target_timeline. 0 0 +###### RESTORE COMMAND TEST-0017 ###### +###### check to work even if the path of tablespace has $PGDATA ###### +0 +0 + diff --git a/expected/restore_checksum.out b/expected/restore_checksum.out index 6dc35248..f52a5754 100644 --- a/expected/restore_checksum.out +++ b/expected/restore_checksum.out @@ -117,3 +117,8 @@ OK: new value is configured for recovery_target_timeline. 0 0 +###### RESTORE COMMAND TEST-0017 ###### +###### check to work even if the path of tablespace has $PGDATA ###### +0 +0 + diff --git a/sql/restore.sh b/sql/restore.sh index e62536a8..72e2ee82 100644 --- a/sql/restore.sh +++ b/sql/restore.sh @@ -520,6 +520,37 @@ psql --no-psqlrc -p ${TEST_PGPORT} -d db0015 -c "SELECT * FROM t0015;" > ${TEST_ diff ${TEST_BASE}/TEST-0015-before.out ${TEST_BASE}/TEST-0015-after.out echo '' +echo '###### RESTORE COMMAND TEST-0017 ######' +echo '###### check to work even if the path of tablespace has $PGDATA ######' +init_backup +start_postgres + +TBLSPC_PATH_HAS_PGDATA_PATH=${PGDATA_PATH}_test_tbl/test +TEST_DB=test + +mkdir -p ${TBLSPC_PATH_HAS_PGDATA_PATH} +psql --no-psqlrc -p ${TEST_PGPORT} -d postgres > /dev/null 2>&1 << EOF +CREATE TABLESPACE ${TEST_DB} LOCATION '${TBLSPC_PATH_HAS_PGDATA_PATH}'; +CREATE DATABASE ${TEST_DB} TABLESPACE = ${TEST_DB}; +EOF + +pgbench -p ${TEST_PGPORT} -i -s 10 -d ${TEST_DB} > /dev/null 2>&1 +psql -p ${TEST_PGPORT} --no-psqlrc -d ${TEST_DB} -c "SELECT * FROM pgbench_branches;" > ${TEST_BASE}/TEST-0017-before.out + +pg_rman backup -B ${BACKUP_PATH} -b full -Z -p ${TEST_PGPORT} -d postgres --quiet;echo $? +pg_rman validate -B ${BACKUP_PATH} --quiet +stop_postgres +pg_rman restore -B ${BACKUP_PATH} --quiet;echo $? +start_postgres +sleep 1 + +psql -p ${TEST_PGPORT} --no-psqlrc -d ${TEST_DB} -c "SELECT * FROM pgbench_branches;" > ${TEST_BASE}/TEST-0017-after.out +diff ${TEST_BASE}/TEST-0017-before.out ${TEST_BASE}/TEST-0017-after.out + +stop_postgres +rm -r ${TBLSPC_PATH_HAS_PGDATA_PATH} +echo '' + # clean up the temporal test data pg_ctl stop -m immediate > /dev/null 2>&1 rm -fr ${PGDATA_PATH}