1 /*
2  *	pg_upgrade.h
3  *
4  *	Copyright (c) 2010-2017, PostgreSQL Global Development Group
5  *	src/bin/pg_upgrade/pg_upgrade.h
6  */
7 
8 #include <unistd.h>
9 #include <assert.h>
10 #include <sys/stat.h>
11 #include <sys/time.h>
12 
13 #include "libpq-fe.h"
14 
15 /* Use port in the private/dynamic port number range */
16 #define DEF_PGUPORT			50432
17 
18 /* Allocate for null byte */
19 #define USER_NAME_SIZE		128
20 
21 #define MAX_STRING			1024
22 #define LINE_ALLOC			4096
23 #define QUERY_ALLOC			8192
24 
25 #define MIGRATOR_API_VERSION	1
26 
27 #define MESSAGE_WIDTH		60
28 
29 #define GET_MAJOR_VERSION(v)	((v) / 100)
30 
31 /* contains both global db information and CREATE DATABASE commands */
32 #define GLOBALS_DUMP_FILE	"pg_upgrade_dump_globals.sql"
33 #define DB_DUMP_FILE_MASK	"pg_upgrade_dump_%u.custom"
34 
35 #define DB_DUMP_LOG_FILE_MASK	"pg_upgrade_dump_%u.log"
36 #define SERVER_LOG_FILE		"pg_upgrade_server.log"
37 #define UTILITY_LOG_FILE	"pg_upgrade_utility.log"
38 #define INTERNAL_LOG_FILE	"pg_upgrade_internal.log"
39 
40 extern char *output_files[];
41 
42 /*
43  * WIN32 files do not accept writes from multiple processes
44  *
45  * On Win32, we can't send both pg_upgrade output and command output to the
46  * same file because we get the error: "The process cannot access the file
47  * because it is being used by another process." so send the pg_ctl
48  * command-line output to a new file, rather than into the server log file.
49  * Ideally we could use UTILITY_LOG_FILE for this, but some Windows platforms
50  * keep the pg_ctl output file open by the running postmaster, even after
51  * pg_ctl exits.
52  *
53  * We could use the Windows pgwin32_open() flags to allow shared file
54  * writes but is unclear how all other tools would use those flags, so
55  * we just avoid it and log a little differently on Windows;  we adjust
56  * the error message appropriately.
57  */
58 #ifndef WIN32
59 #define SERVER_START_LOG_FILE	SERVER_LOG_FILE
60 #define SERVER_STOP_LOG_FILE	SERVER_LOG_FILE
61 #else
62 #define SERVER_START_LOG_FILE	"pg_upgrade_server_start.log"
63 /*
64  *	"pg_ctl start" keeps SERVER_START_LOG_FILE and SERVER_LOG_FILE open
65  *	while the server is running, so we use UTILITY_LOG_FILE for "pg_ctl
66  *	stop".
67  */
68 #define SERVER_STOP_LOG_FILE	UTILITY_LOG_FILE
69 #endif
70 
71 
72 #ifndef WIN32
73 #define pg_mv_file			rename
74 #define pg_link_file		link
75 #define PATH_SEPARATOR		'/'
76 #define PATH_QUOTE	'\''
77 #define RM_CMD				"rm -f"
78 #define RMDIR_CMD			"rm -rf"
79 #define SCRIPT_PREFIX		"./"
80 #define SCRIPT_EXT			"sh"
81 #define ECHO_QUOTE	"'"
82 #define ECHO_BLANK	""
83 #else
84 #define pg_mv_file			pgrename
85 #define pg_link_file		win32_pghardlink
86 #define PATH_SEPARATOR		'\\'
87 #define PATH_QUOTE	'"'
88 #define RM_CMD				"DEL /q"
89 #define RMDIR_CMD			"RMDIR /s/q"
90 #define SCRIPT_PREFIX		""
91 #define SCRIPT_EXT			"bat"
92 #define EXE_EXT				".exe"
93 #define ECHO_QUOTE	""
94 #define ECHO_BLANK	"."
95 #endif
96 
97 
98 /*
99  * postmaster/postgres -b (binary_upgrade) flag added during PG 9.1
100  * development
101  */
102 #define BINARY_UPGRADE_SERVER_FLAG_CAT_VER 201104251
103 
104 /*
105  *	Visibility map changed with this 9.2 commit,
106  *	8f9fe6edce358f7904e0db119416b4d1080a83aa; pick later catalog version.
107  */
108 #define VISIBILITY_MAP_CRASHSAFE_CAT_VER 201107031
109 
110 /*
111  * The format of visibility map is changed with this 9.6 commit,
112  */
113 #define VISIBILITY_MAP_FROZEN_BIT_CAT_VER 201603011
114 
115 /*
116  * pg_multixact format changed in 9.3 commit 0ac5ad5134f2769ccbaefec73844f85,
117  * ("Improve concurrency of foreign key locking") which also updated catalog
118  * version to this value.  pg_upgrade behavior depends on whether old and new
119  * server versions are both newer than this, or only the new one is.
120  */
121 #define MULTIXACT_FORMATCHANGE_CAT_VER 201301231
122 
123 /*
124  * large object chunk size added to pg_controldata,
125  * commit 5f93c37805e7485488480916b4585e098d3cc883
126  */
127 #define LARGE_OBJECT_SIZE_PG_CONTROL_VER 942
128 
129 /*
130  * change in JSONB format during 9.4 beta
131  */
132 #define JSONB_FORMAT_CHANGE_CAT_VER 201409291
133 
134 
135 /*
136  * Each relation is represented by a relinfo structure.
137  */
138 typedef struct
139 {
140 	/* Can't use NAMEDATALEN; not guaranteed to be same on client */
141 	char	   *nspname;		/* namespace name */
142 	char	   *relname;		/* relation name */
143 	Oid			reloid;			/* relation OID */
144 	Oid			relfilenode;	/* relation relfile node */
145 	Oid			indtable;		/* if index, OID of its table, else 0 */
146 	Oid			toastheap;		/* if toast table, OID of base table, else 0 */
147 	char	   *tablespace;		/* tablespace path; "" for cluster default */
148 	bool		nsp_alloc;		/* should nspname be freed? */
149 	bool		tblsp_alloc;	/* should tablespace be freed? */
150 } RelInfo;
151 
152 typedef struct
153 {
154 	RelInfo    *rels;
155 	int			nrels;
156 } RelInfoArr;
157 
158 /*
159  * The following structure represents a relation mapping.
160  */
161 typedef struct
162 {
163 	const char *old_tablespace;
164 	const char *new_tablespace;
165 	const char *old_tablespace_suffix;
166 	const char *new_tablespace_suffix;
167 	Oid			old_db_oid;
168 	Oid			new_db_oid;
169 
170 	/*
171 	 * old/new relfilenodes might differ for pg_largeobject(_metadata) indexes
172 	 * due to VACUUM FULL or REINDEX.  Other relfilenodes are preserved.
173 	 */
174 	Oid			old_relfilenode;
175 	Oid			new_relfilenode;
176 	/* the rest are used only for logging and error reporting */
177 	char	   *nspname;		/* namespaces */
178 	char	   *relname;
179 } FileNameMap;
180 
181 /*
182  * Structure to store database information
183  */
184 typedef struct
185 {
186 	Oid			db_oid;			/* oid of the database */
187 	char	   *db_name;		/* database name */
188 	char		db_tablespace[MAXPGPATH];	/* database default tablespace
189 											 * path */
190 	char	   *db_collate;
191 	char	   *db_ctype;
192 	int			db_encoding;
193 	RelInfoArr	rel_arr;		/* array of all user relinfos */
194 } DbInfo;
195 
196 typedef struct
197 {
198 	DbInfo	   *dbs;			/* array of db infos */
199 	int			ndbs;			/* number of db infos */
200 } DbInfoArr;
201 
202 /*
203  * The following structure is used to hold pg_control information.
204  * Rather than using the backend's control structure we use our own
205  * structure to avoid pg_control version issues between releases.
206  */
207 typedef struct
208 {
209 	uint32		ctrl_ver;
210 	uint32		cat_ver;
211 	char		nextxlogfile[25];
212 	uint32		chkpnt_nxtxid;
213 	uint32		chkpnt_nxtepoch;
214 	uint32		chkpnt_nxtoid;
215 	uint32		chkpnt_nxtmulti;
216 	uint32		chkpnt_nxtmxoff;
217 	uint32		chkpnt_oldstMulti;
218 	uint32		chkpnt_oldstxid;
219 	uint32		align;
220 	uint32		blocksz;
221 	uint32		largesz;
222 	uint32		walsz;
223 	uint32		walseg;
224 	uint32		ident;
225 	uint32		index;
226 	uint32		toast;
227 	uint32		large_object;
228 	bool		date_is_int;
229 	bool		float8_pass_by_value;
230 	bool		data_checksum_version;
231 } ControlData;
232 
233 /*
234  * Enumeration to denote link modes
235  */
236 typedef enum
237 {
238 	TRANSFER_MODE_COPY,
239 	TRANSFER_MODE_LINK
240 } transferMode;
241 
242 /*
243  * Enumeration to denote pg_log modes
244  */
245 typedef enum
246 {
247 	PG_VERBOSE,
248 	PG_STATUS,
249 	PG_REPORT,
250 	PG_WARNING,
251 	PG_FATAL
252 } eLogType;
253 
254 
255 typedef long pgpid_t;
256 
257 
258 /*
259  * cluster
260  *
261  *	information about each cluster
262  */
263 typedef struct
264 {
265 	ControlData controldata;	/* pg_control information */
266 	DbInfoArr	dbarr;			/* dbinfos array */
267 	char	   *pgdata;			/* pathname for cluster's $PGDATA directory */
268 	char	   *pgconfig;		/* pathname for cluster's config file
269 								 * directory */
270 	char	   *bindir;			/* pathname for cluster's executable directory */
271 	char	   *pgopts;			/* options to pass to the server, like pg_ctl
272 								 * -o */
273 	char	   *sockdir;		/* directory for Unix Domain socket, if any */
274 	unsigned short port;		/* port number where postmaster is waiting */
275 	uint32		major_version;	/* PG_VERSION of cluster */
276 	char		major_version_str[64];	/* string PG_VERSION of cluster */
277 	uint32		bin_version;	/* version returned from pg_ctl */
278 	const char *tablespace_suffix;	/* directory specification */
279 } ClusterInfo;
280 
281 
282 /*
283  *	LogOpts
284 */
285 typedef struct
286 {
287 	FILE	   *internal;		/* internal log FILE */
288 	bool		verbose;		/* TRUE -> be verbose in messages */
289 	bool		retain;			/* retain log files on success */
290 } LogOpts;
291 
292 
293 /*
294  *	UserOpts
295 */
296 typedef struct
297 {
298 	bool		check;			/* TRUE -> ask user for permission to make
299 								 * changes */
300 	transferMode transfer_mode; /* copy files or link them? */
301 	int			jobs;
302 } UserOpts;
303 
304 
305 /*
306  * OSInfo
307  */
308 typedef struct
309 {
310 	const char *progname;		/* complete pathname for this program */
311 	char	   *exec_path;		/* full path to my executable */
312 	char	   *user;			/* username for clusters */
313 	bool		user_specified; /* user specified on command-line */
314 	char	  **old_tablespaces;	/* tablespaces */
315 	int			num_old_tablespaces;
316 	char	  **libraries;		/* loadable libraries */
317 	int			num_libraries;
318 	ClusterInfo *running_cluster;
319 } OSInfo;
320 
321 
322 /*
323  * Global variables
324  */
325 extern LogOpts log_opts;
326 extern UserOpts user_opts;
327 extern ClusterInfo old_cluster,
328 			new_cluster;
329 extern OSInfo os_info;
330 
331 
332 /* check.c */
333 
334 void		output_check_banner(bool live_check);
335 void		check_and_dump_old_cluster(bool live_check);
336 void		check_new_cluster(void);
337 void		report_clusters_compatible(void);
338 void		issue_warnings_and_set_wal_level(void);
339 void output_completion_banner(char *analyze_script_file_name,
340 						 char *deletion_script_file_name);
341 void		check_cluster_versions(void);
342 void		check_cluster_compatibility(bool live_check);
343 void		create_script_for_old_cluster_deletion(char **deletion_script_file_name);
344 void		create_script_for_cluster_analyze(char **analyze_script_file_name);
345 
346 
347 /* controldata.c */
348 
349 void		get_control_data(ClusterInfo *cluster, bool live_check);
350 void		check_control_data(ControlData *oldctrl, ControlData *newctrl);
351 void		disable_old_cluster(void);
352 
353 
354 /* dump.c */
355 
356 void		generate_old_dump(void);
357 
358 
359 /* exec.c */
360 
361 #define EXEC_PSQL_ARGS "--echo-queries --set ON_ERROR_STOP=on --no-psqlrc --dbname=template1"
362 
363 bool exec_prog(const char *log_file, const char *opt_log_file,
364 		  bool report_error, bool exit_on_error, const char *fmt,...) pg_attribute_printf(5, 6);
365 void		verify_directories(void);
366 bool		pid_lock_file_exists(const char *datadir);
367 
368 
369 /* file.c */
370 
371 void copyFile(const char *src, const char *dst,
372 		 const char *schemaName, const char *relName);
373 void linkFile(const char *src, const char *dst,
374 		 const char *schemaName, const char *relName);
375 void rewriteVisibilityMap(const char *fromfile, const char *tofile,
376 					 const char *schemaName, const char *relName);
377 void		check_hard_link(void);
378 
379 /* fopen_priv() is no longer different from fopen() */
380 #define fopen_priv(path, mode)	fopen(path, mode)
381 
382 /* function.c */
383 
384 void		get_loadable_libraries(void);
385 void		check_loadable_libraries(void);
386 
387 /* info.c */
388 
389 FileNameMap *gen_db_file_maps(DbInfo *old_db,
390 				 DbInfo *new_db, int *nmaps, const char *old_pgdata,
391 				 const char *new_pgdata);
392 void		get_db_and_rel_infos(ClusterInfo *cluster);
393 void print_maps(FileNameMap *maps, int n,
394 		   const char *db_name);
395 
396 /* option.c */
397 
398 void		parseCommandLine(int argc, char *argv[]);
399 void		adjust_data_dir(ClusterInfo *cluster);
400 void		get_sock_dir(ClusterInfo *cluster, bool live_check);
401 
402 /* relfilenode.c */
403 
404 void transfer_all_new_tablespaces(DbInfoArr *old_db_arr,
405 							 DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata);
406 void transfer_all_new_dbs(DbInfoArr *old_db_arr,
407 					 DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata,
408 					 char *old_tablespace);
409 
410 /* tablespace.c */
411 
412 void		init_tablespaces(void);
413 
414 
415 /* server.c */
416 
417 PGconn	   *connectToServer(ClusterInfo *cluster, const char *db_name);
418 PGresult   *executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2, 3);
419 
420 char	   *cluster_conn_opts(ClusterInfo *cluster);
421 
422 bool		start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error);
423 void		stop_postmaster(bool in_atexit);
424 uint32		get_major_server_version(ClusterInfo *cluster);
425 void		check_pghost_envvar(void);
426 
427 
428 /* util.c */
429 
430 char	   *quote_identifier(const char *s);
431 int			get_user_info(char **user_name_p);
432 void		check_ok(void);
433 void		report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3);
434 void		pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3);
435 void		pg_fatal(const char *fmt,...) pg_attribute_printf(1, 2) pg_attribute_noreturn();
436 void		end_progress_output(void);
437 void		prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
438 void		check_ok(void);
439 unsigned int str2uint(const char *str);
440 void		pg_putenv(const char *var, const char *val);
441 
442 
443 /* version.c */
444 
445 bool		check_for_data_types_usage(ClusterInfo *cluster,
446 									   const char *base_query,
447 									   const char *output_path);
448 bool		check_for_data_type_usage(ClusterInfo *cluster,
449 									  const char *type_name,
450 									  const char *output_path);
451 void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
452 										 bool check_mode);
453 void		old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster);
454 void		old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster);
455 void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster,
456 								bool check_mode);
457 void		report_extension_updates(ClusterInfo *cluster);
458 
459 /* parallel.c */
460 void parallel_exec_prog(const char *log_file, const char *opt_log_file,
461 				   const char *fmt,...) pg_attribute_printf(3, 4);
462 void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
463 							  char *old_pgdata, char *new_pgdata,
464 							  char *old_tablespace);
465 bool		reap_child(bool wait_for_child);
466