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  <br...@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 ----
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to