Header And Logo

PostgreSQL
| The world's most advanced open source database.

pg_upgrade.c

Go to the documentation of this file.
00001 /*
00002  *  pg_upgrade.c
00003  *
00004  *  main source file
00005  *
00006  *  Copyright (c) 2010-2013, PostgreSQL Global Development Group
00007  *  contrib/pg_upgrade/pg_upgrade.c
00008  */
00009 
00010 /*
00011  *  To simplify the upgrade process, we force certain system values to be
00012  *  identical between old and new clusters:
00013  *
00014  *  We control all assignments of pg_class.oid (and relfilenode) so toast
00015  *  oids are the same between old and new clusters.  This is important
00016  *  because toast oids are stored as toast pointers in user tables.
00017  *
00018  *  FYI, while pg_class.oid and pg_class.relfilenode are initially the same
00019  *  in a cluster, but they can diverge due to CLUSTER, REINDEX, or VACUUM
00020  *  FULL.  The new cluster will have matching pg_class.oid and
00021  *  pg_class.relfilenode values and be based on the old oid value.  This can
00022  *  cause the old and new pg_class.relfilenode values to differ.  In summary,
00023  *  old and new pg_class.oid and new pg_class.relfilenode will have the
00024  *  same value, and old pg_class.relfilenode might differ.
00025  *
00026  *  We control all assignments of pg_type.oid because these oids are stored
00027  *  in user composite type values.
00028  *
00029  *  We control all assignments of pg_enum.oid because these oids are stored
00030  *  in user tables as enum values.
00031  *
00032  *  We control all assignments of pg_authid.oid because these oids are stored
00033  *  in pg_largeobject_metadata.
00034  */
00035 
00036 
00037 
00038 #include "postgres_fe.h"
00039 
00040 #include "pg_upgrade.h"
00041 
00042 #ifdef HAVE_LANGINFO_H
00043 #include <langinfo.h>
00044 #endif
00045 
00046 static void prepare_new_cluster(void);
00047 static void prepare_new_databases(void);
00048 static void create_new_objects(void);
00049 static void copy_clog_xlog_xid(void);
00050 static void set_frozenxids(void);
00051 static void setup(char *argv0, bool *live_check);
00052 static void cleanup(void);
00053 
00054 ClusterInfo old_cluster,
00055             new_cluster;
00056 OSInfo      os_info;
00057 
00058 char       *output_files[] = {
00059     SERVER_LOG_FILE,
00060 #ifdef WIN32
00061     /* unique file for pg_ctl start */
00062     SERVER_START_LOG_FILE,
00063 #endif
00064     UTILITY_LOG_FILE,
00065     INTERNAL_LOG_FILE,
00066     NULL
00067 };
00068 
00069 
00070 int
00071 main(int argc, char **argv)
00072 {
00073     char       *sequence_script_file_name = NULL;
00074     char       *analyze_script_file_name = NULL;
00075     char       *deletion_script_file_name = NULL;
00076     bool        live_check = false;
00077 
00078     parseCommandLine(argc, argv);
00079 
00080     adjust_data_dir(&old_cluster);
00081     adjust_data_dir(&new_cluster);
00082 
00083     setup(argv[0], &live_check);
00084 
00085     output_check_banner(live_check);
00086 
00087     check_cluster_versions();
00088 
00089     get_sock_dir(&old_cluster, live_check);
00090     get_sock_dir(&new_cluster, false);
00091 
00092     check_cluster_compatibility(live_check);
00093 
00094     check_and_dump_old_cluster(live_check, &sequence_script_file_name);
00095 
00096 
00097     /* -- NEW -- */
00098     start_postmaster(&new_cluster, true);
00099 
00100     check_new_cluster();
00101     report_clusters_compatible();
00102 
00103     pg_log(PG_REPORT, "\nPerforming Upgrade\n");
00104     pg_log(PG_REPORT, "------------------\n");
00105 
00106     prepare_new_cluster();
00107 
00108     stop_postmaster(false);
00109 
00110     /*
00111      * Destructive Changes to New Cluster
00112      */
00113 
00114     copy_clog_xlog_xid();
00115 
00116     /* New now using xids of the old system */
00117 
00118     /* -- NEW -- */
00119     start_postmaster(&new_cluster, true);
00120 
00121     prepare_new_databases();
00122 
00123     create_new_objects();
00124 
00125     stop_postmaster(false);
00126 
00127     /*
00128      * Most failures happen in create_new_objects(), which has completed at
00129      * this point.  We do this here because it is just before linking, which
00130      * will link the old and new cluster data files, preventing the old
00131      * cluster from being safely started once the new cluster is started.
00132      */
00133     if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
00134         disable_old_cluster();
00135 
00136     transfer_all_new_tablespaces(&old_cluster.dbarr, &new_cluster.dbarr,
00137                          old_cluster.pgdata, new_cluster.pgdata);
00138 
00139     /*
00140      * Assuming OIDs are only used in system tables, there is no need to
00141      * restore the OID counter because we have not transferred any OIDs from
00142      * the old system, but we do it anyway just in case.  We do it late here
00143      * because there is no need to have the schema load use new oids.
00144      */
00145     prep_status("Setting next OID for new cluster");
00146     exec_prog(UTILITY_LOG_FILE, NULL, true,
00147               "\"%s/pg_resetxlog\" -o %u \"%s\"",
00148               new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid,
00149               new_cluster.pgdata);
00150     check_ok();
00151 
00152     prep_status("Sync data directory to disk");
00153     exec_prog(UTILITY_LOG_FILE, NULL, true,
00154               "\"%s/initdb\" --sync-only \"%s\"", new_cluster.bindir,
00155               new_cluster.pgdata);
00156     check_ok();
00157 
00158     create_script_for_cluster_analyze(&analyze_script_file_name);
00159     create_script_for_old_cluster_deletion(&deletion_script_file_name);
00160 
00161     issue_warnings(sequence_script_file_name);
00162 
00163     pg_log(PG_REPORT, "\nUpgrade Complete\n");
00164     pg_log(PG_REPORT, "----------------\n");
00165 
00166     output_completion_banner(analyze_script_file_name,
00167                              deletion_script_file_name);
00168 
00169     pg_free(analyze_script_file_name);
00170     pg_free(deletion_script_file_name);
00171     pg_free(sequence_script_file_name);
00172 
00173     cleanup();
00174 
00175     return 0;
00176 }
00177 
00178 
00179 static void
00180 setup(char *argv0, bool *live_check)
00181 {
00182     char        exec_path[MAXPGPATH];   /* full path to my executable */
00183 
00184     /*
00185      * make sure the user has a clean environment, otherwise, we may confuse
00186      * libpq when we connect to one (or both) of the servers.
00187      */
00188     check_pghost_envvar();
00189 
00190     verify_directories();
00191 
00192     /* no postmasters should be running, except for a live check */
00193     if (pid_lock_file_exists(old_cluster.pgdata))
00194     {
00195         /*
00196          *  If we have a postmaster.pid file, try to start the server.  If
00197          *  it starts, the pid file was stale, so stop the server.  If it
00198          *  doesn't start, assume the server is running.  If the pid file
00199          *  is left over from a server crash, this also allows any committed
00200          *  transactions stored in the WAL to be replayed so they are not
00201          *  lost, because WAL files are not transfered from old to new
00202          *  servers.
00203          */     
00204         if (start_postmaster(&old_cluster, false))
00205             stop_postmaster(false);
00206         else
00207         {
00208             if (!user_opts.check)
00209                 pg_log(PG_FATAL, "There seems to be a postmaster servicing the old cluster.\n"
00210                        "Please shutdown that postmaster and try again.\n");
00211             else
00212                 *live_check = true;
00213         }
00214     }
00215 
00216     /* same goes for the new postmaster */
00217     if (pid_lock_file_exists(new_cluster.pgdata))
00218     {
00219         if (start_postmaster(&new_cluster, false))
00220             stop_postmaster(false);
00221         else
00222             pg_log(PG_FATAL, "There seems to be a postmaster servicing the new cluster.\n"
00223                "Please shutdown that postmaster and try again.\n");
00224     }
00225 
00226     /* get path to pg_upgrade executable */
00227     if (find_my_exec(argv0, exec_path) < 0)
00228         pg_log(PG_FATAL, "Could not get path name to pg_upgrade: %s\n", getErrorText(errno));
00229 
00230     /* Trim off program name and keep just path */
00231     *last_dir_separator(exec_path) = '\0';
00232     canonicalize_path(exec_path);
00233     os_info.exec_path = pg_strdup(exec_path);
00234 }
00235 
00236 
00237 static void
00238 prepare_new_cluster(void)
00239 {
00240     /*
00241      * It would make more sense to freeze after loading the schema, but that
00242      * would cause us to lose the frozenids restored by the load. We use
00243      * --analyze so autovacuum doesn't update statistics later
00244      */
00245     prep_status("Analyzing all rows in the new cluster");
00246     exec_prog(UTILITY_LOG_FILE, NULL, true,
00247               "\"%s/vacuumdb\" %s --all --analyze %s",
00248               new_cluster.bindir, cluster_conn_opts(&new_cluster),
00249               log_opts.verbose ? "--verbose" : "");
00250     check_ok();
00251 
00252     /*
00253      * We do freeze after analyze so pg_statistic is also frozen. template0 is
00254      * not frozen here, but data rows were frozen by initdb, and we set its
00255      * datfrozenxid and relfrozenxids later to match the new xid counter
00256      * later.
00257      */
00258     prep_status("Freezing all rows on the new cluster");
00259     exec_prog(UTILITY_LOG_FILE, NULL, true,
00260               "\"%s/vacuumdb\" %s --all --freeze %s",
00261               new_cluster.bindir, cluster_conn_opts(&new_cluster),
00262               log_opts.verbose ? "--verbose" : "");
00263     check_ok();
00264 
00265     get_pg_database_relfilenode(&new_cluster);
00266 }
00267 
00268 
00269 static void
00270 prepare_new_databases(void)
00271 {
00272     /*
00273      * We set autovacuum_freeze_max_age to its maximum value so autovacuum
00274      * does not launch here and delete clog files, before the frozen xids are
00275      * set.
00276      */
00277 
00278     set_frozenxids();
00279 
00280     prep_status("Restoring global objects in the new cluster");
00281 
00282     /*
00283      * Install support functions in the global-object restore database to
00284      * preserve pg_authid.oid.  pg_dumpall uses 'template0' as its template
00285      * database so objects we add into 'template1' are not propogated.  They
00286      * are removed on pg_upgrade exit.
00287      */
00288     install_support_functions_in_new_db("template1");
00289 
00290     /*
00291      * We have to create the databases first so we can install support
00292      * functions in all the other databases.  Ideally we could create the
00293      * support functions in template1 but pg_dumpall creates database using
00294      * the template0 template.
00295      */
00296     exec_prog(UTILITY_LOG_FILE, NULL, true,
00297               "\"%s/psql\" " EXEC_PSQL_ARGS " %s -f \"%s\"",
00298               new_cluster.bindir, cluster_conn_opts(&new_cluster),
00299               GLOBALS_DUMP_FILE);
00300     check_ok();
00301 
00302     /* we load this to get a current list of databases */
00303     get_db_and_rel_infos(&new_cluster);
00304 }
00305 
00306 
00307 static void
00308 create_new_objects(void)
00309 {
00310     int         dbnum;
00311 
00312     prep_status("Adding support functions to new cluster");
00313 
00314     /*
00315      *  Technically, we only need to install these support functions in new
00316      *  databases that also exist in the old cluster, but for completeness
00317      *  we process all new databases.
00318      */
00319     for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
00320     {
00321         DbInfo     *new_db = &new_cluster.dbarr.dbs[dbnum];
00322 
00323         /* skip db we already installed */
00324         if (strcmp(new_db->db_name, "template1") != 0)
00325             install_support_functions_in_new_db(new_db->db_name);
00326     }
00327     check_ok();
00328 
00329     prep_status("Restoring database schemas in the new cluster\n");
00330 
00331     for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
00332     {
00333         char sql_file_name[MAXPGPATH], log_file_name[MAXPGPATH];
00334         DbInfo     *old_db = &old_cluster.dbarr.dbs[dbnum];
00335 
00336         pg_log(PG_STATUS, "%s", old_db->db_name);
00337         snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
00338         snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
00339 
00340         /*
00341          *  pg_dump only produces its output at the end, so there is little
00342          *  parallelism if using the pipe.
00343          */
00344         parallel_exec_prog(log_file_name, NULL,
00345                   "\"%s/pg_restore\" %s --exit-on-error --verbose --dbname \"%s\" \"%s\"",
00346                   new_cluster.bindir, cluster_conn_opts(&new_cluster),
00347                   old_db->db_name, sql_file_name);
00348     }
00349 
00350     /* reap all children */
00351     while (reap_child(true) == true)
00352         ;
00353 
00354     end_progress_output();
00355     check_ok();
00356 
00357     /* regenerate now that we have objects in the databases */
00358     get_db_and_rel_infos(&new_cluster);
00359 
00360     uninstall_support_functions_from_new_cluster();
00361 }
00362 
00363 /*
00364  * Delete the given subdirectory contents from the new cluster, and copy the
00365  * files from the old cluster into it.
00366  */
00367 static void
00368 copy_subdir_files(char *subdir)
00369 {
00370     char        old_path[MAXPGPATH];
00371     char        new_path[MAXPGPATH];
00372 
00373     prep_status("Deleting files from new %s", subdir);
00374 
00375     snprintf(old_path, sizeof(old_path), "%s/%s", old_cluster.pgdata, subdir);
00376     snprintf(new_path, sizeof(new_path), "%s/%s", new_cluster.pgdata, subdir);
00377     if (!rmtree(new_path, true))
00378         pg_log(PG_FATAL, "could not delete directory \"%s\"\n", new_path);
00379     check_ok();
00380 
00381     prep_status("Copying old %s to new server", subdir);
00382 
00383     exec_prog(UTILITY_LOG_FILE, NULL, true,
00384 #ifndef WIN32
00385               "cp -Rf \"%s\" \"%s\"",
00386 #else
00387     /* flags: everything, no confirm, quiet, overwrite read-only */
00388               "xcopy /e /y /q /r \"%s\" \"%s\\\"",
00389 #endif
00390               old_path, new_path);
00391 
00392     check_ok();
00393 }
00394 
00395 static void
00396 copy_clog_xlog_xid(void)
00397 {
00398     /* copy old commit logs to new data dir */
00399     copy_subdir_files("pg_clog");
00400 
00401     /* set the next transaction id of the new cluster */
00402     prep_status("Setting next transaction ID for new cluster");
00403     exec_prog(UTILITY_LOG_FILE, NULL, true,
00404               "\"%s/pg_resetxlog\" -f -x %u \"%s\"",
00405               new_cluster.bindir, old_cluster.controldata.chkpnt_nxtxid,
00406               new_cluster.pgdata);
00407     check_ok();
00408 
00409     /*
00410      * If the old server is before the MULTIXACT_FORMATCHANGE_CAT_VER change
00411      * (see pg_upgrade.h) and the new server is after, then we don't copy
00412      * pg_multixact files, but we need to reset pg_control so that the new
00413      * server doesn't attempt to read multis older than the cutoff value.
00414      */
00415     if (old_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER &&
00416         new_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER)
00417     {
00418         copy_subdir_files("pg_multixact/offsets");
00419         copy_subdir_files("pg_multixact/members");
00420         prep_status("Setting next multixact ID and offset for new cluster");
00421         /*
00422          * we preserve all files and contents, so we must preserve both "next"
00423          * counters here and the oldest multi present on system.
00424          */
00425         exec_prog(UTILITY_LOG_FILE, NULL, true,
00426                   "\"%s/pg_resetxlog\" -O %u -m %u,%u \"%s\"",
00427                   new_cluster.bindir,
00428                   old_cluster.controldata.chkpnt_nxtmxoff,
00429                   old_cluster.controldata.chkpnt_nxtmulti,
00430                   old_cluster.controldata.chkpnt_oldstMulti,
00431                   new_cluster.pgdata);
00432         check_ok();
00433     }
00434     else if (new_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER)
00435     {
00436         prep_status("Setting oldest multixact ID on new cluster");
00437         /*
00438          * We don't preserve files in this case, but it's important that the
00439          * oldest multi is set to the latest value used by the old system, so
00440          * that multixact.c returns the empty set for multis that might be
00441          * present on disk.  We set next multi to the value following that; it
00442          * might end up wrapped around (i.e. 0) if the old cluster had
00443          * next=MaxMultiXactId, but multixact.c can cope with that just fine.
00444          */
00445         exec_prog(UTILITY_LOG_FILE, NULL, true,
00446                   "\"%s/pg_resetxlog\" -m %u,%u \"%s\"",
00447                   new_cluster.bindir,
00448                   old_cluster.controldata.chkpnt_nxtmulti + 1,
00449                   old_cluster.controldata.chkpnt_nxtmulti,
00450                   new_cluster.pgdata);
00451         check_ok();
00452     }
00453 
00454     /* now reset the wal archives in the new cluster */
00455     prep_status("Resetting WAL archives");
00456     exec_prog(UTILITY_LOG_FILE, NULL, true,
00457               "\"%s/pg_resetxlog\" -l %s \"%s\"", new_cluster.bindir,
00458               old_cluster.controldata.nextxlogfile,
00459               new_cluster.pgdata);
00460     check_ok();
00461 }
00462 
00463 
00464 /*
00465  *  set_frozenxids()
00466  *
00467  *  We have frozen all xids, so set relfrozenxid and datfrozenxid
00468  *  to be the old cluster's xid counter, which we just set in the new
00469  *  cluster.  User-table frozenxid values will be set by pg_dumpall
00470  *  --binary-upgrade, but objects not set by the pg_dump must have
00471  *  proper frozen counters.
00472  */
00473 static
00474 void
00475 set_frozenxids(void)
00476 {
00477     int         dbnum;
00478     PGconn     *conn,
00479                *conn_template1;
00480     PGresult   *dbres;
00481     int         ntups;
00482     int         i_datname;
00483     int         i_datallowconn;
00484 
00485     prep_status("Setting frozenxid counters in new cluster");
00486 
00487     conn_template1 = connectToServer(&new_cluster, "template1");
00488 
00489     /* set pg_database.datfrozenxid */
00490     PQclear(executeQueryOrDie(conn_template1,
00491                               "UPDATE pg_catalog.pg_database "
00492                               "SET  datfrozenxid = '%u'",
00493                               old_cluster.controldata.chkpnt_nxtxid));
00494 
00495     /* get database names */
00496     dbres = executeQueryOrDie(conn_template1,
00497                               "SELECT   datname, datallowconn "
00498                               "FROM pg_catalog.pg_database");
00499 
00500     i_datname = PQfnumber(dbres, "datname");
00501     i_datallowconn = PQfnumber(dbres, "datallowconn");
00502 
00503     ntups = PQntuples(dbres);
00504     for (dbnum = 0; dbnum < ntups; dbnum++)
00505     {
00506         char       *datname = PQgetvalue(dbres, dbnum, i_datname);
00507         char       *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
00508 
00509         /*
00510          * We must update databases where datallowconn = false, e.g.
00511          * template0, because autovacuum increments their datfrozenxids and
00512          * relfrozenxids even if autovacuum is turned off, and even though all
00513          * the data rows are already frozen  To enable this, we temporarily
00514          * change datallowconn.
00515          */
00516         if (strcmp(datallowconn, "f") == 0)
00517             PQclear(executeQueryOrDie(conn_template1,
00518                                       "UPDATE pg_catalog.pg_database "
00519                                       "SET  datallowconn = true "
00520                                       "WHERE datname = '%s'", datname));
00521 
00522         conn = connectToServer(&new_cluster, datname);
00523 
00524         /* set pg_class.relfrozenxid */
00525         PQclear(executeQueryOrDie(conn,
00526                                   "UPDATE   pg_catalog.pg_class "
00527                                   "SET  relfrozenxid = '%u' "
00528         /* only heap, materialized view, and TOAST are vacuumed */
00529                                   "WHERE    relkind IN ('r', 'm', 't')",
00530                                   old_cluster.controldata.chkpnt_nxtxid));
00531         PQfinish(conn);
00532 
00533         /* Reset datallowconn flag */
00534         if (strcmp(datallowconn, "f") == 0)
00535             PQclear(executeQueryOrDie(conn_template1,
00536                                       "UPDATE pg_catalog.pg_database "
00537                                       "SET  datallowconn = false "
00538                                       "WHERE datname = '%s'", datname));
00539     }
00540 
00541     PQclear(dbres);
00542 
00543     PQfinish(conn_template1);
00544 
00545     check_ok();
00546 }
00547 
00548 
00549 static void
00550 cleanup(void)
00551 {
00552 
00553     fclose(log_opts.internal);
00554 
00555     /* Remove dump and log files? */
00556     if (!log_opts.retain)
00557     {
00558         int         dbnum;
00559         char      **filename;
00560 
00561         for (filename = output_files; *filename != NULL; filename++)
00562             unlink(*filename);
00563 
00564         /* remove dump files */
00565         unlink(GLOBALS_DUMP_FILE);
00566 
00567         if (old_cluster.dbarr.dbs)
00568             for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
00569             {
00570                 char sql_file_name[MAXPGPATH], log_file_name[MAXPGPATH];
00571                 DbInfo     *old_db = &old_cluster.dbarr.dbs[dbnum];
00572 
00573                 snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
00574                 unlink(sql_file_name);
00575 
00576                 snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
00577                 unlink(log_file_name);
00578             }
00579     }
00580 }