PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
relfilenode.c File Reference
#include "postgres_fe.h"
#include "pg_upgrade.h"
#include <sys/stat.h>
#include "catalog/pg_class.h"
#include "access/transam.h"
Include dependency graph for relfilenode.c:

Go to the source code of this file.

Functions

static void transfer_single_new_db (FileNameMap *maps, int size, char *old_tablespace)
 
static void transfer_relfile (FileNameMap *map, const char *suffix, bool vm_must_add_frozenbit)
 
void transfer_all_new_tablespaces (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata)
 
void transfer_all_new_dbs (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
 

Function Documentation

void transfer_all_new_dbs ( DbInfoArr old_db_arr,
DbInfoArr new_db_arr,
char *  old_pgdata,
char *  new_pgdata,
char *  old_tablespace 
)

Definition at line 81 of file relfilenode.c.

References DbInfo::db_name, DbInfoArr::dbs, gen_db_file_maps(), DbInfoArr::ndbs, NULL, pg_fatal(), pg_free(), print_maps(), and transfer_single_new_db().

Referenced by parallel_transfer_all_new_dbs().

83 {
84  int old_dbnum,
85  new_dbnum;
86 
87  /* Scan the old cluster databases and transfer their files */
88  for (old_dbnum = new_dbnum = 0;
89  old_dbnum < old_db_arr->ndbs;
90  old_dbnum++, new_dbnum++)
91  {
92  DbInfo *old_db = &old_db_arr->dbs[old_dbnum],
93  *new_db = NULL;
94  FileNameMap *mappings;
95  int n_maps;
96 
97  /*
98  * Advance past any databases that exist in the new cluster but not in
99  * the old, e.g. "postgres". (The user might have removed the
100  * 'postgres' database from the old cluster.)
101  */
102  for (; new_dbnum < new_db_arr->ndbs; new_dbnum++)
103  {
104  new_db = &new_db_arr->dbs[new_dbnum];
105  if (strcmp(old_db->db_name, new_db->db_name) == 0)
106  break;
107  }
108 
109  if (new_dbnum >= new_db_arr->ndbs)
110  pg_fatal("old database \"%s\" not found in the new cluster\n",
111  old_db->db_name);
112 
113  mappings = gen_db_file_maps(old_db, new_db, &n_maps, old_pgdata,
114  new_pgdata);
115  if (n_maps)
116  {
117  print_maps(mappings, n_maps, new_db->db_name);
118 
119  transfer_single_new_db(mappings, n_maps, old_tablespace);
120  }
121  /* We allocate something even for n_maps == 0 */
122  pg_free(mappings);
123  }
124 
125  return;
126 }
FileNameMap * gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, int *nmaps, const char *old_pgdata, const char *new_pgdata)
Definition: info.c:41
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void print_maps(FileNameMap *maps, int n_maps, const char *db_name)
Definition: info.c:285
#define NULL
Definition: c.h:229
void pg_free(void *ptr)
Definition: fe_memutils.c:105
char * db_name
Definition: pg_upgrade.h:183
DbInfo * dbs
Definition: pg_upgrade.h:194
static void transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
Definition: relfilenode.c:134
void transfer_all_new_tablespaces ( DbInfoArr old_db_arr,
DbInfoArr new_db_arr,
char *  old_pgdata,
char *  new_pgdata 
)

Definition at line 30 of file relfilenode.c.

References check_ok(), end_progress_output(), UserOpts::jobs, NULL, OSInfo::num_old_tablespaces, OSInfo::old_tablespaces, os_info, parallel_transfer_all_new_dbs(), pg_log(), PG_REPORT, reap_child(), UserOpts::transfer_mode, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

32 {
34  pg_log(PG_REPORT, "Linking user relation files\n");
35  else
36  pg_log(PG_REPORT, "Copying user relation files\n");
37 
38  /*
39  * Transferring files by tablespace is tricky because a single database
40  * can use multiple tablespaces. For non-parallel mode, we just pass a
41  * NULL tablespace path, which matches all tablespaces. In parallel mode,
42  * we pass the default tablespace and all user-created tablespaces and let
43  * those operations happen in parallel.
44  */
45  if (user_opts.jobs <= 1)
46  parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
47  new_pgdata, NULL);
48  else
49  {
50  int tblnum;
51 
52  /* transfer default tablespace */
53  parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
54  new_pgdata, old_pgdata);
55 
56  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
58  new_db_arr,
59  old_pgdata,
60  new_pgdata,
61  os_info.old_tablespaces[tblnum]);
62  /* reap all children */
63  while (reap_child(true) == true)
64  ;
65  }
66 
68  check_ok();
69 
70  return;
71 }
void end_progress_output(void)
Definition: util.c:44
int jobs
Definition: pg_upgrade.h:296
void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
Definition: parallel.c:178
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2023
transferMode transfer_mode
Definition: pg_upgrade.h:295
UserOpts user_opts
Definition: option.c:29
char ** old_tablespaces
Definition: pg_upgrade.h:309
#define NULL
Definition: c.h:229
bool reap_child(bool wait_for_child)
Definition: parallel.c:290
int num_old_tablespaces
Definition: pg_upgrade.h:310
OSInfo os_info
Definition: pg_upgrade.c:58
static void transfer_relfile ( FileNameMap map,
const char *  suffix,
bool  vm_must_add_frozenbit 
)
static

Definition at line 186 of file relfilenode.c.

References copyFile(), linkFile(), MAXPGPATH, FileNameMap::new_db_oid, FileNameMap::new_relfilenode, FileNameMap::new_tablespace, FileNameMap::new_tablespace_suffix, FileNameMap::nspname, FileNameMap::old_db_oid, FileNameMap::old_relfilenode, FileNameMap::old_tablespace, FileNameMap::old_tablespace_suffix, pg_fatal(), pg_log(), PG_STATUS, PG_VERBOSE, FileNameMap::relname, rewriteVisibilityMap(), snprintf(), strerror(), UserOpts::transfer_mode, TRANSFER_MODE_COPY, unlink(), and user_opts.

Referenced by transfer_single_new_db().

187 {
188  char old_file[MAXPGPATH];
189  char new_file[MAXPGPATH];
190  int segno;
191  char extent_suffix[65];
192  struct stat statbuf;
193 
194  /*
195  * Now copy/link any related segments as well. Remember, PG breaks large
196  * files into 1GB segments, the first segment has no extension, subsequent
197  * segments are named relfilenode.1, relfilenode.2, relfilenode.3. copied.
198  */
199  for (segno = 0;; segno++)
200  {
201  if (segno == 0)
202  extent_suffix[0] = '\0';
203  else
204  snprintf(extent_suffix, sizeof(extent_suffix), ".%d", segno);
205 
206  snprintf(old_file, sizeof(old_file), "%s%s/%u/%u%s%s",
207  map->old_tablespace,
209  map->old_db_oid,
210  map->old_relfilenode,
211  type_suffix,
212  extent_suffix);
213  snprintf(new_file, sizeof(new_file), "%s%s/%u/%u%s%s",
214  map->new_tablespace,
216  map->new_db_oid,
217  map->new_relfilenode,
218  type_suffix,
219  extent_suffix);
220 
221  /* Is it an extent, fsm, or vm file? */
222  if (type_suffix[0] != '\0' || segno != 0)
223  {
224  /* Did file open fail? */
225  if (stat(old_file, &statbuf) != 0)
226  {
227  /* File does not exist? That's OK, just return */
228  if (errno == ENOENT)
229  return;
230  else
231  pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
232  map->nspname, map->relname, old_file, new_file,
233  strerror(errno));
234  }
235 
236  /* If file is empty, just return */
237  if (statbuf.st_size == 0)
238  return;
239  }
240 
241  unlink(new_file);
242 
243  /* Copying files might take some time, so give feedback. */
244  pg_log(PG_STATUS, "%s", old_file);
245 
246  if (vm_must_add_frozenbit && strcmp(type_suffix, "_vm") == 0)
247  {
248  /* Need to rewrite visibility map format */
249  pg_log(PG_VERBOSE, "rewriting \"%s\" to \"%s\"\n",
250  old_file, new_file);
251  rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname);
252  }
254  {
255  pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n",
256  old_file, new_file);
257  copyFile(old_file, new_file, map->nspname, map->relname);
258  }
259  else
260  {
261  pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n",
262  old_file, new_file);
263  linkFile(old_file, new_file, map->nspname, map->relname);
264  }
265  }
266 }
Oid old_relfilenode
Definition: pg_upgrade.h:170
void rewriteVisibilityMap(const char *fromfile, const char *tofile, const char *schemaName, const char *relName)
Definition: file.c:129
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
Oid new_db_oid
Definition: pg_upgrade.h:164
void copyFile(const char *src, const char *dst, const char *schemaName, const char *relName)
Definition: file.c:34
const char * old_tablespace
Definition: pg_upgrade.h:159
Oid new_relfilenode
Definition: pg_upgrade.h:171
#define MAXPGPATH
void linkFile(const char *src, const char *dst, const char *schemaName, const char *relName)
Definition: file.c:103
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
int unlink(const char *filename)
const char * old_tablespace_suffix
Definition: pg_upgrade.h:161
transferMode transfer_mode
Definition: pg_upgrade.h:295
UserOpts user_opts
Definition: option.c:29
Oid old_db_oid
Definition: pg_upgrade.h:163
char * nspname
Definition: pg_upgrade.h:173
const char * strerror(int errnum)
Definition: strerror.c:19
const char * new_tablespace
Definition: pg_upgrade.h:160
const char * new_tablespace_suffix
Definition: pg_upgrade.h:162
char * relname
Definition: pg_upgrade.h:174
static void transfer_single_new_db ( FileNameMap maps,
int  size,
char *  old_tablespace 
)
static

Definition at line 134 of file relfilenode.c.

References ControlData::cat_ver, ClusterInfo::controldata, GET_MAJOR_VERSION, ClusterInfo::major_version, new_cluster, NULL, old_cluster, transfer_relfile(), VISIBILITY_MAP_CRASHSAFE_CAT_VER, and VISIBILITY_MAP_FROZEN_BIT_CAT_VER.

Referenced by transfer_all_new_dbs().

135 {
136  int mapnum;
137  bool vm_crashsafe_match = true;
138  bool vm_must_add_frozenbit = false;
139 
140  /*
141  * Do the old and new cluster disagree on the crash-safetiness of the vm
142  * files? If so, do not copy them.
143  */
146  vm_crashsafe_match = false;
147 
148  /*
149  * Do we need to rewrite visibilitymap?
150  */
153  vm_must_add_frozenbit = true;
154 
155  for (mapnum = 0; mapnum < size; mapnum++)
156  {
157  if (old_tablespace == NULL ||
158  strcmp(maps[mapnum].old_tablespace, old_tablespace) == 0)
159  {
160  /* transfer primary file */
161  transfer_relfile(&maps[mapnum], "", vm_must_add_frozenbit);
162 
163  /* fsm/vm files added in PG 8.4 */
165  {
166  /*
167  * Copy/link any fsm and vm files, if they exist
168  */
169  transfer_relfile(&maps[mapnum], "_fsm", vm_must_add_frozenbit);
170  if (vm_crashsafe_match)
171  transfer_relfile(&maps[mapnum], "_vm", vm_must_add_frozenbit);
172  }
173  }
174  }
175 }
uint32 major_version
Definition: pg_upgrade.h:270
#define VISIBILITY_MAP_CRASHSAFE_CAT_VER
Definition: pg_upgrade.h:106
ControlData controldata
Definition: pg_upgrade.h:260
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
static void transfer_relfile(FileNameMap *map, const char *suffix, bool vm_must_add_frozenbit)
Definition: relfilenode.c:186
#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER
Definition: pg_upgrade.h:111
uint32 cat_ver
Definition: pg_upgrade.h:206
#define NULL
Definition: c.h:229