1 /* 2 * pg_upgrade.h 3 * 4 * Copyright (c) 2010-2018, 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