6 * Copyright (c) 2010-2022, PostgreSQL Global Development Group
7 * src/bin/pg_upgrade/tablespace.c
10 #include "postgres_fe.h"
12 #include "pg_upgrade.h"
14 static void get_tablespace_paths(void);
15 static void set_tablespace_directory_suffix(ClusterInfo
*cluster
);
19 init_tablespaces(void)
21 get_tablespace_paths();
23 set_tablespace_directory_suffix(&old_cluster
);
24 set_tablespace_directory_suffix(&new_cluster
);
26 if (os_info
.num_old_tablespaces
> 0 &&
27 strcmp(old_cluster
.tablespace_suffix
, new_cluster
.tablespace_suffix
) == 0)
28 pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
29 "using tablespaces.\n");
34 * get_tablespace_paths()
36 * Scans pg_tablespace and returns a malloc'ed array of all tablespace
37 * paths. It's the caller's responsibility to free the array.
40 get_tablespace_paths(void)
42 PGconn
*conn
= connectToServer(&old_cluster
, "template1");
46 char query
[QUERY_ALLOC
];
48 snprintf(query
, sizeof(query
),
49 "SELECT pg_catalog.pg_tablespace_location(oid) AS spclocation "
50 "FROM pg_catalog.pg_tablespace "
51 "WHERE spcname != 'pg_default' AND "
52 " spcname != 'pg_global'");
54 res
= executeQueryOrDie(conn
, "%s", query
);
56 if ((os_info
.num_old_tablespaces
= PQntuples(res
)) != 0)
57 os_info
.old_tablespaces
=
58 (char **) pg_malloc(os_info
.num_old_tablespaces
* sizeof(char *));
60 os_info
.old_tablespaces
= NULL
;
62 i_spclocation
= PQfnumber(res
, "spclocation");
64 for (tblnum
= 0; tblnum
< os_info
.num_old_tablespaces
; tblnum
++)
68 os_info
.old_tablespaces
[tblnum
] = pg_strdup(PQgetvalue(res
, tblnum
, i_spclocation
));
71 * Check that the tablespace path exists and is a directory.
72 * Effectively, this is checking only for tables/indexes in
73 * non-existent tablespace directories. Databases located in
74 * non-existent tablespaces already throw a backend error.
75 * Non-existent tablespace directories can occur when a data directory
76 * that contains user tablespaces is moved as part of pg_upgrade
77 * preparation and the symbolic links are not updated.
79 if (stat(os_info
.old_tablespaces
[tblnum
], &statBuf
) != 0)
82 report_status(PG_FATAL
,
83 "tablespace directory \"%s\" does not exist\n",
84 os_info
.old_tablespaces
[tblnum
]);
86 report_status(PG_FATAL
,
87 "could not stat tablespace directory \"%s\": %s\n",
88 os_info
.old_tablespaces
[tblnum
], strerror(errno
));
90 if (!S_ISDIR(statBuf
.st_mode
))
91 report_status(PG_FATAL
,
92 "tablespace path \"%s\" is not a directory\n",
93 os_info
.old_tablespaces
[tblnum
]);
103 set_tablespace_directory_suffix(ClusterInfo
*cluster
)
105 /* This cluster has a version-specific subdirectory */
107 /* The leading slash is needed to start a new directory. */
108 cluster
->tablespace_suffix
= psprintf("/PG_%s_%d",
109 cluster
->major_version_str
,
110 cluster
->controldata
.cat_ver
);