From a50d860ae1dfca56148dd41692b963bb859bf1d6 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 1 Nov 2011 13:49:03 -0400 Subject: [PATCH] Allow pg_upgrade to upgrade an old cluster that doesn't have a 'postgres' database. --- contrib/pg_upgrade/check.c | 37 +------------------------------- contrib/pg_upgrade/function.c | 3 +-- contrib/pg_upgrade/relfilenode.c | 22 +++++++++++++------ 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c index e400814617..d32a84c635 100644 --- a/contrib/pg_upgrade/check.c +++ b/contrib/pg_upgrade/check.c @@ -14,7 +14,6 @@ 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_is_super_user(ClusterInfo *cluster); @@ -127,7 +126,6 @@ check_new_cluster(void) check_new_cluster_is_empty(); check_for_prepared_transactions(&new_cluster); - check_old_cluster_has_new_cluster_dbs(); check_loadable_libraries(); @@ -381,39 +379,6 @@ check_new_cluster_is_empty(void) } -/* - * 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. We would detect this as a database count mismatch during - * upgrade, but we want to detect it during the check phase and report - * the database name. - */ -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) - { - if (strcmp(new_cluster.dbarr.dbs[new_dbnum].db_name, "postgres") == 0) - pg_log(PG_FATAL, "The \"postgres\" database must exist in the old cluster\n"); - else - pg_log(PG_FATAL, "New cluster database \"%s\" does not exist in the old cluster\n", - new_cluster.dbarr.dbs[new_dbnum].db_name); - } - } -} - - /* * create_script_for_old_cluster_deletion() * @@ -462,7 +427,7 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name) fprintf(script, RM_CMD " %s%s/PG_VERSION\n", os_info.tablespaces[tblnum], old_cluster.tablespace_suffix); - for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++) { fprintf(script, RMDIR_CMD " %s%s/%d\n", os_info.tablespaces[tblnum], old_cluster.tablespace_suffix, diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c index 0f8008951a..b154f033e6 100644 --- a/contrib/pg_upgrade/function.c +++ b/contrib/pg_upgrade/function.c @@ -132,8 +132,7 @@ get_loadable_libraries(void) int totaltups; int dbnum; - ress = (PGresult **) - pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *)); + ress = (PGresult **) pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *)); totaltups = 0; /* Fetch all library names, removing duplicates within each DB */ diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c index 1aefd337f1..ad893be1c7 100644 --- a/contrib/pg_upgrade/relfilenode.c +++ b/contrib/pg_upgrade/relfilenode.c @@ -34,22 +34,30 @@ const char * transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata) { - int dbnum; + int old_dbnum, new_dbnum; const char *msg = NULL; prep_status("Restoring user relation files\n"); - if (old_db_arr->ndbs != new_db_arr->ndbs) - pg_log(PG_FATAL, "old and new clusters have a different number of databases\n"); - - for (dbnum = 0; dbnum < old_db_arr->ndbs; dbnum++) + /* Scan the old cluster databases and transfer their files */ + for (old_dbnum = new_dbnum = 0; + old_dbnum < old_db_arr->ndbs && new_dbnum < new_db_arr->ndbs; + old_dbnum++, new_dbnum++) { - DbInfo *old_db = &old_db_arr->dbs[dbnum]; - DbInfo *new_db = &new_db_arr->dbs[dbnum]; + DbInfo *old_db = &old_db_arr->dbs[old_dbnum]; + DbInfo *new_db = &new_db_arr->dbs[new_dbnum]; FileNameMap *mappings; int n_maps; pageCnvCtx *pageConverter = NULL; + /* + * Advance past any databases that exist in the new cluster + * but not in the old, e.g. "postgres". + */ + while (strcmp(old_db->db_name, new_db->db_name) != 0 && + new_dbnum < new_db_arr->ndbs) + new_db = &new_db_arr->dbs[++new_dbnum]; + if (strcmp(old_db->db_name, new_db->db_name) != 0) pg_log(PG_FATAL, "old and new databases have different names: old \"%s\", new \"%s\"\n", old_db->db_name, new_db->db_name); -- 2.40.0