4 * Copyright (c) 2010-2011, PostgreSQL Global Development Group
5 * contrib/pg_upgrade/pg_upgrade.h
18 /* Use port in the private/dynamic port number range */
19 #define DEF_PGUPORT 50432
21 /* Allocate for null byte */
22 #define USER_NAME_SIZE 128
24 #define MAX_STRING 1024
25 #define LINE_ALLOC 4096
26 #define QUERY_ALLOC 8192
28 #define MIGRATOR_API_VERSION 1
30 #define MESSAGE_WIDTH "60"
32 #define OVERWRITE_MESSAGE " %-" MESSAGE_WIDTH "." MESSAGE_WIDTH "s\r"
33 #define GET_MAJOR_VERSION(v) ((v) / 100)
35 #define ALL_DUMP_FILE "pg_upgrade_dump_all.sql"
36 /* contains both global db information and CREATE DATABASE commands */
37 #define GLOBALS_DUMP_FILE "pg_upgrade_dump_globals.sql"
38 #define DB_DUMP_FILE "pg_upgrade_dump_db.sql"
41 #define pg_copy_file copy_file
42 #define pg_mv_file rename
43 #define pg_link_file link
44 #define RM_CMD "rm -f"
45 #define RMDIR_CMD "rm -rf"
46 #define SCRIPT_EXT "sh"
48 #define pg_copy_file CopyFile
49 #define pg_mv_file pgrename
50 #define pg_link_file win32_pghardlink
51 #define sleep(x) Sleep(x * 1000)
52 #define RM_CMD "DEL /q"
53 #define RMDIR_CMD "RMDIR /s/q"
54 #define SCRIPT_EXT "bat"
55 #define EXE_EXT ".exe"
58 #define CLUSTER_NAME(cluster) ((cluster) == &old_cluster ? "old" : \
59 (cluster) == &new_cluster ? "new" : "none")
61 #define atooid(x) ((Oid) strtoul((x), NULL, 10))
63 /* OID system catalog preservation added during PG 9.0 development */
64 #define TABLE_SPACE_SUBDIRS_CAT_VER 201001111
65 /* postmaster/postgres -b (binary_upgrade) flag added during PG 9.1 development */
66 #define BINARY_UPGRADE_SERVER_FLAG_CAT_VER 201104251
69 * Each relation is represented by a relinfo structure.
73 char nspname[NAMEDATALEN]; /* namespace name */
74 char relname[NAMEDATALEN]; /* relation name */
75 Oid reloid; /* relation oid */
76 Oid relfilenode; /* relation relfile node */
77 char tablespace[MAXPGPATH]; /* relations tablespace path */
87 * The following structure represents a relation mapping.
91 char old_dir[MAXPGPATH];
92 char new_dir[MAXPGPATH];
95 * old/new relfilenodes might differ for pg_largeobject(_metadata) indexes
96 * due to VACUUM FULL or REINDEX. Other relfilenodes are preserved.
100 /* the rest are used only for logging and error reporting */
101 char nspname[NAMEDATALEN]; /* namespaces */
102 char relname[NAMEDATALEN];
106 * Structure to store database information
110 Oid db_oid; /* oid of the database */
111 char db_name[NAMEDATALEN]; /* database name */
112 char db_tblspace[MAXPGPATH]; /* database default tablespace path */
113 RelInfoArr rel_arr; /* array of all user relinfos */
118 DbInfo *dbs; /* array of db infos */
119 int ndbs; /* number of db infos */
123 * The following structure is used to hold pg_control information.
124 * Rather than using the backend's control structure we use our own
125 * structure to avoid pg_control version issues between releases.
134 uint32 chkpnt_nxtxid;
135 uint32 chkpnt_nxtoid;
145 bool float8_pass_by_value;
152 * Enumeration to denote link modes
161 * Enumeration to denote pg_log modes
173 typedef long pgpid_t;
179 * information about each cluster
183 ControlData controldata; /* pg_control information */
184 DbInfoArr dbarr; /* dbinfos array */
185 char *pgdata; /* pathname for cluster's $PGDATA directory */
186 char *bindir; /* pathname for cluster's executable directory */
187 unsigned short port; /* port number where postmaster is waiting */
188 uint32 major_version; /* PG_VERSION of cluster */
189 char major_version_str[64]; /* string PG_VERSION of cluster */
190 uint32 bin_version; /* version returned from pg_ctl */
191 Oid pg_database_oid; /* OID of pg_database relation */
192 char *tablespace_suffix; /* directory specification */
201 char *filename; /* name of log file (may be /dev/null) */
202 FILE *fd; /* log FILE */
203 bool debug; /* TRUE -> log more information */
204 FILE *debug_fd; /* debug-level log FILE */
205 bool verbose; /* TRUE -> be verbose in messages */
214 bool check; /* TRUE -> ask user for permission to make
216 transferMode transfer_mode; /* copy files or link them? */
225 const char *progname; /* complete pathname for this program */
226 char *exec_path; /* full path to my executable */
227 char *user; /* username for clusters */
228 char cwd[MAXPGPATH]; /* current working directory, used for output */
229 char **tablespaces; /* tablespaces */
231 char **libraries; /* loadable libraries */
233 ClusterInfo *running_cluster;
240 extern LogOpts log_opts;
241 extern UserOpts user_opts;
242 extern ClusterInfo old_cluster,
244 extern OSInfo os_info;
245 extern char scandir_file_pattern[];
250 void output_check_banner(bool *live_check);
251 void check_old_cluster(bool live_check,
252 char **sequence_script_file_name);
253 void check_new_cluster(void);
254 void report_clusters_compatible(void);
255 void issue_warnings(char *sequence_script_file_name);
256 void output_completion_banner(char *deletion_script_file_name);
257 void check_cluster_versions(void);
258 void check_cluster_compatibility(bool live_check);
259 void create_script_for_old_cluster_deletion(char **deletion_script_file_name);
264 void get_control_data(ClusterInfo *cluster, bool live_check);
265 void check_control_data(ControlData *oldctrl,
266 ControlData *newctrl);
271 void generate_old_dump(void);
272 void split_old_dump(void);
277 int exec_prog(bool throw_error,
278 const char *cmd,...);
279 void verify_directories(void);
280 bool is_server_running(const char *datadir);
281 void rename_old_pg_control(void);
286 #ifdef PAGE_CONVERSION
287 typedef const char *(*pluginStartup) (uint16 migratorVersion,
288 uint16 *pluginVersion, uint16 newPageVersion,
289 uint16 oldPageVersion, void **pluginData);
290 typedef const char *(*pluginConvertFile) (void *pluginData,
291 const char *dstName, const char *srcName);
292 typedef const char *(*pluginConvertPage) (void *pluginData,
293 const char *dstPage, const char *srcPage);
294 typedef const char *(*pluginShutdown) (void *pluginData);
298 uint16 oldPageVersion; /* Page layout version of the old cluster */
299 uint16 newPageVersion; /* Page layout version of the new cluster */
300 uint16 pluginVersion; /* API version of converter plugin */
301 void *pluginData; /* Plugin data (set by plugin) */
302 pluginStartup startup; /* Pointer to plugin's startup function */
303 pluginConvertFile convertFile; /* Pointer to plugin's file converter
305 pluginConvertPage convertPage; /* Pointer to plugin's page converter
307 pluginShutdown shutdown; /* Pointer to plugin's shutdown function */
310 const char *setupPageConverter(pageCnvCtx **result);
313 typedef void *pageCnvCtx;
316 int dir_matching_filenames(const struct dirent * scan_ent);
317 int pg_scandir(const char *dirname, struct dirent *** namelist,
318 int (*selector) (const struct dirent *));
319 const char *copyAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
320 const char *dst, bool force);
321 const char *linkAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
324 void check_hard_link(void);
328 void install_support_functions_in_new_db(const char *db_name);
329 void uninstall_support_functions_from_new_cluster(void);
330 void get_loadable_libraries(void);
331 void check_loadable_libraries(void);
335 FileNameMap *gen_db_file_maps(DbInfo *old_db,
336 DbInfo *new_db, int *nmaps, const char *old_pgdata,
337 const char *new_pgdata);
338 void get_db_and_rel_infos(ClusterInfo *cluster);
339 void free_db_and_rel_infos(DbInfoArr *db_arr);
340 void print_maps(FileNameMap *maps, int n,
341 const char *db_name);
345 void parseCommandLine(int argc, char *argv[]);
349 void get_pg_database_relfilenode(ClusterInfo *cluster);
350 const char *transfer_all_new_dbs(DbInfoArr *olddb_arr,
351 DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata);
356 void init_tablespaces(void);
361 PGconn *connectToServer(ClusterInfo *cluster, const char *db_name);
362 PGresult *executeQueryOrDie(PGconn *conn, const char *fmt,...);
364 void start_postmaster(ClusterInfo *cluster);
365 void stop_postmaster(bool fast);
366 uint32 get_major_server_version(ClusterInfo *cluster);
367 void check_pghost_envvar(void);
372 char *quote_identifier(const char *s);
373 int get_user_info(char **user_name);
375 void report_status(eLogType type, const char *fmt,...);
376 void pg_log(eLogType type, char *fmt,...);
377 void prep_status(const char *fmt,...);
379 char *pg_strdup(const char *s);
380 void *pg_malloc(int size);
381 void pg_free(void *ptr);
382 const char *getErrorText(int errNum);
383 unsigned int str2uint(const char *str);
384 void pg_putenv(const char *var, const char *val);
389 void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
392 /* version_old_8_3.c */
394 void old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster);
395 void old_8_3_check_for_tsquery_usage(ClusterInfo *cluster);
396 void old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode);
397 void old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode);
398 void old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster,
400 char *old_8_3_create_sequence_script(ClusterInfo *cluster);