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-2022, 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 
14 static void get_tablespace_paths(void);
16 
17 
18 void
20 {
22 
25 
26  if (os_info.num_old_tablespaces > 0 &&
28  pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
29  "using tablespaces.");
30 }
31 
32 
33 /*
34  * get_tablespace_paths()
35  *
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.
38  */
39 static void
41 {
42  PGconn *conn = connectToServer(&old_cluster, "template1");
43  PGresult *res;
44  int tblnum;
45  int i_spclocation;
46  char query[QUERY_ALLOC];
47 
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'");
53 
54  res = executeQueryOrDie(conn, "%s", query);
55 
58  (char **) pg_malloc(os_info.num_old_tablespaces * sizeof(char *));
59  else
60  os_info.old_tablespaces = NULL;
61 
62  i_spclocation = PQfnumber(res, "spclocation");
63 
64  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
65  {
66  struct stat statBuf;
67 
68  os_info.old_tablespaces[tblnum] = pg_strdup(PQgetvalue(res, tblnum, i_spclocation));
69 
70  /*
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.
78  */
79  if (stat(os_info.old_tablespaces[tblnum], &statBuf) != 0)
80  {
81  if (errno == ENOENT)
83  "tablespace directory \"%s\" does not exist",
84  os_info.old_tablespaces[tblnum]);
85  else
87  "could not stat tablespace directory \"%s\": %s",
88  os_info.old_tablespaces[tblnum], strerror(errno));
89  }
90  if (!S_ISDIR(statBuf.st_mode))
92  "tablespace path \"%s\" is not a directory",
93  os_info.old_tablespaces[tblnum]);
94  }
95 
96  PQclear(res);
97 
98  PQfinish(conn);
99 }
100 
101 
102 static void
104 {
105  /* This cluster has a version-specific subdirectory */
106 
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);
111 }
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:103
void init_tablespaces(void)
Definition: tablespace.c:19
static void get_tablespace_paths(void)
Definition: tablespace.c:40
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:110
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4130
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3310
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3705
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3418
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define pg_fatal(...)
OSInfo os_info
Definition: pg_upgrade.c:64
ClusterInfo new_cluster
Definition: pg_upgrade.c:63
ClusterInfo old_cluster
Definition: pg_upgrade.c:62
#define QUERY_ALLOC
Definition: pg_upgrade.h:23
@ PG_FATAL
Definition: pg_upgrade.h:243
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:251
#define snprintf
Definition: port.h:238
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
PGconn * conn
Definition: streamutil.c:54
const char * tablespace_suffix
Definition: pg_upgrade.h:267
int num_old_tablespaces
Definition: pg_upgrade.h:316
char ** old_tablespaces
Definition: pg_upgrade.h:315
unsigned short st_mode
Definition: win32_port.h:270
#define stat
Definition: win32_port.h:286
#define S_ISDIR(m)
Definition: win32_port.h:327