1/*
2 * pg_upgrade.h
3 *
4 * Copyright (c) 2010-2019, 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
40extern 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 */
138typedef 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
152typedef struct
153{
154 RelInfo *rels;
155 int nrels;
156} RelInfoArr;
157
158/*
159 * The following structure represents a relation mapping.
160 */
161typedef 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 */
184typedef 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
196typedef 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 */
207typedef 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 align;
219 uint32 blocksz;
220 uint32 largesz;
221 uint32 walsz;
222 uint32 walseg;
223 uint32 ident;
224 uint32 index;
225 uint32 toast;
226 uint32 large_object;
227 bool date_is_int;
228 bool float8_pass_by_value;
229 bool data_checksum_version;
230} ControlData;
231
232/*
233 * Enumeration to denote transfer modes
234 */
235typedef enum
236{
237 TRANSFER_MODE_CLONE,
238 TRANSFER_MODE_COPY,
239 TRANSFER_MODE_LINK
240} transferMode;
241
242/*
243 * Enumeration to denote pg_log modes
244 */
245typedef enum
246{
247 PG_VERBOSE,
248 PG_STATUS,
249 PG_REPORT,
250 PG_WARNING,
251 PG_FATAL
252} eLogType;
253
254
255typedef long pgpid_t;
256
257
258/*
259 * cluster
260 *
261 * information about each cluster
262 */
263typedef 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*/
285typedef 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*/
296typedef 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; /* number of processes/threads to use */
302 char *socketdir; /* directory to use for Unix sockets */
303} UserOpts;
304
305typedef struct
306{
307 char *name;
308 int dbnum;
309} LibraryInfo;
310
311/*
312 * OSInfo
313 */
314typedef struct
315{
316 const char *progname; /* complete pathname for this program */
317 char *exec_path; /* full path to my executable */
318 char *user; /* username for clusters */
319 bool user_specified; /* user specified on command-line */
320 char **old_tablespaces; /* tablespaces */
321 int num_old_tablespaces;
322 LibraryInfo *libraries; /* loadable libraries */
323 int num_libraries;
324 ClusterInfo *running_cluster;
325} OSInfo;
326
327
328/*
329 * Global variables
330 */
331extern LogOpts log_opts;
332extern UserOpts user_opts;
333extern ClusterInfo old_cluster,
334 new_cluster;
335extern OSInfo os_info;
336
337
338/* check.c */
339
340void output_check_banner(bool live_check);
341void check_and_dump_old_cluster(bool live_check);
342void check_new_cluster(void);
343void report_clusters_compatible(void);
344void issue_warnings_and_set_wal_level(void);
345void output_completion_banner(char *analyze_script_file_name,
346 char *deletion_script_file_name);
347void check_cluster_versions(void);
348void check_cluster_compatibility(bool live_check);
349void create_script_for_old_cluster_deletion(char **deletion_script_file_name);
350void create_script_for_cluster_analyze(char **analyze_script_file_name);
351
352
353/* controldata.c */
354
355void get_control_data(ClusterInfo *cluster, bool live_check);
356void check_control_data(ControlData *oldctrl, ControlData *newctrl);
357void disable_old_cluster(void);
358
359
360/* dump.c */
361
362void generate_old_dump(void);
363
364
365/* exec.c */
366
367#define EXEC_PSQL_ARGS "--echo-queries --set ON_ERROR_STOP=on --no-psqlrc --dbname=template1"
368
369bool exec_prog(const char *log_file, const char *opt_log_file,
370 bool report_error, bool exit_on_error, const char *fmt,...) pg_attribute_printf(5, 6);
371void verify_directories(void);
372bool pid_lock_file_exists(const char *datadir);
373
374
375/* file.c */
376
377void cloneFile(const char *src, const char *dst,
378 const char *schemaName, const char *relName);
379void copyFile(const char *src, const char *dst,
380 const char *schemaName, const char *relName);
381void linkFile(const char *src, const char *dst,
382 const char *schemaName, const char *relName);
383void rewriteVisibilityMap(const char *fromfile, const char *tofile,
384 const char *schemaName, const char *relName);
385void check_file_clone(void);
386void check_hard_link(void);
387
388/* fopen_priv() is no longer different from fopen() */
389#define fopen_priv(path, mode) fopen(path, mode)
390
391/* function.c */
392
393void get_loadable_libraries(void);
394void check_loadable_libraries(void);
395
396/* info.c */
397
398FileNameMap *gen_db_file_maps(DbInfo *old_db,
399 DbInfo *new_db, int *nmaps, const char *old_pgdata,
400 const char *new_pgdata);
401void get_db_and_rel_infos(ClusterInfo *cluster);
402void print_maps(FileNameMap *maps, int n,
403 const char *db_name);
404
405/* option.c */
406
407void parseCommandLine(int argc, char *argv[]);
408void adjust_data_dir(ClusterInfo *cluster);
409void get_sock_dir(ClusterInfo *cluster, bool live_check);
410
411/* relfilenode.c */
412
413void transfer_all_new_tablespaces(DbInfoArr *old_db_arr,
414 DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata);
415void transfer_all_new_dbs(DbInfoArr *old_db_arr,
416 DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata,
417 char *old_tablespace);
418
419/* tablespace.c */
420
421void init_tablespaces(void);
422
423
424/* server.c */
425
426PGconn *connectToServer(ClusterInfo *cluster, const char *db_name);
427PGresult *executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2, 3);
428
429char *cluster_conn_opts(ClusterInfo *cluster);
430
431bool start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error);
432void stop_postmaster(bool in_atexit);
433uint32 get_major_server_version(ClusterInfo *cluster);
434void check_pghost_envvar(void);
435
436
437/* util.c */
438
439char *quote_identifier(const char *s);
440int get_user_info(char **user_name_p);
441void check_ok(void);
442void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3);
443void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3);
444void pg_fatal(const char *fmt,...) pg_attribute_printf(1, 2) pg_attribute_noreturn();
445void end_progress_output(void);
446void prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
447void check_ok(void);
448unsigned int str2uint(const char *str);
449void pg_putenv(const char *var, const char *val);
450
451
452/* version.c */
453
454void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
455 bool check_mode);
456void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster);
457void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster);
458void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster,
459 bool check_mode);
460
461/* parallel.c */
462void parallel_exec_prog(const char *log_file, const char *opt_log_file,
463 const char *fmt,...) pg_attribute_printf(3, 4);
464void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
465 char *old_pgdata, char *new_pgdata,
466 char *old_tablespace);
467bool reap_child(bool wait_for_child);
468