Fix for pg_upgrade with extra new cluster databases

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Fix for pg_upgrade with extra new cluster databases
Дата
Msg-id 201104200102.p3K12gi09859@momjian.us
обсуждение исходный текст
Список pgsql-hackers
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 ----

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: Insufficient description in collation mismatch error
Следующее
От: Hiroshi Inoue
Дата:
Сообщение: Re: Re: [COMMITTERS] pgsql: setlocale() on Windows doesn't work correctly if the locale name