PostgreSQL Source Code: src/bin/pg_upgrade/tablespace.c Source File

PostgreSQL Source Code git master
tablespace.c
Go to the documentation of this file.
1/*
2 * tablespace.c
3 *
4 * tablespace functions
5 *
6 * Copyright (c) 2010-2025, PostgreSQL Global Development Group
7 * src/bin/pg_upgrade/tablespace.c
8 */
9
10#include "postgres_fe.h"
11
12#include "pg_upgrade.h"
13
14static void get_tablespace_paths(void);
15static void set_tablespace_directory_suffix(ClusterInfo *cluster);
16
17
18void
19 init_tablespaces(void)
20{
21 get_tablespace_paths();
22
23 set_tablespace_directory_suffix(&old_cluster);
24 set_tablespace_directory_suffix(&new_cluster);
25
26 if (old_cluster.num_tablespaces > 0 &&
27 strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
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 */
35 if (strcmp(old_cluster.tablespaces[i], new_cluster.tablespaces[i]) == 0)
36 pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
37 "using tablespaces.");
38 }
39 }
40}
41
42
43/*
44 * get_tablespace_paths()
45 *
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.
48 */
49static void
50 get_tablespace_paths(void)
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
66 old_cluster.num_tablespaces = PQntuples(res);
67 new_cluster.num_tablespaces = PQntuples(res);
68
69 if (PQntuples(res) != 0)
70 {
71 old_cluster.tablespaces =
72 (char **) pg_malloc(old_cluster.num_tablespaces * sizeof(char *));
73 new_cluster.tablespaces =
74 (char **) pg_malloc(new_cluster.num_tablespaces * sizeof(char *));
75 }
76 else
77 {
78 old_cluster.tablespaces = NULL;
79 new_cluster.tablespaces = NULL;
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);
101 new_cluster.tablespaces[tblnum] = old_cluster.tablespaces[tblnum];
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)
121 report_status(PG_FATAL,
122 "tablespace directory \"%s\" does not exist",
123 old_cluster.tablespaces[tblnum]);
124 else
125 report_status(PG_FATAL,
126 "could not stat tablespace directory \"%s\": %m",
127 old_cluster.tablespaces[tblnum]);
128 }
129 if (!S_ISDIR(statBuf.st_mode))
130 report_status(PG_FATAL,
131 "tablespace path \"%s\" is not a directory",
132 old_cluster.tablespaces[tblnum]);
133 }
134
135 PQclear(res);
136
137 PQfinish(conn);
138}
139
140
141static void
142 set_tablespace_directory_suffix(ClusterInfo *cluster)
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}
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:142
void init_tablespaces(void)
Definition: tablespace.c:19
static void get_tablespace_paths(void)
Definition: tablespace.c:50
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:107
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5305
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3600
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
i
int i
Definition: isn.c:77
#define PQgetvalue
Definition: libpq-be-fe.h:253
#define PQclear
Definition: libpq-be-fe.h:245
#define PQntuples
Definition: libpq-be-fe.h:251
#define pg_fatal(...)
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:239
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
const char * tablespace_suffix
Definition: pg_upgrade.h:305
Definition: win32_port.h:255
unsigned short st_mode
Definition: win32_port.h:258
#define stat
Definition: win32_port.h:274
#define S_ISDIR(m)
Definition: win32_port.h:315

AltStyle によって変換されたページ (->オリジナル) /