On Sun, Jan 12, 2014 at 11:04:41PM -0500, Bruce Momjian wrote:
> > In the pgsql_old installation you have symlinks pointing back to the
> > current default location. As well pg_tablespace points back to
> > /usr/local/pgsql/data/ The issue is that there is not actually
> > anything there in the way of a tablespace. So when pg_upgrade runs
> > it tries to upgrade from /usr/local/pgsql/data/tblspc_dir to
> > /usr/local/pgsql/data/tblspc_dir where the first directory either
> > does not exist. or if the user went ahead and created the directory
> > in the new installation, is empty. What is really wanted is to
> > upgrade from /usr/local/pgsql_old/data/tblspc_dir to
> > /usr/local/pgsql/data/tblspc_dir. Right now the only way that
> > happens is with user intervention.
>
> Right, it points to _nothing_ in the _new_ cluster. Perhaps the
> simplest approach would be to check all the pg_tablespace locations to
> see if they point at real directories. If not, we would have to have
> the user update pg_tablespace and the symlinks. :-( Actually, even in
> 9.2+, those symlinks are going to point at the same "nothing". That
> would support checking the symlinks in all versions.
I have developed the attached patch which checks all tablespaces to make
sure the directories exist. I plan to backpatch this.
The reason we haven't seen this bug reported more frequently is that a
_database_ defined in a non-existent tablespace directory already throws
an backend error, so this check is only necessary where tables/indexes
(not databases) are defined in non-existant tablespace directories.
--
Bruce Momjian <[email protected]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ Everyone has their own god. +
diff --git a/contrib/pg_upgrade/tablespace.c b/contrib/pg_upgrade/tablespace.c
new file mode 100644
index 783ee93..5a3dc60
*** a/contrib/pg_upgrade/tablespace.c
--- b/contrib/pg_upgrade/tablespace.c
***************
*** 11,16 ****
--- 11,18 ----
#include "pg_upgrade.h"
+ #include <sys/types.h>
+
static void get_tablespace_paths(void);
static void set_tablespace_directory_suffix(ClusterInfo *cluster);
*************** get_tablespace_paths(void)
*** 65,73 ****
--- 67,101 ----
i_spclocation = PQfnumber(res, "spclocation");
for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
+ {
+ struct stat statBuf;
+
os_info.old_tablespaces[tblnum] = pg_strdup(
PQgetvalue(res, tblnum, i_spclocation));
+ /*
+ * Check that the tablespace path exists and is a directory.
+ * Effectively, this is checking only for tables/indexes in
+ * non-existant tablespace directories. Databases located in
+ * non-existant tablespaces already throw a backend error.
+ */
+ if (stat(os_info.old_tablespaces[tblnum], &statBuf) != 0)
+ {
+ if (errno == ENOENT)
+ report_status(PG_FATAL,
+ "tablespace directory \"%s\" does not exist\n",
+ os_info.old_tablespaces[tblnum]);
+ else
+ report_status(PG_FATAL,
+ "cannot stat() tablespace directory \"%s\": %s\n",
+ os_info.old_tablespaces[tblnum], getErrorText(errno));
+ }
+ if (!S_ISDIR(statBuf.st_mode))
+ report_status(PG_FATAL,
+ "tablespace path \"%s\" is not a directory\n",
+ os_info.old_tablespaces[tblnum]);
+ }
+
PQclear(res);
PQfinish(conn);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers