From f3e6b078d4159c90237d966c56289cb59b54ede1 Mon Sep 17 00:00:00 2001 From: Pierre Ducroquet Date: Mon, 1 May 2017 11:38:52 +0200 Subject: [PATCH] Allow a pg_basebackup when a tablespace is shared between two versions When a tablespace folder is shared between two PostgreSQL versions, pg_basebackup fails because its tablespace folder checking is stricter than what is done in the server. That behaviour makes it possible to create clusters that will then be complicated to replicate whithout playing with symlinks. This patch fixes this by delaying the tablespace folder verification. The folder name is using the PG catalog version, that can not be obtained from the server. It is a compile-time constant that is not exposed publicly. The fix is thus to simply delay the checking of folders and use the folder name from the tablespace tarball. --- src/bin/pg_basebackup/pg_basebackup.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index e2a2ebb30f..2e687a2880 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -1306,6 +1306,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) pgoff_t current_len_left = 0; int current_padding = 0; bool basetablespace; + bool firstfile = 1; char *copybuf = NULL; FILE *file = NULL; @@ -1399,7 +1400,15 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) * Directory */ filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */ - if (mkdir(filename, S_IRWXU) != 0) + if (firstfile && !basetablespace) + { + /* + * The first file in the tablespace is its main folder, whose name can not be guessed (PG_MAJORVER_CATVER) + * So we must check here that this folder can be created or is empty. + */ + verify_dir_is_empty_or_create(filename, &made_tablespace_dirs, &found_tablespace_dirs); + } + else if (mkdir(filename, S_IRWXU) != 0) { /* * When streaming WAL, pg_wal (or pg_xlog for pre-9.6 @@ -1530,6 +1539,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) continue; } } /* continuing data in existing file */ + firstfile = 0; /* mark that we are done with the first file of the tarball */ } /* loop over all data blocks */ progress_report(rownum, filename, true); @@ -1844,18 +1854,6 @@ BaseBackup(void) for (i = 0; i < PQntuples(res); i++) { totalsize += atol(PQgetvalue(res, i, 2)); - - /* - * Verify tablespace directories are empty. Don't bother with the - * first once since it can be relocated, and it will be checked before - * we do anything anyway. - */ - if (format == 'p' && !PQgetisnull(res, i, 1)) - { - char *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1)); - - verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs); - } } /* -- 2.11.0