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