PostgreSQL Source Code git master
tablespace.c File Reference
#include "postgres_fe.h"
#include "pg_upgrade.h"
Include dependency graph for tablespace.c:

Go to the source code of this file.

Functions

static void get_tablespace_paths (void)
 
static void set_tablespace_directory_suffix (ClusterInfo *cluster)
 
void init_tablespaces (void)
 

Function Documentation

◆ get_tablespace_paths()

static void get_tablespace_paths ( void  )
static

Definition at line 50 of file tablespace.c.

51{
52 PGconn *conn = connectToServer(&old_cluster, "template1");
53 PGresult *res;
54 int tblnum;
55 int i_spclocation;
56 char query[QUERY_ALLOC];
57
58 snprintf(query, sizeof(query),
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'");
63
64 res = executeQueryOrDie(conn, "%s", query);
65
68
69 if (PQntuples(res) != 0)
70 {
72 (char **) pg_malloc(old_cluster.num_tablespaces * sizeof(char *));
74 (char **) pg_malloc(new_cluster.num_tablespaces * sizeof(char *));
75 }
76 else
77 {
80 }
81
82 i_spclocation = PQfnumber(res, "spclocation");
83
84 for (tblnum = 0; tblnum < old_cluster.num_tablespaces; tblnum++)
85 {
86 struct stat statBuf;
87 char *spcloc = PQgetvalue(res, tblnum, i_spclocation);
88
89 /*
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.
93 *
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.
97 */
98 if (is_absolute_path(PQgetvalue(res, tblnum, i_spclocation)))
99 {
100 old_cluster.tablespaces[tblnum] = pg_strdup(spcloc);
102 }
103 else
104 {
105 old_cluster.tablespaces[tblnum] = psprintf("%s/%s", old_cluster.pgdata, spcloc);
106 new_cluster.tablespaces[tblnum] = psprintf("%s/%s", new_cluster.pgdata, spcloc);
107 }
108
109 /*
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.
117 */
118 if (stat(old_cluster.tablespaces[tblnum], &statBuf) != 0)
119 {
120 if (errno == ENOENT)
122 "tablespace directory \"%s\" does not exist",
123 old_cluster.tablespaces[tblnum]);
124 else
126 "could not stat tablespace directory \"%s\": %m",
127 old_cluster.tablespaces[tblnum]);
128 }
129 if (!S_ISDIR(statBuf.st_mode))
131 "tablespace path \"%s\" is not a directory",
132 old_cluster.tablespaces[tblnum]);
133 }
134
135 PQclear(res);
136
137 PQfinish(conn);
138}
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5316
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3606
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define PQgetvalue
Definition: libpq-be-fe.h:253
#define PQclear
Definition: libpq-be-fe.h:245
#define PQntuples
Definition: libpq-be-fe.h:251
ClusterInfo new_cluster
Definition: pg_upgrade.c:73
ClusterInfo old_cluster
Definition: pg_upgrade.c:72
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
#define QUERY_ALLOC
Definition: pg_upgrade.h:23
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
@ PG_FATAL
Definition: pg_upgrade.h:278
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define is_absolute_path(filename)
Definition: port.h:104
#define snprintf
Definition: port.h:260
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
PGconn * conn
Definition: streamutil.c:52
char * pgdata
Definition: pg_upgrade.h:292
int num_tablespaces
Definition: pg_upgrade.h:304
char ** tablespaces
Definition: pg_upgrade.h:303
#define stat
Definition: win32_port.h:274
#define S_ISDIR(m)
Definition: win32_port.h:315

References conn, connectToServer(), executeQueryOrDie(), is_absolute_path, new_cluster, ClusterInfo::num_tablespaces, old_cluster, PG_FATAL, pg_malloc(), pg_strdup(), ClusterInfo::pgdata, PQclear, PQfinish(), PQfnumber(), PQgetvalue, PQntuples, psprintf(), QUERY_ALLOC, report_status(), S_ISDIR, snprintf, stat::st_mode, stat, and ClusterInfo::tablespaces.

Referenced by init_tablespaces().

◆ init_tablespaces()

void init_tablespaces ( void  )

Definition at line 19 of file tablespace.c.

20{
22
25
28 {
29 for (int i = 0; i < old_cluster.num_tablespaces; i++)
30 {
31 /*
32 * In-place tablespaces are okay for same-version upgrades because
33 * their paths will differ between clusters.
34 */
36 pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
37 "using tablespaces.");
38 }
39 }
40}
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:142
static void get_tablespace_paths(void)
Definition: tablespace.c:50
int i
Definition: isn.c:77
#define pg_fatal(...)
const char * tablespace_suffix
Definition: pg_upgrade.h:305

References get_tablespace_paths(), i, new_cluster, ClusterInfo::num_tablespaces, old_cluster, pg_fatal, set_tablespace_directory_suffix(), ClusterInfo::tablespace_suffix, and ClusterInfo::tablespaces.

Referenced by check_and_dump_old_cluster().

◆ set_tablespace_directory_suffix()

static void set_tablespace_directory_suffix ( ClusterInfo cluster)
static

Definition at line 142 of file tablespace.c.

143{
144 /* This cluster has a version-specific subdirectory */
145
146 /* The leading slash is needed to start a new directory. */
147 cluster->tablespace_suffix = psprintf("/PG_%s_%d",
148 cluster->major_version_str,
149 cluster->controldata.cat_ver);
150}
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:107

References cluster(), and psprintf().

Referenced by init_tablespaces().