From: Justin Pryzby <pryzby@telsasoft.com>
To: pgsql-hackers@postgresql.org
Subject: pg_upgrade: fail early if a tablespace dir already exists for new cluster version
Date: Thu, 24 Sep 2020 19:55:31 -0500
Message-ID: <20200925005531.GJ23631@telsasoft.com> (raw)
This should be caught during --check, or earlier in the upgrade, rather than
only after dumping the schema.
Typically, the tablespace dir would be left behind by a previous failed upgrade
attempt, causing a cascade of failured upgrades. I guess I may not be the only
one with a 3 year old wrapper which has a hack to check for this.
|rm -fr pgsql12.dat pgsql13.dat
|/usr/pgsql-12/bin/initdb -D pgsql12.dat --no-sync
|/usr/pgsql-13/bin/initdb -D pgsql13.dat --no-sync
|/usr/pgsql-12/bin/postgres -D pgsql12.dat -c port=5678 -k /tmp
|mkdir tblspc tblspc/PG_13_202007203
|psql -h /tmp -p 5678 postgres -c "CREATE TABLESPACE one LOCATION '/home/pryzbyj/tblspc'"
|/usr/pgsql-13/bin/pg_upgrade -D pgsql13.dat -d pgsql12.dat -b /usr/pgsql-12/bin
|pg_upgrade_utility.log:
|CREATE TABLESPACE "one" OWNER "pryzbyj" LOCATION '/home/pryzbyj/tblspc';
|psql:pg_upgrade_dump_globals.sql:27: ERROR: directory "/home/pryzbyj/tblspc/PG_13_202007201" already in use as a tablespace
Attachments:v1-0001-pg_upgrade-check-to-avoid-tablespace-failure-mode.patch (text/x-diff, 2.4K) download
From 3df104610d73833da60bffcc54756a6ecb2f390f Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 24 Sep 2020 19:49:40 -0500
Subject: [PATCH v1] pg_upgrade --check to avoid tablespace failure mode
---
src/bin/pg_upgrade/check.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.cindex 2f7aa632c5..b07e63dab2 100644--- a/src/bin/pg_upgrade/check.c+++ b/src/bin/pg_upgrade/check.c@@ -13,6 +13,7 @@
#include "fe_utils/string_utils.h"
#include "mb/pg_wchar.h"
#include "pg_upgrade.h"
+#include "common/relpath.h"
static void check_new_cluster_is_empty(void);
static void check_databases_are_compatible(void);
@@ -27,6 +28,7 @@ static void check_for_tables_with_oids(ClusterInfo *cluster);
static void check_for_reg_data_type_usage(ClusterInfo *cluster);
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster);
static void check_for_pg_role_prefix(ClusterInfo *cluster);
+static void check_for_existing_tablespace_dirs(ClusterInfo *new_cluster);
static char *get_canonical_locale_name(int category, const char *locale);
@@ -187,6 +189,8 @@ check_new_cluster(void)
check_is_install_user(&new_cluster);
check_for_prepared_transactions(&new_cluster);
++ check_for_existing_tablespace_dirs(&new_cluster);
}
@@ -541,6 +545,34 @@ create_script_for_cluster_analyze(char **analyze_script_file_name)
check_ok();
}
+/*+ * Check that tablespace dirs for new cluster do not already exist.+ * If they did, they'd cause an error while restoring global objects.+ * This allows failing earlier rather than only after dumping schema.+ */+static void+check_for_existing_tablespace_dirs(ClusterInfo *new_cluster)+{+ char old_tablespace_dir[MAXPGPATH];++ prep_status("Checking for pre-existing tablespace directories for new cluster version");++// if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)+ for (int tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)+ {+ struct stat statbuf;+ snprintf(old_tablespace_dir, MAXPGPATH, "%s%c%s",+ os_info.old_tablespaces[tblnum],+ PATH_SEPARATOR, TABLESPACE_VERSION_DIRECTORY);++ canonicalize_path(old_tablespace_dir);++ // XXX: lstat ?+ if (stat(old_tablespace_dir, &statbuf) == 0)+ pg_fatal("tablespace directory already exists for new cluster version: \"%s\"\n",+ old_tablespace_dir);+ }+}
/*
* create_script_for_old_cluster_deletion()
--
2.17.0
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: pryzby@telsasoft.com
Subject: Re: pg_upgrade: fail early if a tablespace dir already exists for new cluster version
In-Reply-To: <20200925005531.GJ23631@telsasoft.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox