The attached, applied patch adds a check to throw a pg_upgrade error
during the check phase, rather than during the post-check upgrade phase.
Specifically, if someone removes the 'postgres' database from the old
cluster and the new cluster has a 'postgres' database, the number of
databases will not match. We actually could upgrade such a setup, but
it would violate the 1-to-1 mapping of database counts, so we throw an
error instead.
Previously they got an error during the upgrade, and not at the check
stage; PG 9.0.4 does the same.
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ It's impossible for everything to be true. +
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
new file mode 100644
index 7472440..469bbdb
*** a/contrib/pg_upgrade/check.c
--- b/contrib/pg_upgrade/check.c
***************
*** 11,17 ****
static void set_locale_and_encoding(ClusterInfo *cluster);
! static void check_new_db_is_empty(void);
static void check_locale_and_encoding(ControlData *oldctrl,
ControlData *newctrl);
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
--- 11,18 ----
static void set_locale_and_encoding(ClusterInfo *cluster);
! static void check_new_cluster_is_empty(void);
! static void check_old_cluster_has_new_cluster_dbs(void);
static void check_locale_and_encoding(ControlData *oldctrl,
ControlData *newctrl);
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
*************** check_new_cluster(void)
*** 112,118 ****
{
set_locale_and_encoding(&new_cluster);
! check_new_db_is_empty();
check_loadable_libraries();
--- 113,122 ----
{
set_locale_and_encoding(&new_cluster);
! get_db_and_rel_infos(&new_cluster);
!
! check_new_cluster_is_empty();
! check_old_cluster_has_new_cluster_dbs();
check_loadable_libraries();
*************** check_locale_and_encoding(ControlData *o
*** 341,352 ****
static void
! check_new_db_is_empty(void)
{
int dbnum;
- bool found = false;
-
- get_db_and_rel_infos(&new_cluster);
for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
{
--- 345,353 ----
static void
! check_new_cluster_is_empty(void)
{
int dbnum;
for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
{
*************** check_new_db_is_empty(void)
*** 358,372 ****
{
/* pg_largeobject and its index should be skipped */
if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
! {
! found = true;
! break;
! }
}
}
! if (found)
! pg_log(PG_FATAL, "New cluster is not empty; exiting\n");
}
--- 359,394 ----
{
/* pg_largeobject and its index should be skipped */
if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
! pg_log(PG_FATAL, "New cluster database \"%s\" is not empty\n",
! new_cluster.dbarr.dbs[dbnum].db_name);
}
}
! }
!
!
! /*
! * If someone removes the 'postgres' database from the old cluster and
! * the new cluster has a 'postgres' database, the number of databases
! * will not match. We actually could upgrade such a setup, but it would
! * violate the 1-to-1 mapping of database counts, so we throw an error
! * instead.
! */
! static void
! check_old_cluster_has_new_cluster_dbs(void)
! {
! int old_dbnum, new_dbnum;
!
! for (new_dbnum = 0; new_dbnum < new_cluster.dbarr.ndbs; new_dbnum++)
! {
! for (old_dbnum = 0; old_dbnum < old_cluster.dbarr.ndbs; old_dbnum++)
! if (strcmp(old_cluster.dbarr.dbs[old_dbnum].db_name,
! new_cluster.dbarr.dbs[new_dbnum].db_name) == 0)
! break;
! if (old_dbnum == old_cluster.dbarr.ndbs)
! pg_log(PG_FATAL, "New cluster database \"%s\" does not exist in the old cluster\n",
! new_cluster.dbarr.dbs[new_dbnum].db_name);
! }
}
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
new file mode 100644
index 6fb336c..9a0a3ac
*** a/contrib/pg_upgrade/relfilenode.c
--- b/contrib/pg_upgrade/relfilenode.c
*************** transfer_all_new_dbs(DbInfoArr *old_db_a
*** 37,48 ****
prep_status("Restoring user relation files\n");
- /*
- * If the user removed the 'postgres' database from the old cluster,
- * this will cause the database counts to not match and throw an error.
- * We could allow this to work because the new database is empty (we
- * checked), but we don't.
- */
if (old_db_arr->ndbs != new_db_arr->ndbs)
pg_log(PG_FATAL, "old and new clusters have a different number of databases\n");
--- 37,42 ----