From ba7490d1e691bcadb45260dccedc0f72e8550c26 Mon Sep 17 00:00:00 2001 From: mikecaat <35882227+mikecaat@users.noreply.github.com> Date: Mon, 5 Sep 2022 09:08:37 +0900 Subject: [PATCH] Fix the fail if a tablespace path has PGDATA(#141) (#210) 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 | 2 +- expected/restore.out | 5 +++++ expected/restore_checksum.out | 5 +++++ sql/restore.sh | 31 +++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/dir.c b/dir.c index 5861f610..32531903 100644 --- a/dir.c +++ b/dir.c @@ -457,7 +457,7 @@ 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) + 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 60d86b97..31a54288 100644 --- a/expected/restore.out +++ b/expected/restore.out @@ -122,3 +122,8 @@ OK: new value is configured for recovery_target_timeline. 0 0 +###### RESTORE COMMAND TEST-0018 ###### +###### 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 265f23af..b10ca9f3 100644 --- a/expected/restore_checksum.out +++ b/expected/restore_checksum.out @@ -122,3 +122,8 @@ OK: new value is configured for recovery_target_timeline. 0 0 +###### RESTORE COMMAND TEST-0018 ###### +###### check to work even if the path of tablespace has $PGDATA ###### +0 +0 + diff --git a/sql/restore.sh b/sql/restore.sh index 59887cc0..3dabdeaf 100644 --- a/sql/restore.sh +++ b/sql/restore.sh @@ -572,6 +572,37 @@ psql --no-psqlrc -p ${TEST_PGPORT} -d pgbench -c "SELECT * FROM pgbench_branches diff ${TEST_BASE}/TEST-0017-before.out ${TEST_BASE}/TEST-0017-after.out echo '' +echo '###### RESTORE COMMAND TEST-0018 ######' +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-0018-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-0018-after.out +diff ${TEST_BASE}/TEST-0018-before.out ${TEST_BASE}/TEST-0018-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}