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 <br...@momjian.us> 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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers