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 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 transfer modes 235 */ 236 typedef enum 237 { 238 TRANSFER_MODE_CLONE, 239 TRANSFER_MODE_COPY, 240 TRANSFER_MODE_LINK 241 } transferMode; 242 243 /* 244 * Enumeration to denote pg_log modes 245 */ 246 typedef enum 247 { 248 PG_VERBOSE, 249 PG_STATUS, 250 PG_REPORT, 251 PG_WARNING, 252 PG_FATAL 253 } eLogType; 254 255 256 typedef long pgpid_t; 257 258 259 /* 260 * cluster 261 * 262 * information about each cluster 263 */ 264 typedef struct 265 { 266 ControlData controldata; /* pg_control information */ 267 DbInfoArr dbarr; /* dbinfos array */ 268 char *pgdata; /* pathname for cluster's $PGDATA directory */ 269 char *pgconfig; /* pathname for cluster's config file 270 * directory */ 271 char *bindir; /* pathname for cluster's executable directory */ 272 char *pgopts; /* options to pass to the server, like pg_ctl 273 * -o */ 274 char *sockdir; /* directory for Unix Domain socket, if any */ 275 unsigned short port; /* port number where postmaster is waiting */ 276 uint32 major_version; /* PG_VERSION of cluster */ 277 char major_version_str[64]; /* string PG_VERSION of cluster */ 278 uint32 bin_version; /* version returned from pg_ctl */ 279 const char *tablespace_suffix; /* directory specification */ 280 } ClusterInfo; 281 282 283 /* 284 * LogOpts 285 */ 286 typedef struct 287 { 288 FILE *internal; /* internal log FILE */ 289 bool verbose; /* true -> be verbose in messages */ 290 bool retain; /* retain log files on success */ 291 } LogOpts; 292 293 294 /* 295 * UserOpts 296 */ 297 typedef struct 298 { 299 bool check; /* true -> ask user for permission to make 300 * changes */ 301 transferMode transfer_mode; /* copy files or link them? */ 302 int jobs; /* number of processes/threads to use */ 303 char *socketdir; /* directory to use for Unix sockets */ 304 } UserOpts; 305 306 typedef struct 307 { 308 char *name; 309 int dbnum; 310 } LibraryInfo; 311 312 /* 313 * OSInfo 314 */ 315 typedef struct 316 { 317 const char *progname; /* complete pathname for this program */ 318 char *exec_path; /* full path to my executable */ 319 char *user; /* username for clusters */ 320 bool user_specified; /* user specified on command-line */ 321 char **old_tablespaces; /* tablespaces */ 322 int num_old_tablespaces; 323 LibraryInfo *libraries; /* loadable libraries */ 324 int num_libraries; 325 ClusterInfo *running_cluster; 326 } OSInfo; 327 328 329 /* 330 * Global variables 331 */ 332 extern LogOpts log_opts; 333 extern UserOpts user_opts; 334 extern ClusterInfo old_cluster, 335 new_cluster; 336 extern OSInfo os_info; 337 338 339 /* check.c */ 340 341 void output_check_banner(bool live_check); 342 void check_and_dump_old_cluster(bool live_check); 343 void check_new_cluster(void); 344 void report_clusters_compatible(void); 345 void issue_warnings_and_set_wal_level(void); 346 void output_completion_banner(char *analyze_script_file_name, 347 char *deletion_script_file_name); 348 void check_cluster_versions(void); 349 void check_cluster_compatibility(bool live_check); 350 void create_script_for_old_cluster_deletion(char **deletion_script_file_name); 351 void create_script_for_cluster_analyze(char **analyze_script_file_name); 352 353 354 /* controldata.c */ 355 356 void get_control_data(ClusterInfo *cluster, bool live_check); 357 void check_control_data(ControlData *oldctrl, ControlData *newctrl); 358 void disable_old_cluster(void); 359 360 361 /* dump.c */ 362 363 void generate_old_dump(void); 364 365 366 /* exec.c */ 367 368 #define EXEC_PSQL_ARGS "--echo-queries --set ON_ERROR_STOP=on --no-psqlrc --dbname=template1" 369 370 bool exec_prog(const char *log_file, const char *opt_log_file, 371 bool report_error, bool exit_on_error, const char *fmt,...) pg_attribute_printf(5, 6); 372 void verify_directories(void); 373 bool pid_lock_file_exists(const char *datadir); 374 375 376 /* file.c */ 377 378 void cloneFile(const char *src, const char *dst, 379 const char *schemaName, const char *relName); 380 void copyFile(const char *src, const char *dst, 381 const char *schemaName, const char *relName); 382 void linkFile(const char *src, const char *dst, 383 const char *schemaName, const char *relName); 384 void rewriteVisibilityMap(const char *fromfile, const char *tofile, 385 const char *schemaName, const char *relName); 386 void check_file_clone(void); 387 void check_hard_link(void); 388 389 /* fopen_priv() is no longer different from fopen() */ 390 #define fopen_priv(path, mode) fopen(path, mode) 391 392 /* function.c */ 393 394 void get_loadable_libraries(void); 395 void check_loadable_libraries(void); 396 397 /* info.c */ 398 399 FileNameMap *gen_db_file_maps(DbInfo *old_db, 400 DbInfo *new_db, int *nmaps, const char *old_pgdata, 401 const char *new_pgdata); 402 void get_db_and_rel_infos(ClusterInfo *cluster); 403 void print_maps(FileNameMap *maps, int n, 404 const char *db_name); 405 406 /* option.c */ 407 408 void parseCommandLine(int argc, char *argv[]); 409 void adjust_data_dir(ClusterInfo *cluster); 410 void get_sock_dir(ClusterInfo *cluster, bool live_check); 411 412 /* relfilenode.c */ 413 414 void transfer_all_new_tablespaces(DbInfoArr *old_db_arr, 415 DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata); 416 void transfer_all_new_dbs(DbInfoArr *old_db_arr, 417 DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, 418 char *old_tablespace); 419 420 /* tablespace.c */ 421 422 void init_tablespaces(void); 423 424 425 /* server.c */ 426 427 PGconn *connectToServer(ClusterInfo *cluster, const char *db_name); 428 PGresult *executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2, 3); 429 430 char *cluster_conn_opts(ClusterInfo *cluster); 431 432 bool start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error); 433 void stop_postmaster(bool in_atexit); 434 uint32 get_major_server_version(ClusterInfo *cluster); 435 void check_pghost_envvar(void); 436 437 438 /* util.c */ 439 440 char *quote_identifier(const char *s); 441 int get_user_info(char **user_name_p); 442 void check_ok(void); 443 void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3); 444 void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3); 445 void pg_fatal(const char *fmt,...) pg_attribute_printf(1, 2) pg_attribute_noreturn(); 446 void end_progress_output(void); 447 void prep_status(const char *fmt,...) pg_attribute_printf(1, 2); 448 void check_ok(void); 449 unsigned int str2uint(const char *str); 450 void pg_putenv(const char *var, const char *val); 451 452 453 /* version.c */ 454 455 bool check_for_data_types_usage(ClusterInfo *cluster, 456 const char *base_query, 457 const char *output_path); 458 bool check_for_data_type_usage(ClusterInfo *cluster, 459 const char *type_name, 460 const char *output_path); 461 void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, 462 bool check_mode); 463 void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster); 464 void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster); 465 void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, 466 bool check_mode); 467 468 void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster); 469 void report_extension_updates(ClusterInfo *cluster); 470 471 /* parallel.c */ 472 void parallel_exec_prog(const char *log_file, const char *opt_log_file, 473 const char *fmt,...) pg_attribute_printf(3, 4); 474 void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, 475 char *old_pgdata, char *new_pgdata, 476 char *old_tablespace); 477 bool reap_child(bool wait_for_child); 478