]> granicus.if.org Git - postgresql/blob - contrib/pg_upgrade/pg_upgrade.h
Remove all mentions of EnterpriseDB Advanced Server from pg_upgrade;
[postgresql] / contrib / pg_upgrade / pg_upgrade.h
1 /*
2  *      pg_upgrade.h
3  */
4
5 #include "postgres.h"
6
7 #include <unistd.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <assert.h>
11 #include <dirent.h>
12 #include <sys/stat.h>
13 #include <sys/time.h>
14 #include <sys/types.h>
15
16 #include "libpq-fe.h"
17
18 /* Allocate for null byte */
19 #define NAMEDATASIZE            (NAMEDATALEN + 1)
20
21 #define USER_NAME_SIZE          128
22
23 #define MAX_STRING                      1024
24 #define LINE_ALLOC                      4096
25 #define QUERY_ALLOC                     8192
26   
27 #define MIGRATOR_API_VERSION    1
28
29 #define MESSAGE_WIDTH           "60"
30
31 #define OVERWRITE_MESSAGE       "  %-" MESSAGE_WIDTH "." MESSAGE_WIDTH "s\r"
32 #define GET_MAJOR_VERSION(v)    ((v) / 100)
33
34 #define OUTPUT_SUBDIR           "pg_upgrade_output"
35
36 #define ALL_DUMP_FILE           "pg_upgrade_dump_all.sql"
37 /* contains both global db information and CREATE DATABASE commands */
38 #define GLOBALS_DUMP_FILE       "pg_upgrade_dump_globals.sql"
39 #define DB_DUMP_FILE            "pg_upgrade_dump_db.sql"
40
41 #ifndef WIN32
42 #define pg_copy_file            copy_file
43 #define pg_mv_file                      rename
44 #define pg_link_file            link
45 #define DEVNULL                         "/dev/null"
46 #define DEVTTY                          "/dev/tty"
47 #define RMDIR_CMD                       "rm -rf"
48 #define EXEC_EXT                        "sh"
49 #else
50 #define pg_copy_file            CopyFile
51 #define pg_mv_file                      pgrename
52 #define pg_link_file            win32_pghardlink
53 #define EXE_EXT                         ".exe"
54 #define sleep(x)                        Sleep(x * 1000)
55 #define DEVNULL "nul"
56 /* "con" does not work from the Msys 1.0.10 console (part of MinGW). */
57 #define DEVTTY  "con"
58 /* from pgport */
59 extern int  pgrename(const char *from, const char *to);
60 extern int  pgunlink(const char *path);
61 #define rename(from, to)        pgrename(from, to)
62 #define unlink(path)            pgunlink(path)
63 #define RMDIR_CMD                       "RMDIR /s/q"
64 #define EXEC_EXT                        "bat"
65 #endif
66
67 #define CLUSTERNAME(cluster)    ((cluster) == CLUSTER_OLD ? "old" : "new")
68
69 /* OID system catalog preservation added during PG 9.0 development */
70 #define TABLE_SPACE_SUBDIRS     201001111
71
72 /* from pgport */
73 extern void copydir(char *fromdir, char *todir, bool recurse);
74 extern bool rmtree(const char *path, bool rmtopdir);
75
76 extern char pathSeparator;
77
78 /*
79  * Each relation is represented by a relinfo structure.
80  */
81 typedef struct
82 {
83         char            nspname[NAMEDATASIZE];          /* namespace name */
84         char            relname[NAMEDATASIZE];          /* relation name */
85         Oid                     reloid;                 /* relation oid                          */
86         Oid                     relfilenode;    /* relation relfile node         */
87         Oid                     toastrelid;             /* oid of the toast relation */
88         char            tablespace[MAXPGPATH]; /* relations tablespace path */
89 } RelInfo;
90
91 typedef struct
92 {
93         RelInfo    *rels;
94         int                     nrels;
95 } RelInfoArr;
96
97 /*
98  * The following structure represents a relation mapping.
99  */
100 typedef struct
101 {
102         Oid                     old;                    /* Relfilenode of the old relation */
103         Oid                     new;                    /* Relfilenode of the new relation */
104         char            old_file[MAXPGPATH];
105         char            new_file[MAXPGPATH];
106         char            old_nspname[NAMEDATASIZE];      /* old name of the namespace */
107         char            old_relname[NAMEDATASIZE];      /* old name of the relation */
108         char            new_nspname[NAMEDATASIZE];      /* new name of the namespace */
109         char            new_relname[NAMEDATASIZE];      /* new name of the relation */
110 } FileNameMap;
111
112 /*
113  * Structure to store database information
114  */
115 typedef struct
116 {
117         Oid                     db_oid;                 /* oid of the database */
118         char            db_name[NAMEDATASIZE];  /* database name */
119         char            db_tblspace[MAXPGPATH]; /* database default tablespace path */
120         RelInfoArr      rel_arr;                /* array of all user relinfos */
121 } DbInfo;
122
123 typedef struct
124 {
125         DbInfo     *dbs;                        /* array of db infos */
126         int                     ndbs;                   /* number of db infos */
127 } DbInfoArr;
128
129 /*
130  * The following structure is used to hold pg_control information.
131  * Rather than using the backend's control structure we use our own
132  * structure to avoid pg_control version issues between releases.
133  */
134 typedef struct
135 {
136         uint32          ctrl_ver;
137         uint32          cat_ver;
138         uint32          logid;
139         uint32          nxtlogseg;
140         uint32          chkpnt_tli;
141         uint32          chkpnt_nxtxid;
142         uint32          chkpnt_nxtoid;
143         uint32          align;
144         uint32          blocksz;
145         uint32          largesz;
146         uint32          walsz;
147         uint32          walseg;
148         uint32          ident;
149         uint32          index;
150         uint32          toast;
151         bool            date_is_int;
152         bool            float8_pass_by_value;
153         char       *lc_collate;
154         char       *lc_ctype;
155         char       *encoding;
156 } ControlData;
157
158 /*
159  * Enumeration to denote link modes
160  */
161 typedef enum
162 {
163         TRANSFER_MODE_COPY,
164         TRANSFER_MODE_LINK
165 } transferMode;
166
167 /*
168  * Enumeration to denote pg_log modes
169  */
170 typedef enum
171 {
172         PG_INFO,
173         PG_REPORT,
174         PG_WARNING,
175         PG_FATAL,
176         PG_DEBUG
177 } eLogType;
178
179 /*
180  * Enumeration to distinguish between old cluster and new cluster
181  */
182 typedef enum
183 {
184         NONE = 0,       /* used for no running servers */
185         CLUSTER_OLD,
186         CLUSTER_NEW
187 } Cluster;
188
189 typedef long pgpid_t;
190
191
192 /*
193  * cluster
194  *
195  *      information about each cluster
196  */
197 typedef struct
198 {
199         ControlData controldata;        /* pg_control information */
200         DbInfoArr       dbarr;          /* dbinfos array */
201         char       *pgdata;             /* pathname for cluster's $PGDATA directory */
202         char       *bindir;             /* pathname for cluster's executable directory */
203         unsigned short port;    /* port number where postmaster is waiting */
204         uint32          major_version;          /* PG_VERSION of cluster */
205         char       *major_version_str;  /* string PG_VERSION of cluster */
206         Oid                     pg_database_oid;                /* OID of pg_database relation */
207         char       *libpath;    /* pathname for cluster's pkglibdir */
208         char       *tablespace_suffix;  /* directory specification */
209 } ClusterInfo;
210
211
212 /*
213  * migratorContext
214  *
215  *      We create a migratorContext object to store all of the information
216  *      that we need to migrate a single cluster.
217  */
218 typedef struct
219 {
220         ClusterInfo             old, new;       /* old and new cluster information */
221         const char *progname;           /* complete pathname for this program */
222         char       *exec_path;          /* full path to my executable */
223         char       *user;                       /* username for clusters */
224         char            home_dir[MAXPGPATH];    /* name of user's home directory */
225         char            output_dir[MAXPGPATH];  /* directory for pg_upgrade output */
226         char      **tablespaces;        /* tablespaces */
227         int                     num_tablespaces;
228         char      **libraries;          /* loadable libraries */
229         int                     num_libraries;
230         pgpid_t         postmasterPID;  /* PID of currently running postmaster */
231         Cluster         running_cluster;
232
233         char       *logfile;            /* name of log file (may be /dev/null) */
234         FILE       *log_fd;                     /* log FILE */
235         FILE       *debug_fd;           /* debug-level log FILE */
236         bool            check;                  /* TRUE -> ask user for permission to make
237                                                                  * changes */
238         bool            verbose;                /* TRUE -> be verbose in messages */
239         bool            debug;                  /* TRUE -> log more information */
240         transferMode    transfer_mode;          /* copy files or link them? */
241 } migratorContext;
242
243
244 /*
245  * Global variables
246  */
247 char            scandir_file_pattern[MAXPGPATH];
248
249
250 /* check.c */
251
252 void            output_check_banner(migratorContext *ctx, bool *live_check);
253 void            check_old_cluster(migratorContext *ctx, bool live_check,
254                                                                 char **sequence_script_file_name);
255 void            check_new_cluster(migratorContext *ctx);
256 void            report_clusters_compatible(migratorContext *ctx);
257 void            issue_warnings(migratorContext *ctx,
258                                                    char *sequence_script_file_name);
259 void            output_completion_banner(migratorContext *ctx,
260                                                                 char *deletion_script_file_name);
261 void            check_cluster_versions(migratorContext *ctx);
262 void            check_cluster_compatibility(migratorContext *ctx, bool live_check);
263 void            create_script_for_old_cluster_deletion(migratorContext *ctx,
264                                                                 char **deletion_script_file_name);
265
266
267 /* controldata.c */
268
269 void            get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check);
270 void            check_control_data(migratorContext *ctx, ControlData *oldctrl,
271                                    ControlData *newctrl);
272
273
274 /* dump.c */
275
276 void            generate_old_dump(migratorContext *ctx);
277 void            split_old_dump(migratorContext *ctx);
278
279
280 /* exec.c */
281
282 int                     exec_prog(migratorContext *ctx, bool throw_error,
283                                 const char *cmd,...);
284 void            verify_directories(migratorContext *ctx);
285 bool            is_server_running(migratorContext *ctx, const char *datadir);
286 void            rename_old_pg_control(migratorContext *ctx);
287
288
289 /* file.c */
290
291 #ifdef PAGE_CONVERSION
292 typedef const char *(*pluginStartup) (uint16 migratorVersion,
293                                                                 uint16 *pluginVersion, uint16 newPageVersion,
294                                                                    uint16 oldPageVersion, void **pluginData);
295 typedef const char *(*pluginConvertFile) (void *pluginData,
296                                                                    const char *dstName, const char *srcName);
297 typedef const char *(*pluginConvertPage) (void *pluginData,
298                                                                    const char *dstPage, const char *srcPage);
299 typedef const char *(*pluginShutdown) (void *pluginData);
300
301 typedef struct
302 {
303         uint16          oldPageVersion;         /* Page layout version of the old
304                                                                          * cluster               */
305         uint16          newPageVersion;         /* Page layout version of the new
306                                                                          * cluster               */
307         uint16          pluginVersion;  /* API version of converter plugin */
308         void       *pluginData; /* Plugin data (set by plugin) */
309         pluginStartup startup;  /* Pointer to plugin's startup function */
310         pluginConvertFile convertFile;  /* Pointer to plugin's file converter
311                                                                                  * function */
312         pluginConvertPage convertPage;  /* Pointer to plugin's page converter
313                                                                                  * function */
314         pluginShutdown shutdown;        /* Pointer to plugin's shutdown function */
315 } pageCnvCtx;
316
317 const char *setupPageConverter(migratorContext *ctx, pageCnvCtx **result);
318
319 #else
320 /* dummy */
321 typedef void *pageCnvCtx;
322 #endif
323
324 int                     dir_matching_filenames(const struct dirent *scan_ent);
325 int                     pg_scandir(migratorContext *ctx, const char *dirname,
326                                            struct dirent ***namelist,
327                                            int (*selector) (const struct dirent *));
328 const char *copyAndUpdateFile(migratorContext *ctx,
329                                   pageCnvCtx *pageConverter, const char *src,
330                                   const char *dst, bool force);
331 const char *linkAndUpdateFile(migratorContext *ctx,
332                                 pageCnvCtx *pageConverter, const char *src, const char *dst);
333
334 void            check_hard_link(migratorContext *ctx);
335
336 /* function.c */
337
338 void            install_support_functions(migratorContext *ctx);
339 void            uninstall_support_functions(migratorContext *ctx);
340 void            get_loadable_libraries(migratorContext *ctx);
341 void            check_loadable_libraries(migratorContext *ctx);
342
343 /* info.c */
344
345 FileNameMap *gen_db_file_maps(migratorContext *ctx, DbInfo *old_db,
346                                 DbInfo *new_db, int *nmaps, const char *old_pgdata,
347                                 const char *new_pgdata);
348 void            get_db_and_rel_infos(migratorContext *ctx, DbInfoArr *db_arr,
349                         Cluster whichCluster);
350 DbInfo     *dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name);
351 void            dbarr_free(DbInfoArr *db_arr);
352 void            print_maps(migratorContext *ctx, FileNameMap *maps, int n,
353                                 const char *dbName);
354
355 /* option.c */
356
357 void            parseCommandLine(migratorContext *ctx, int argc, char *argv[]);
358
359 /* relfilenode.c */
360
361 void            get_pg_database_relfilenode(migratorContext *ctx, Cluster whichCluster);
362 const char *transfer_all_new_dbs(migratorContext *ctx, DbInfoArr *olddb_arr,
363                                    DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata);
364
365
366 /* tablespace.c */
367
368 void            init_tablespaces(migratorContext *ctx);
369
370
371 /* server.c */
372
373 PGconn          *connectToServer(migratorContext *ctx, const char *db_name,
374                                 Cluster whichCluster);
375 PGresult        *executeQueryOrDie(migratorContext *ctx, PGconn *conn,
376                                   const char *fmt,...);
377
378 void            start_postmaster(migratorContext *ctx, Cluster whichCluster, bool quiet);
379 void            stop_postmaster(migratorContext *ctx, bool fast, bool quiet);
380 uint32          get_major_server_version(migratorContext *ctx, char **verstr,
381                                                                  Cluster whichCluster);
382 void            check_for_libpq_envvars(migratorContext *ctx);
383
384
385 /* util.c */
386
387 void            exit_nicely(migratorContext *ctx, bool need_cleanup);
388 void       *pg_malloc(migratorContext *ctx, int n);
389 void            pg_free(void *p);
390 char       *pg_strdup(migratorContext *ctx, const char *s);
391 char       *quote_identifier(migratorContext *ctx, const char *s);
392 int                     get_user_info(migratorContext *ctx, char **user_name);
393 void            check_ok(migratorContext *ctx);
394 void            report_status(migratorContext *ctx, eLogType type, const char *fmt,...);
395 void            pg_log(migratorContext *ctx, eLogType type, char *fmt,...);
396 void            prep_status(migratorContext *ctx, const char *fmt,...);
397 void            check_ok(migratorContext *ctx);
398 char       *pg_strdup(migratorContext *ctx, const char *s);
399 void       *pg_malloc(migratorContext *ctx, int size);
400 void            pg_free(void *ptr);
401 const char *getErrorText(int errNum);
402
403 /* version.c */
404
405 void            new_9_0_populate_pg_largeobject_metadata(migratorContext *ctx,
406                                                         bool check_mode, Cluster whichCluster);
407
408 /* version_old_8_3.c */
409
410 void            old_8_3_check_for_name_data_type_usage(migratorContext *ctx,
411                                                         Cluster whichCluster);
412 void            old_8_3_check_for_tsquery_usage(migratorContext *ctx,
413                                                         Cluster whichCluster);
414 void            old_8_3_check_for_isn_and_int8_passing_mismatch(migratorContext *ctx,
415                                                         Cluster whichCluster);
416 void            old_8_3_rebuild_tsvector_tables(migratorContext *ctx,
417                                                         bool check_mode, Cluster whichCluster);
418 void            old_8_3_invalidate_hash_gin_indexes(migratorContext *ctx,
419                                                         bool check_mode, Cluster whichCluster);
420 void            old_8_3_invalidate_bpchar_pattern_ops_indexes(migratorContext *ctx,
421                                                         bool check_mode, Cluster whichCluster);
422 char            *old_8_3_create_sequence_script(migratorContext *ctx,
423                                                         Cluster whichCluster);