PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tablespace.c
Go to the documentation of this file.
1 /*
2  * tablespace.c
3  *
4  * tablespace functions
5  *
6  * Copyright (c) 2010-2017, 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 #include <sys/types.h>
15 
16 static void get_tablespace_paths(void);
18 
19 
20 void
22 {
24 
27 
28  if (os_info.num_old_tablespaces > 0 &&
30  pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
31  "using tablespaces.\n");
32 }
33 
34 
35 /*
36  * get_tablespace_paths()
37  *
38  * Scans pg_tablespace and returns a malloc'ed array of all tablespace
39  * paths. Its the caller's responsibility to free the array.
40  */
41 static void
43 {
44  PGconn *conn = connectToServer(&old_cluster, "template1");
45  PGresult *res;
46  int tblnum;
47  int i_spclocation;
48  char query[QUERY_ALLOC];
49 
50  snprintf(query, sizeof(query),
51  "SELECT %s "
52  "FROM pg_catalog.pg_tablespace "
53  "WHERE spcname != 'pg_default' AND "
54  " spcname != 'pg_global'",
55  /* 9.2 removed the spclocation column */
57  "spclocation" : "pg_catalog.pg_tablespace_location(oid) AS spclocation");
58 
59  res = executeQueryOrDie(conn, "%s", query);
60 
61  if ((os_info.num_old_tablespaces = PQntuples(res)) != 0)
62  os_info.old_tablespaces = (char **) pg_malloc(
63  os_info.num_old_tablespaces * sizeof(char *));
64  else
66 
67  i_spclocation = PQfnumber(res, "spclocation");
68 
69  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
70  {
71  struct stat statBuf;
72 
74  PQgetvalue(res, tblnum, i_spclocation));
75 
76  /*
77  * Check that the tablespace path exists and is a directory.
78  * Effectively, this is checking only for tables/indexes in
79  * non-existent tablespace directories. Databases located in
80  * non-existent tablespaces already throw a backend error.
81  * Non-existent tablespace directories can occur when a data directory
82  * that contains user tablespaces is moved as part of pg_upgrade
83  * preparation and the symbolic links are not updated.
84  */
85  if (stat(os_info.old_tablespaces[tblnum], &statBuf) != 0)
86  {
87  if (errno == ENOENT)
89  "tablespace directory \"%s\" does not exist\n",
90  os_info.old_tablespaces[tblnum]);
91  else
93  "could not stat tablespace directory \"%s\": %s\n",
94  os_info.old_tablespaces[tblnum], strerror(errno));
95  }
96  if (!S_ISDIR(statBuf.st_mode))
98  "tablespace path \"%s\" is not a directory\n",
99  os_info.old_tablespaces[tblnum]);
100  }
101 
102  PQclear(res);
103 
104  PQfinish(conn);
105 
106  return;
107 }
108 
109 
110 static void
112 {
113  if (GET_MAJOR_VERSION(cluster->major_version) <= 804)
114  cluster->tablespace_suffix = pg_strdup("");
115  else
116  {
117  /* This cluster has a version-specific subdirectory */
118 
119  /* The leading slash is needed to start a new directory. */
120  cluster->tablespace_suffix = psprintf("/PG_%s_%d",
121  cluster->major_version_str,
122  cluster->controldata.cat_ver);
123  }
124 }
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:111
static void get_tablespace_paths(void)
Definition: tablespace.c:42
uint32 major_version
Definition: pg_upgrade.h:274
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
ControlData controldata
Definition: pg_upgrade.h:264
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
#define QUERY_ALLOC
Definition: logging.c:26
char major_version_str[64]
Definition: pg_upgrade.h:275
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
PGconn * conn
Definition: streamutil.c:45
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
uint32 cat_ver
Definition: pg_upgrade.h:210
char ** old_tablespaces
Definition: pg_upgrade.h:313
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
const char * tablespace_suffix
Definition: pg_upgrade.h:277
void init_tablespaces(void)
Definition: tablespace.c:21
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:226
int num_old_tablespaces
Definition: pg_upgrade.h:314
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:57
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2