6 * Copyright (c) 2010-2025, PostgreSQL Global Development Group
7 * src/bin/pg_upgrade/tablespace.c
32 * In-place tablespaces are okay for same-version upgrades because
33 * their paths will differ between clusters.
36 pg_fatal(
"Cannot upgrade to/from the same system catalog version when\n"
37 "using tablespaces.");
44 * get_tablespace_paths()
46 * Scans pg_tablespace and returns a malloc'ed array of all tablespace
47 * paths. It's the caller's responsibility to free the array.
59 "SELECT pg_catalog.pg_tablespace_location(oid) AS spclocation "
60 "FROM pg_catalog.pg_tablespace "
61 "WHERE spcname != 'pg_default' AND "
62 " spcname != 'pg_global'");
82 i_spclocation =
PQfnumber(res,
"spclocation");
87 char *spcloc =
PQgetvalue(res, tblnum, i_spclocation);
90 * For now, we do not expect non-in-place tablespaces to move during
91 * upgrade. If that changes, it will likely become necessary to run
92 * the above query on the new cluster, too.
94 * pg_tablespace_location() returns absolute paths for non-in-place
95 * tablespaces and relative paths for in-place ones, so we use
96 * is_absolute_path() to distinguish between them.
110 * Check that the tablespace path exists and is a directory.
111 * Effectively, this is checking only for tables/indexes in
112 * non-existent tablespace directories. Databases located in
113 * non-existent tablespaces already throw a backend error.
114 * Non-existent tablespace directories can occur when a data directory
115 * that contains user tablespaces is moved as part of pg_upgrade
116 * preparation and the symbolic links are not updated.
122 "tablespace directory \"%s\" does not exist",
126 "could not stat tablespace directory \"%s\": %m",
131 "tablespace path \"%s\" is not a directory",
144 /* This cluster has a version-specific subdirectory */
146 /* The leading slash is needed to start a new directory. */
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
void init_tablespaces(void)
static void get_tablespace_paths(void)
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
void PQfinish(PGconn *conn)
int PQfnumber(const PGresult *res, const char *field_name)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define is_absolute_path(filename)
char * psprintf(const char *fmt,...)
const char * tablespace_suffix