]> granicus.if.org Git - postgresql/blob - contrib/pg_upgrade/pg_upgrade.h
In pg_upgrade, add various logging improvements:
[postgresql] / contrib / pg_upgrade / pg_upgrade.h
1 /*
2  *      pg_upgrade.h
3  *
4  *      Copyright (c) 2010-2012, PostgreSQL Global Development Group
5  *      contrib/pg_upgrade/pg_upgrade.h
6  */
7
8 #include <unistd.h>
9 #include <assert.h>
10 #include <dirent.h>
11 #include <sys/stat.h>
12 #include <sys/time.h>
13
14 #include "libpq-fe.h"
15
16 /* Use port in the private/dynamic port number range */
17 #define DEF_PGUPORT                     50432
18
19 /* Allocate for null byte */
20 #define USER_NAME_SIZE          128
21
22 #define MAX_STRING                      1024
23 #define LINE_ALLOC                      4096
24 #define QUERY_ALLOC                     8192
25
26 #define MIGRATOR_API_VERSION    1
27
28 #define MESSAGE_WIDTH           "60"
29
30 #define OVERWRITE_MESSAGE       "  %-" MESSAGE_WIDTH "." MESSAGE_WIDTH "s\r"
31 #define GET_MAJOR_VERSION(v)    ((v) / 100)
32
33 #define ALL_DUMP_FILE           "pg_upgrade_dump_all.sql"
34 /* contains both global db information and CREATE DATABASE commands */
35 #define GLOBALS_DUMP_FILE       "pg_upgrade_dump_globals.sql"
36 #define DB_DUMP_FILE            "pg_upgrade_dump_db.sql"
37
38 #define SERVER_LOG_FILE         "pg_upgrade_server.log"
39 #define RESTORE_LOG_FILE        "pg_upgrade_restore.log"
40 #define UTILITY_LOG_FILE        "pg_upgrade_utility.log"
41 #define INTERNAL_LOG_FILE       "pg_upgrade_internal.log"
42
43 #define NUM_LOG_FILES           4
44 extern char *output_files[];
45
46 /*
47  * WIN32 files do not accept writes from multiple processes
48  *
49  * On Win32, we can't send both pg_upgrade output and command output to the
50  * same file because we get the error: "The process cannot access the file
51  * because it is being used by another process." so send the pg_ctl
52  * command-line output to the utility log file on Windows, rather than
53  * into the server log file.
54  *
55  * We could use the Windows pgwin32_open() flags to allow shared file
56  * writes but is unclear how all other tools would use those flags, so
57  * we just avoid it and log a little differently on Windows;  we adjust
58  * the error message appropriately.
59  */
60 #ifndef WIN32
61 #define SERVER_LOG_FILE2        SERVER_LOG_FILE
62 #else
63 #define SERVER_LOG_FILE2        UTILITY_LOG_FILE
64 #endif
65
66 #ifndef WIN32
67 #define pg_copy_file            copy_file
68 #define pg_mv_file                      rename
69 #define pg_link_file            link
70 #define RM_CMD                          "rm -f"
71 #define RMDIR_CMD                       "rm -rf"
72 #define SCRIPT_EXT                      "sh"
73 #else
74 #define pg_copy_file            CopyFile
75 #define pg_mv_file                      pgrename
76 #define pg_link_file            win32_pghardlink
77 #define sleep(x)                        Sleep(x * 1000)
78 #define RM_CMD                          "DEL /q"
79 #define RMDIR_CMD                       "RMDIR /s/q"
80 #define SCRIPT_EXT                      "bat"
81 #define EXE_EXT                         ".exe"
82 #endif
83
84 #define CLUSTER_NAME(cluster)   ((cluster) == &old_cluster ? "old" : \
85                                                                  (cluster) == &new_cluster ? "new" : "none")
86
87 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
88
89 /* OID system catalog preservation added during PG 9.0 development */
90 #define TABLE_SPACE_SUBDIRS_CAT_VER 201001111
91 /* postmaster/postgres -b (binary_upgrade) flag added during PG 9.1 development */
92 #define BINARY_UPGRADE_SERVER_FLAG_CAT_VER 201104251
93 /*
94  *      Visibility map changed with this 9.2 commit,
95  *      8f9fe6edce358f7904e0db119416b4d1080a83aa; pick later catalog version.
96  */
97 #define VISIBILITY_MAP_CRASHSAFE_CAT_VER 201107031
98
99
100 /*
101  * Each relation is represented by a relinfo structure.
102  */
103 typedef struct
104 {
105         char            nspname[NAMEDATALEN];   /* namespace name */
106         char            relname[NAMEDATALEN];   /* relation name */
107         Oid                     reloid;                 /* relation oid */
108         Oid                     relfilenode;    /* relation relfile node */
109         char            tablespace[MAXPGPATH];  /* relations tablespace path */
110 } RelInfo;
111
112 typedef struct
113 {
114         RelInfo    *rels;
115         int                     nrels;
116 } RelInfoArr;
117
118 /*
119  * The following structure represents a relation mapping.
120  */
121 typedef struct
122 {
123         char            old_dir[MAXPGPATH];
124         char            new_dir[MAXPGPATH];
125
126         /*
127          * old/new relfilenodes might differ for pg_largeobject(_metadata) indexes
128          * due to VACUUM FULL or REINDEX.  Other relfilenodes are preserved.
129          */
130         Oid                     old_relfilenode;
131         Oid                     new_relfilenode;
132         /* the rest are used only for logging and error reporting */
133         char            nspname[NAMEDATALEN];   /* namespaces */
134         char            relname[NAMEDATALEN];
135 } FileNameMap;
136
137 /*
138  * Structure to store database information
139  */
140 typedef struct
141 {
142         Oid                     db_oid;                 /* oid of the database */
143         char            db_name[NAMEDATALEN];   /* database name */
144         char            db_tblspace[MAXPGPATH]; /* database default tablespace path */
145         RelInfoArr      rel_arr;                /* array of all user relinfos */
146 } DbInfo;
147
148 typedef struct
149 {
150         DbInfo     *dbs;                        /* array of db infos */
151         int                     ndbs;                   /* number of db infos */
152 } DbInfoArr;
153
154 /*
155  * The following structure is used to hold pg_control information.
156  * Rather than using the backend's control structure we use our own
157  * structure to avoid pg_control version issues between releases.
158  */
159 typedef struct
160 {
161         uint32          ctrl_ver;
162         uint32          cat_ver;
163         uint32          logid;
164         uint32          nxtlogseg;
165         uint32          chkpnt_tli;
166         uint32          chkpnt_nxtxid;
167         uint32          chkpnt_nxtoid;
168         uint32          align;
169         uint32          blocksz;
170         uint32          largesz;
171         uint32          walsz;
172         uint32          walseg;
173         uint32          ident;
174         uint32          index;
175         uint32          toast;
176         bool            date_is_int;
177         bool            float8_pass_by_value;
178         char       *lc_collate;
179         char       *lc_ctype;
180         char       *encoding;
181 } ControlData;
182
183 /*
184  * Enumeration to denote link modes
185  */
186 typedef enum
187 {
188         TRANSFER_MODE_COPY,
189         TRANSFER_MODE_LINK
190 } transferMode;
191
192 /*
193  * Enumeration to denote pg_log modes
194  */
195 typedef enum
196 {
197         PG_VERBOSE,
198         PG_REPORT,
199         PG_WARNING,
200         PG_FATAL
201 } eLogType;
202
203
204 typedef long pgpid_t;
205
206
207 /*
208  * cluster
209  *
210  *      information about each cluster
211  */
212 typedef struct
213 {
214         ControlData controldata;        /* pg_control information */
215         DbInfoArr       dbarr;                  /* dbinfos array */
216         char       *pgdata;                     /* pathname for cluster's $PGDATA directory */
217         char       *pgconfig;           /* pathname for cluster's config file directory */
218         char       *bindir;                     /* pathname for cluster's executable directory */
219         char       *pgopts;                     /* options to pass to the server, like pg_ctl -o */
220         unsigned short port;            /* port number where postmaster is waiting */
221         uint32          major_version;  /* PG_VERSION of cluster */
222         char            major_version_str[64];  /* string PG_VERSION of cluster */
223         uint32          bin_version;    /* version returned from pg_ctl */
224         Oid                     pg_database_oid;        /* OID of pg_database relation */
225         char       *tablespace_suffix;          /* directory specification */
226 } ClusterInfo;
227
228
229 /*
230  *      LogOpts
231 */
232 typedef struct
233 {
234         FILE       *internal;           /* internal log FILE */
235         bool            verbose;                /* TRUE -> be verbose in messages */
236         bool            retain;                 /* retain log files on success */
237 } LogOpts;
238
239
240 /*
241  *      UserOpts
242 */
243 typedef struct
244 {
245         bool            check;                  /* TRUE -> ask user for permission to make
246                                                                  * changes */
247         transferMode transfer_mode; /* copy files or link them? */
248 } UserOpts;
249
250
251 /*
252  * OSInfo
253  */
254 typedef struct
255 {
256         const char *progname;           /* complete pathname for this program */
257         char       *exec_path;          /* full path to my executable */
258         char       *user;                       /* username for clusters */
259         char      **tablespaces;        /* tablespaces */
260         int                     num_tablespaces;
261         char      **libraries;          /* loadable libraries */
262         int                     num_libraries;
263         ClusterInfo *running_cluster;
264 } OSInfo;
265
266
267 /*
268  * Global variables
269  */
270 extern LogOpts log_opts;
271 extern UserOpts user_opts;
272 extern ClusterInfo old_cluster,
273                         new_cluster;
274 extern OSInfo os_info;
275 extern char scandir_file_pattern[];
276
277
278 /* check.c */
279
280 void            output_check_banner(bool *live_check);
281 void check_old_cluster(bool live_check,
282                                   char **sequence_script_file_name);
283 void            check_new_cluster(void);
284 void            report_clusters_compatible(void);
285 void            issue_warnings(char *sequence_script_file_name);
286 void            output_completion_banner(char *deletion_script_file_name);
287 void            check_cluster_versions(void);
288 void            check_cluster_compatibility(bool live_check);
289 void            create_script_for_old_cluster_deletion(char **deletion_script_file_name);
290
291
292 /* controldata.c */
293
294 void            get_control_data(ClusterInfo *cluster, bool live_check);
295 void            check_control_data(ControlData *oldctrl, ControlData *newctrl);
296 void            disable_old_cluster(void);
297
298
299 /* dump.c */
300
301 void            generate_old_dump(void);
302 void            split_old_dump(void);
303
304
305 /* exec.c */
306
307 int exec_prog(bool throw_error, bool is_priv,
308         const char *log_file, const char *cmd, ...)
309         __attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
310 void            verify_directories(void);
311 bool            is_server_running(const char *datadir);
312
313
314 /* file.c */
315
316 #ifdef PAGE_CONVERSION
317 typedef const char *(*pluginStartup) (uint16 migratorVersion,
318                                                                 uint16 *pluginVersion, uint16 newPageVersion,
319                                                                    uint16 oldPageVersion, void **pluginData);
320 typedef const char *(*pluginConvertFile) (void *pluginData,
321                                                                    const char *dstName, const char *srcName);
322 typedef const char *(*pluginConvertPage) (void *pluginData,
323                                                                    const char *dstPage, const char *srcPage);
324 typedef const char *(*pluginShutdown) (void *pluginData);
325
326 typedef struct
327 {
328         uint16          oldPageVersion; /* Page layout version of the old cluster               */
329         uint16          newPageVersion; /* Page layout version of the new cluster               */
330         uint16          pluginVersion;  /* API version of converter plugin */
331         void       *pluginData;         /* Plugin data (set by plugin) */
332         pluginStartup startup;          /* Pointer to plugin's startup function */
333         pluginConvertFile convertFile;          /* Pointer to plugin's file converter
334                                                                                  * function */
335         pluginConvertPage convertPage;          /* Pointer to plugin's page converter
336                                                                                  * function */
337         pluginShutdown shutdown;        /* Pointer to plugin's shutdown function */
338 } pageCnvCtx;
339
340 const char *setupPageConverter(pageCnvCtx **result);
341 #else
342 /* dummy */
343 typedef void *pageCnvCtx;
344 #endif
345
346 int load_directory(const char *dirname, struct dirent ***namelist);
347 const char *copyAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
348                                   const char *dst, bool force);
349 const char *linkAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
350                                   const char *dst);
351
352 void            check_hard_link(void);
353 FILE       *fopen_priv(const char *path, const char *mode);
354
355 /* function.c */
356
357 void            install_support_functions_in_new_db(const char *db_name);
358 void            uninstall_support_functions_from_new_cluster(void);
359 void            get_loadable_libraries(void);
360 void            check_loadable_libraries(void);
361
362 /* info.c */
363
364 FileNameMap *gen_db_file_maps(DbInfo *old_db,
365                                  DbInfo *new_db, int *nmaps, const char *old_pgdata,
366                                  const char *new_pgdata);
367 void            get_db_and_rel_infos(ClusterInfo *cluster);
368 void            free_db_and_rel_infos(DbInfoArr *db_arr);
369 void print_maps(FileNameMap *maps, int n,
370                    const char *db_name);
371
372 /* option.c */
373
374 void            parseCommandLine(int argc, char *argv[]);
375 void            adjust_data_dir(ClusterInfo *cluster);
376
377 /* relfilenode.c */
378
379 void            get_pg_database_relfilenode(ClusterInfo *cluster);
380 const char *transfer_all_new_dbs(DbInfoArr *olddb_arr,
381                                    DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata);
382
383
384 /* tablespace.c */
385
386 void            init_tablespaces(void);
387
388
389 /* server.c */
390
391 PGconn     *connectToServer(ClusterInfo *cluster, const char *db_name);
392 PGresult   *executeQueryOrDie(PGconn *conn, const char *fmt, ...)
393         __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
394
395 void            start_postmaster(ClusterInfo *cluster);
396 void            stop_postmaster(bool fast);
397 uint32          get_major_server_version(ClusterInfo *cluster);
398 void            check_pghost_envvar(void);
399
400
401 /* util.c */
402
403 char       *quote_identifier(const char *s);
404 int                     get_user_info(char **user_name);
405 void            check_ok(void);
406 void            report_status(eLogType type, const char *fmt, ...)
407         __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
408 void            pg_log(eLogType type, char *fmt, ...)
409         __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
410 void            prep_status(const char *fmt, ...)
411         __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
412 void            check_ok(void);
413 char       *pg_strdup(const char *s);
414 void       *pg_malloc(int size);
415 void            pg_free(void *ptr);
416 const char *getErrorText(int errNum);
417 unsigned int str2uint(const char *str);
418 void            pg_putenv(const char *var, const char *val);
419
420
421 /* version.c */
422
423 void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
424                                                                                  bool check_mode);
425
426 /* version_old_8_3.c */
427
428 void            old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster);
429 void            old_8_3_check_for_tsquery_usage(ClusterInfo *cluster);
430 void            old_8_3_check_ltree_usage(ClusterInfo *cluster);
431 void            old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode);
432 void            old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode);
433 void old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster,
434                                                                                           bool check_mode);
435 char       *old_8_3_create_sequence_script(ClusterInfo *cluster);