]> granicus.if.org Git - postgresql/blob - contrib/pg_upgrade/pg_upgrade.c
269f8adeb153360abc1513aab02ae512d4ad225e
[postgresql] / contrib / pg_upgrade / pg_upgrade.c
1 /*
2  *      pg_upgrade.c
3  *
4  *      main source file
5  *
6  *      Copyright (c) 2010-2012, PostgreSQL Global Development Group
7  *      contrib/pg_upgrade/pg_upgrade.c
8  */
9
10 /*
11  *      To simplify the upgrade process, we force certain system values to be
12  *      identical between old and new clusters:
13  *
14  *      We control all assignments of pg_class.oid (and relfilenode) so toast
15  *      oids are the same between old and new clusters.  This is important
16  *      because toast oids are stored as toast pointers in user tables.
17  *
18  *      FYI, while pg_class.oid and pg_class.relfilenode are intially the same
19  *      in a cluster, but they can diverge due to CLUSTER, REINDEX, or VACUUM
20  *      FULL.  The new cluster will have matching pg_class.oid and
21  *      pg_class.relfilenode values and be based on the old oid value.  This can
22  *      cause the old and new pg_class.relfilenode values to differ.  In summary,
23  *      old and new pg_class.oid and new pg_class.relfilenode will have the
24  *      same value, and old pg_class.relfilenode might differ.
25  *
26  *      We control all assignments of pg_type.oid because these oids are stored
27  *      in user composite type values.
28  *
29  *      We control all assignments of pg_enum.oid because these oids are stored
30  *      in user tables as enum values.
31  *
32  *      We control all assignments of pg_auth.oid because these oids are stored
33  *      in pg_largeobject_metadata.
34  */
35
36
37
38 #include "postgres.h"
39
40 #include "pg_upgrade.h"
41
42 #ifdef HAVE_LANGINFO_H
43 #include <langinfo.h>
44 #endif
45
46 static void prepare_new_cluster(void);
47 static void prepare_new_databases(void);
48 static void create_new_objects(void);
49 static void copy_clog_xlog_xid(void);
50 static void set_frozenxids(void);
51 static void setup(char *argv0, bool live_check);
52 static void cleanup(void);
53
54 ClusterInfo old_cluster,
55                         new_cluster;
56 OSInfo          os_info;
57
58 char *output_files[NUM_LOG_FILES] = {
59         SERVER_LOG_FILE,
60         RESTORE_LOG_FILE,
61         UTILITY_LOG_FILE,
62         INTERNAL_LOG_FILE
63 };
64
65
66 int
67 main(int argc, char **argv)
68 {
69         char       *sequence_script_file_name = NULL;
70         char       *deletion_script_file_name = NULL;
71         bool            live_check = false;
72
73         parseCommandLine(argc, argv);
74
75         adjust_data_dir(&old_cluster);
76         adjust_data_dir(&new_cluster);
77
78         output_check_banner(&live_check);
79
80         setup(argv[0], live_check);
81
82         check_cluster_versions();
83         check_cluster_compatibility(live_check);
84
85         check_old_cluster(live_check, &sequence_script_file_name);
86
87
88         /* -- NEW -- */
89         start_postmaster(&new_cluster);
90
91         check_new_cluster();
92         report_clusters_compatible();
93
94         pg_log(PG_REPORT, "\nPerforming Upgrade\n");
95         pg_log(PG_REPORT, "------------------\n");
96
97         prepare_new_cluster();
98
99         stop_postmaster(false);
100
101         /*
102          * Destructive Changes to New Cluster
103          */
104
105         copy_clog_xlog_xid();
106
107         /* New now using xids of the old system */
108
109         /* -- NEW -- */
110         start_postmaster(&new_cluster);
111
112         prepare_new_databases();
113
114         create_new_objects();
115
116         stop_postmaster(false);
117
118         /*
119          *      Most failures happen in create_new_objects(), which has
120          *      completed at this point.  We do this here because it is just
121          *      before linking, which will link the old and new cluster data
122          *      files, preventing the old cluster from being safely started
123          *      once the new cluster is started.
124          */
125         if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
126                 disable_old_cluster();
127
128         transfer_all_new_dbs(&old_cluster.dbarr, &new_cluster.dbarr,
129                                                  old_cluster.pgdata, new_cluster.pgdata);
130
131         /*
132          * Assuming OIDs are only used in system tables, there is no need to
133          * restore the OID counter because we have not transferred any OIDs from
134          * the old system, but we do it anyway just in case.  We do it late here
135          * because there is no need to have the schema load use new oids.
136          */
137         prep_status("Setting next OID for new cluster");
138         exec_prog(true, true, UTILITY_LOG_FILE,
139                           SYSTEMQUOTE "\"%s/pg_resetxlog\" -o %u \"%s\" >> \"%s\" 2>&1"
140                           SYSTEMQUOTE,
141                           new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid,
142                           new_cluster.pgdata, UTILITY_LOG_FILE);
143         check_ok();
144
145         create_script_for_old_cluster_deletion(&deletion_script_file_name);
146
147         issue_warnings(sequence_script_file_name);
148
149         pg_log(PG_REPORT, "\nUpgrade complete\n");
150         pg_log(PG_REPORT, "----------------\n");
151
152         output_completion_banner(deletion_script_file_name);
153
154         pg_free(deletion_script_file_name);
155         pg_free(sequence_script_file_name);
156
157         cleanup();
158
159         return 0;
160 }
161
162
163 static void
164 setup(char *argv0, bool live_check)
165 {
166         char            exec_path[MAXPGPATH];   /* full path to my executable */
167
168         /*
169          * make sure the user has a clean environment, otherwise, we may confuse
170          * libpq when we connect to one (or both) of the servers.
171          */
172         check_pghost_envvar();
173
174         verify_directories();
175
176         /* no postmasters should be running */
177         if (!live_check && is_server_running(old_cluster.pgdata))
178                 pg_log(PG_FATAL, "There seems to be a postmaster servicing the old cluster.\n"
179                            "Please shutdown that postmaster and try again.\n");
180
181         /* same goes for the new postmaster */
182         if (is_server_running(new_cluster.pgdata))
183                 pg_log(PG_FATAL, "There seems to be a postmaster servicing the new cluster.\n"
184                            "Please shutdown that postmaster and try again.\n");
185
186         /* get path to pg_upgrade executable */
187         if (find_my_exec(argv0, exec_path) < 0)
188                 pg_log(PG_FATAL, "Could not get path name to pg_upgrade: %s\n", getErrorText(errno));
189
190         /* Trim off program name and keep just path */
191         *last_dir_separator(exec_path) = '\0';
192         canonicalize_path(exec_path);
193         os_info.exec_path = pg_strdup(exec_path);
194 }
195
196
197 static void
198 prepare_new_cluster(void)
199 {
200         /*
201          * It would make more sense to freeze after loading the schema, but that
202          * would cause us to lose the frozenids restored by the load. We use
203          * --analyze so autovacuum doesn't update statistics later
204          */
205         prep_status("Analyzing all rows in the new cluster");
206         exec_prog(true, true, UTILITY_LOG_FILE,
207                           SYSTEMQUOTE "\"%s/vacuumdb\" --port %d --username \"%s\" "
208                           "--all --analyze %s >> \"%s\" 2>&1" SYSTEMQUOTE,
209           new_cluster.bindir, new_cluster.port, os_info.user,
210           log_opts.verbose ? "--verbose" : "", UTILITY_LOG_FILE);
211         check_ok();
212
213         /*
214          * We do freeze after analyze so pg_statistic is also frozen. template0 is
215          * not frozen here, but data rows were frozen by initdb, and we set its
216          * datfrozenxid and relfrozenxids later to match the new xid counter
217          * later.
218          */
219         prep_status("Freezing all rows on the new cluster");
220         exec_prog(true, true, UTILITY_LOG_FILE,
221                           SYSTEMQUOTE "\"%s/vacuumdb\" --port %d --username \"%s\" "
222                           "--all --freeze %s >> \"%s\" 2>&1" SYSTEMQUOTE,
223           new_cluster.bindir, new_cluster.port, os_info.user,
224           log_opts.verbose ? "--verbose" : "", UTILITY_LOG_FILE);
225         check_ok();
226
227         get_pg_database_relfilenode(&new_cluster);
228 }
229
230
231 static void
232 prepare_new_databases(void)
233 {
234         /*
235          * We set autovacuum_freeze_max_age to its maximum value so autovacuum
236          * does not launch here and delete clog files, before the frozen xids are
237          * set.
238          */
239
240         set_frozenxids();
241
242         prep_status("Creating databases in the new cluster");
243
244         /*
245          * Install support functions in the global-object restore database to
246          * preserve pg_authid.oid.  pg_dumpall uses 'template0' as its template
247          * database so objects we add into 'template1' are not propogated.  They
248          * are removed on pg_upgrade exit.
249          */
250         install_support_functions_in_new_db("template1");
251
252         /*
253          * We have to create the databases first so we can install support
254          * functions in all the other databases.  Ideally we could create the
255          * support functions in template1 but pg_dumpall creates database using
256          * the template0 template.
257          */
258         exec_prog(true, true, RESTORE_LOG_FILE,
259                           SYSTEMQUOTE "\"%s/psql\" --echo-queries "
260                           "--set ON_ERROR_STOP=on "
261                           /* --no-psqlrc prevents AUTOCOMMIT=off */
262                           "--no-psqlrc --port %d --username \"%s\" "
263                           "-f \"%s\" --dbname template1 >> \"%s\" 2>&1" SYSTEMQUOTE,
264                           new_cluster.bindir, new_cluster.port, os_info.user,
265                           GLOBALS_DUMP_FILE, RESTORE_LOG_FILE);
266         check_ok();
267
268         /* we load this to get a current list of databases */
269         get_db_and_rel_infos(&new_cluster);
270 }
271
272
273 static void
274 create_new_objects(void)
275 {
276         int                     dbnum;
277
278         prep_status("Adding support functions to new cluster");
279
280         for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
281         {
282                 DbInfo     *new_db = &new_cluster.dbarr.dbs[dbnum];
283
284                 /* skip db we already installed */
285                 if (strcmp(new_db->db_name, "template1") != 0)
286                         install_support_functions_in_new_db(new_db->db_name);
287         }
288         check_ok();
289
290         prep_status("Restoring database schema to new cluster");
291         exec_prog(true, true, RESTORE_LOG_FILE,
292                           SYSTEMQUOTE "\"%s/psql\" --echo-queries "
293                           "--set ON_ERROR_STOP=on "
294                           "--no-psqlrc --port %d --username \"%s\" "
295                           "-f \"%s\" --dbname template1 >> \"%s\" 2>&1" SYSTEMQUOTE,
296                           new_cluster.bindir, new_cluster.port, os_info.user,
297                           DB_DUMP_FILE, RESTORE_LOG_FILE);
298         check_ok();
299
300         /* regenerate now that we have objects in the databases */
301         get_db_and_rel_infos(&new_cluster);
302
303         uninstall_support_functions_from_new_cluster();
304 }
305
306
307 static void
308 copy_clog_xlog_xid(void)
309 {
310         char            old_clog_path[MAXPGPATH];
311         char            new_clog_path[MAXPGPATH];
312
313         /* copy old commit logs to new data dir */
314         prep_status("Deleting new commit clogs");
315
316         snprintf(old_clog_path, sizeof(old_clog_path), "%s/pg_clog", old_cluster.pgdata);
317         snprintf(new_clog_path, sizeof(new_clog_path), "%s/pg_clog", new_cluster.pgdata);
318         if (!rmtree(new_clog_path, true))
319                 pg_log(PG_FATAL, "could not delete directory \"%s\"\n", new_clog_path);
320         check_ok();
321
322         prep_status("Copying old commit clogs to new server");
323         exec_prog(true, false, UTILITY_LOG_FILE,
324 #ifndef WIN32
325                           SYSTEMQUOTE "%s \"%s\" \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
326                           "cp -Rf",
327 #else
328         /* flags: everything, no confirm, quiet, overwrite read-only */
329                           SYSTEMQUOTE "%s \"%s\" \"%s\\\" >> \"%s\" 2>&1" SYSTEMQUOTE,
330                           "xcopy /e /y /q /r",
331 #endif
332                           old_clog_path, new_clog_path, UTILITY_LOG_FILE);
333         check_ok();
334
335         /* set the next transaction id of the new cluster */
336         prep_status("Setting next transaction ID for new cluster");
337         exec_prog(true, true, UTILITY_LOG_FILE,
338                           SYSTEMQUOTE
339                           "\"%s/pg_resetxlog\" -f -x %u \"%s\" >> \"%s\" 2>&1"
340                           SYSTEMQUOTE, new_cluster.bindir,
341                           old_cluster.controldata.chkpnt_nxtxid,
342                           new_cluster.pgdata, UTILITY_LOG_FILE);
343         check_ok();
344
345         /* now reset the wal archives in the new cluster */
346         prep_status("Resetting WAL archives");
347         exec_prog(true, true, UTILITY_LOG_FILE,
348                           SYSTEMQUOTE
349                           "\"%s/pg_resetxlog\" -l %u,%u,%u \"%s\" >> \"%s\" 2>&1"
350                           SYSTEMQUOTE, new_cluster.bindir,
351                           old_cluster.controldata.chkpnt_tli,
352                           old_cluster.controldata.logid,
353                           old_cluster.controldata.nxtlogseg,
354                           new_cluster.pgdata, UTILITY_LOG_FILE);
355         check_ok();
356 }
357
358
359 /*
360  *      set_frozenxids()
361  *
362  *      We have frozen all xids, so set relfrozenxid and datfrozenxid
363  *      to be the old cluster's xid counter, which we just set in the new
364  *      cluster.  User-table frozenxid values will be set by pg_dumpall
365  *      --binary-upgrade, but objects not set by the pg_dump must have
366  *      proper frozen counters.
367  */
368 static
369 void
370 set_frozenxids(void)
371 {
372         int                     dbnum;
373         PGconn     *conn,
374                            *conn_template1;
375         PGresult   *dbres;
376         int                     ntups;
377         int                     i_datname;
378         int                     i_datallowconn;
379
380         prep_status("Setting frozenxid counters in new cluster");
381
382         conn_template1 = connectToServer(&new_cluster, "template1");
383
384         /* set pg_database.datfrozenxid */
385         PQclear(executeQueryOrDie(conn_template1,
386                                                           "UPDATE pg_catalog.pg_database "
387                                                           "SET  datfrozenxid = '%u'",
388                                                           old_cluster.controldata.chkpnt_nxtxid));
389
390         /* get database names */
391         dbres = executeQueryOrDie(conn_template1,
392                                                           "SELECT       datname, datallowconn "
393                                                           "FROM pg_catalog.pg_database");
394
395         i_datname = PQfnumber(dbres, "datname");
396         i_datallowconn = PQfnumber(dbres, "datallowconn");
397
398         ntups = PQntuples(dbres);
399         for (dbnum = 0; dbnum < ntups; dbnum++)
400         {
401                 char       *datname = PQgetvalue(dbres, dbnum, i_datname);
402                 char       *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
403
404                 /*
405                  * We must update databases where datallowconn = false, e.g.
406                  * template0, because autovacuum increments their datfrozenxids and
407                  * relfrozenxids even if autovacuum is turned off, and even though all
408                  * the data rows are already frozen  To enable this, we temporarily
409                  * change datallowconn.
410                  */
411                 if (strcmp(datallowconn, "f") == 0)
412                         PQclear(executeQueryOrDie(conn_template1,
413                                                                           "UPDATE pg_catalog.pg_database "
414                                                                           "SET  datallowconn = true "
415                                                                           "WHERE datname = '%s'", datname));
416
417                 conn = connectToServer(&new_cluster, datname);
418
419                 /* set pg_class.relfrozenxid */
420                 PQclear(executeQueryOrDie(conn,
421                                                                   "UPDATE       pg_catalog.pg_class "
422                                                                   "SET  relfrozenxid = '%u' "
423                 /* only heap and TOAST are vacuumed */
424                                                                   "WHERE        relkind IN ('r', 't')",
425                                                                   old_cluster.controldata.chkpnt_nxtxid));
426                 PQfinish(conn);
427
428                 /* Reset datallowconn flag */
429                 if (strcmp(datallowconn, "f") == 0)
430                         PQclear(executeQueryOrDie(conn_template1,
431                                                                           "UPDATE pg_catalog.pg_database "
432                                                                           "SET  datallowconn = false "
433                                                                           "WHERE datname = '%s'", datname));
434         }
435
436         PQclear(dbres);
437
438         PQfinish(conn_template1);
439
440         check_ok();
441 }
442
443
444 static void
445 cleanup(void)
446 {
447         
448         fclose(log_opts.internal);
449
450         /* Remove dump and log files? */
451         if (!log_opts.retain)
452         {
453                 char            filename[MAXPGPATH];
454                 int i;
455
456                 for (i = 0; i < NUM_LOG_FILES; i++)
457                 {
458                         snprintf(filename, sizeof(filename), "%s", output_files[i]);
459                         unlink(filename);
460                 }
461
462                 /* remove SQL files */
463                 snprintf(filename, sizeof(filename), "%s", ALL_DUMP_FILE);
464                 unlink(filename);
465                 snprintf(filename, sizeof(filename), "%s", GLOBALS_DUMP_FILE);
466                 unlink(filename);
467                 snprintf(filename, sizeof(filename), "%s", DB_DUMP_FILE);
468                 unlink(filename);
469         }
470 }