In pg_upgrade, only lock the old cluster if link mode is used, and do it

right after we restore the schema (a common failure point), and right
before we do the link operation.

Per suggesgtions from Robert and ^!C^!^@lvaro
This commit is contained in:
Bruce Momjian 2012-03-05 21:19:54 -05:00
parent 6b289942bf
commit 2127aac6ef
5 changed files with 37 additions and 35 deletions

View File

@ -148,9 +148,8 @@ report_clusters_compatible(void)
} }
pg_log(PG_REPORT, "\n" pg_log(PG_REPORT, "\n"
"If pg_upgrade fails after this point, you must re-initdb the new cluster\n" "If pg_upgrade fails after this point, you must re-initdb the\n"
"before continuing. You will also need to remove the \".old\" suffix from\n" "new cluster before continuing.\n");
"%s/global/pg_control.old.\n", old_cluster.pgdata);
} }
@ -198,8 +197,8 @@ output_completion_banner(char *deletion_script_file_name)
/* Did we copy the free space files? */ /* Did we copy the free space files? */
if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
pg_log(PG_REPORT, pg_log(PG_REPORT,
"Optimizer statistics are not transferred by pg_upgrade so consider\n" "Optimizer statistics are not transferred by pg_upgrade so\n"
"running:\n" "consider running:\n"
" vacuumdb --all --analyze-only\n" " vacuumdb --all --analyze-only\n"
"on the newly-upgraded cluster.\n\n"); "on the newly-upgraded cluster.\n\n");
else else

View File

@ -516,11 +516,12 @@ check_control_data(ControlData *oldctrl,
void void
rename_old_pg_control(void) disable_old_cluster(void)
{ {
char old_path[MAXPGPATH], char old_path[MAXPGPATH],
new_path[MAXPGPATH]; new_path[MAXPGPATH];
/* rename pg_control so old server cannot be accidentally started */
prep_status("Adding \".old\" suffix to old global/pg_control"); prep_status("Adding \".old\" suffix to old global/pg_control");
snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata); snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
@ -528,4 +529,10 @@ rename_old_pg_control(void)
if (pg_mv_file(old_path, new_path) != 0) if (pg_mv_file(old_path, new_path) != 0)
pg_log(PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path); pg_log(PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path);
check_ok(); check_ok();
pg_log(PG_REPORT, "\n"
"If you want to start the old cluster, you will need to remove\n"
"the \".old\" suffix from %s/global/pg_control.old.\n"
"Because \"link\" mode was used, the old cluster cannot be safely\n"
"started once the new cluster has been started.\n\n", old_cluster.pgdata);
} }

View File

@ -43,7 +43,6 @@
#include <langinfo.h> #include <langinfo.h>
#endif #endif
static void disable_old_cluster(void);
static void prepare_new_cluster(void); static void prepare_new_cluster(void);
static void prepare_new_databases(void); static void prepare_new_databases(void);
static void create_new_objects(void); static void create_new_objects(void);
@ -87,7 +86,6 @@ main(int argc, char **argv)
pg_log(PG_REPORT, "\nPerforming Upgrade\n"); pg_log(PG_REPORT, "\nPerforming Upgrade\n");
pg_log(PG_REPORT, "------------------\n"); pg_log(PG_REPORT, "------------------\n");
disable_old_cluster();
prepare_new_cluster(); prepare_new_cluster();
stop_postmaster(false); stop_postmaster(false);
@ -109,6 +107,16 @@ main(int argc, char **argv)
stop_postmaster(false); stop_postmaster(false);
/*
* Most failures happen in create_new_objects(), which has
* completed at this point. We do this here because it is just
* before linking, which will link the old and new cluster data
* files, preventing the old cluster from being safely started
* once the new cluster is started.
*/
if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
disable_old_cluster();
transfer_all_new_dbs(&old_cluster.dbarr, &new_cluster.dbarr, transfer_all_new_dbs(&old_cluster.dbarr, &new_cluster.dbarr,
old_cluster.pgdata, new_cluster.pgdata); old_cluster.pgdata, new_cluster.pgdata);
@ -176,14 +184,6 @@ setup(char *argv0, bool live_check)
} }
static void
disable_old_cluster(void)
{
/* rename pg_control so old server cannot be accidentally started */
rename_old_pg_control();
}
static void static void
prepare_new_cluster(void) prepare_new_cluster(void)
{ {

View File

@ -282,8 +282,8 @@ void create_script_for_old_cluster_deletion(char **deletion_script_file_name);
/* controldata.c */ /* controldata.c */
void get_control_data(ClusterInfo *cluster, bool live_check); void get_control_data(ClusterInfo *cluster, bool live_check);
void check_control_data(ControlData *oldctrl, void check_control_data(ControlData *oldctrl, ControlData *newctrl);
ControlData *newctrl); void disable_old_cluster(void);
/* dump.c */ /* dump.c */
@ -298,7 +298,6 @@ int exec_prog(bool throw_error, const char *cmd, ...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
void verify_directories(void); void verify_directories(void);
bool is_server_running(const char *datadir); bool is_server_running(const char *datadir);
void rename_old_pg_control(void);
/* file.c */ /* file.c */

View File

@ -182,7 +182,7 @@
<para> <para>
If you are using a version-specific installation directory, e.g. If you are using a version-specific installation directory, e.g.
<filename>/opt/PostgreSQL/8.4</>, you do not need to move the old cluster. The <filename>/opt/PostgreSQL/9.1</>, you do not need to move the old cluster. The
one-click installers all use version-specific installation directories. one-click installers all use version-specific installation directories.
</para> </para>
@ -254,7 +254,8 @@ gmake prefix=/usr/local/pgsql.new install
<para> <para>
Install any custom shared object files (or DLLs) used by the old cluster Install any custom shared object files (or DLLs) used by the old cluster
into the new cluster, e.g. <filename>pgcrypto.so</filename>, whether they are from <filename>contrib</filename> into the new cluster, e.g. <filename>pgcrypto.so</filename>,
whether they are from <filename>contrib</filename>
or some other source. Do not install the schema definitions, e.g. or some other source. Do not install the schema definitions, e.g.
<filename>pgcrypto.sql</>, because these will be upgraded from the old cluster. <filename>pgcrypto.sql</>, because these will be upgraded from the old cluster.
</para> </para>
@ -454,18 +455,14 @@ psql --username postgres --file script.sql postgres
<listitem> <listitem>
<para> <para>
If you If you ran <command>pg_upgrade</command> <emphasis>without</>
ran <command>pg_upgrade</command> <emphasis>without</> <option>--link</> <option>--link</> or did not start the new server, the
or did not start the new server, the old cluster was not old cluster was not modified except that, if linking
modified except that an <literal>.old</> suffix was appended started, a <literal>.old</> suffix was appended to
to <filename>$PGDATA/global/pg_control</> and perhaps <filename>$PGDATA/global/pg_control</>. To reuse the old
tablespace directories. To reuse the old cluster, remove cluster, possibly remove the <filename>.old</> suffix from
the <filename>.old</> suffix <filename>$PGDATA/global/pg_control</>; you can then restart the
from <filename>$PGDATA/global/pg_control</>. and, if upgrading old cluster.
to 8.4 or earlier, remove the tablespace directories created
by the upgrade and remove the <filename>.old</> suffix from
the tablespace directory names; then you can restart the old
cluster.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -582,9 +579,9 @@ psql --username postgres --file script.sql postgres
</para> </para>
<para> <para>
If you want to use link mode and you don't want your old cluster If you want to use link mode and you do not want your old cluster
to be modified when the new cluster is started, make a copy of the to be modified when the new cluster is started, make a copy of the
old cluster and upgrade that with link mode. To make a valid copy old cluster and upgrade that in link mode. To make a valid copy
of the old cluster, use <command>rsync</> to create a dirty of the old cluster, use <command>rsync</> to create a dirty
copy of the old cluster while the server is running, then shut down copy of the old cluster while the server is running, then shut down
the old server and run <command>rsync</> again to update the copy with any the old server and run <command>rsync</> again to update the copy with any