Thread: pg_upgrade issues

pg_upgrade issues

From
Date:
PostgreSQL 9.0 beta 2
Windows XP Professional SP2

While migrating the database from 8.4 to 9.0 using pg_upgrade (now part of =
the Postgres project), the following issues came up:

1. When using the --logfile option, pg_upgrade quits with an error like thi=
s:

The process cannot access the file because it is being used by another proc=
ess.

There were problems executing ""C:\PostgreSQL\8.4\bin/pg_ctl" -l "pg_upgrad=
e.log
" -D "D:\PostgreSQL84_matlab1b" -o "-p 5432 -c autovacuum=3Doff -c autovacu=
um_free
ze_max_age=3D2000000000" start >> "pg_upgrade.log" 2>&1"

2. Although pg_upgrade has a username option, this option is not used when =
pg_dump is called, which tries to use the current logon account name as the=
 user name. As a result, pg_upgrade can only be used when the command shell=
 is launched under the postgres account. (I know that this is mentioned on =
the doc page, but this doesn't seem right).

3. The old database had the pgadmin debugger installed. The module is part =
of 8.4 and 9.0 distributions for Windows. However, pg_upgrade reported the =
following error:

ERROR:  could not load library "C:/PostgreSQL/9.0/lib/pldbgapi.dll": The sp=
ecified module could not be found.

I had to uninstall the debugger from the old database before I could procee=
d.

Re: pg_upgrade issues

From
Date:
Another issue:

4. The --link option doesn't seem to work on Windows: pg_upgrade still copi=
es data from the old cluster to the new. There doesn't appear to be a way t=
o upgrade a database on Windows without copying the entire uncompressed dat=
abase, which can be a problem where disk space is limited.

Re: pg_upgrade issues

From
Bruce Momjian
Date:
depstein@alliedtesting.com wrote:
BBBBBB> PostgreSQL 9.0 beta 2
> Windows XP Professional SP2
>
> While migrating the database from 8.4 to 9.0 using pg_upgrade (now part of the Postgres project), the following
issuescame up: 
>
> 1. When using the --logfile option, pg_upgrade quits with an error like this:
>
> The process cannot access the file because it is being used by another process.
>
> There were problems executing ""C:\PostgreSQL\8.4\bin/pg_ctl" -l "pg_upgrade.log
> " -D "D:\PostgreSQL84_matlab1b" -o "-p 5432 -c autovacuum=off -c autovacuum_free
> ze_max_age=2000000000" start >> "pg_upgrade.log" 2>&1"

Hiroshi, can you comment on the above bug report?   I was able to
reproduce this on XP.  I think we added -l for Win32 because the code
says:

    /* use -l for Win32 */
    snprintf(cmd, sizeof(cmd),
             SYSTEMQUOTE "\"%s/pg_ctl\" -l \"%s\" -D \"%s\" "

but I don't remember the details, and cvs.pgfoundry.org is down right
now.  Thanks.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +

Re: pg_upgrade issues

From
"Hiroshi Saito"
Date:
Hi.

Ooops,  I can't follow your quick thread....
sorry, It will be a weekend if allowed.

Regards,
Hiroshi Saito

----- Original Message -----
From: "Bruce Momjian" <bruce@momjian.us>


> depstein@alliedtesting.com wrote:
> BBBBBB> PostgreSQL 9.0 beta 2
>> Windows XP Professional SP2
>>
>> While migrating the database from 8.4 to 9.0 using pg_upgrade (now part of the Postgres
>> project), the following issues came up:
>>
>> 1. When using the --logfile option, pg_upgrade quits with an error like this:
>>
>> The process cannot access the file because it is being used by another process.
>>
>> There were problems executing ""C:\PostgreSQL\8.4\bin/pg_ctl" -l "pg_upgrade.log
>> " -D "D:\PostgreSQL84_matlab1b" -o "-p 5432 -c autovacuum=off -c autovacuum_free
>> ze_max_age=2000000000" start >> "pg_upgrade.log" 2>&1"
>
> Hiroshi, can you comment on the above bug report?   I was able to
> reproduce this on XP.  I think we added -l for Win32 because the code
> says:
>
>    /* use -l for Win32 */
>    snprintf(cmd, sizeof(cmd),
>             SYSTEMQUOTE "\"%s/pg_ctl\" -l \"%s\" -D \"%s\" "
>
> but I don't remember the details, and cvs.pgfoundry.org is down right
> now.  Thanks.
>
> --
>  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
>  EnterpriseDB                             http://enterprisedb.com
>
>  + None of us is going to be here forever. +

Re: pg_upgrade issues

From
Bruce Momjian
Date:
Hiroshi Saito wrote:
> Hi.
>
> Ooops,  I can't follow your quick thread....
> sorry, It will be a weekend if allowed.

I have replied and I think I have it fixed.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +

Re: pg_upgrade issues

From
Date:
Encountered another problem with pg_upgrade on Windows XP Pro:

I was trying to migrate from 8.4 to 9.0beta2 without linking, and apparentl=
y there was not enough space on the hard drive. However, pg_upgrade didn't =
report any problems, and it looked for all the world as if everything went =
well. I only found out that not all files were copied to the new cluster wh=
en vacuumdb reported missing files and when I actually compared the sizes o=
f the two clusters on the disk.

Re: pg_upgrade issues

From
Bruce Momjian
Date:
depstein@alliedtesting.com wrote:
> Encountered another problem with pg_upgrade on Windows XP Pro:
>
> I was trying to migrate from 8.4 to 9.0beta2 without linking, and
> apparently there was not enough space on the hard drive. However,
> pg_upgrade didn't report any problems, and it looked for all the world
> as if everything went well. I only found out that not all files were
> copied to the new cluster when vacuumdb reported missing files and when
> I actually compared the sizes of the two clusters on the disk.

Thank you for the clear bug report.  Magnus has diagnosed the problem,
and I am attaching the patch fix that will appear in 9.0 beta4.
Fortunately this problem only happens in copy mode, and only when the
copy fails, as you saw.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +
Index: contrib/pg_upgrade/file.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/file.c,v
retrieving revision 1.13
diff -c -c -r1.13 file.c
*** contrib/pg_upgrade/file.c    6 Jul 2010 19:18:55 -0000    1.13
--- contrib/pg_upgrade/file.c    9 Jul 2010 16:41:46 -0000
***************
*** 170,175 ****
--- 170,177 ----

          if (nbytes < 0)
          {
+             int save_errno = errno;
+
              if (buffer != NULL)
                  free(buffer);

***************
*** 179,184 ****
--- 181,187 ----
              if (dest_fd != 0)
                  close(dest_fd);

+             errno = save_errno;
              return -1;
          }

***************
*** 190,197 ****
          if (write(dest_fd, buffer, nbytes) != nbytes)
          {
              /* if write didn't set errno, assume problem is no disk space */
!             if (errno == 0)
!                 errno = ENOSPC;

              if (buffer != NULL)
                  free(buffer);
--- 193,199 ----
          if (write(dest_fd, buffer, nbytes) != nbytes)
          {
              /* if write didn't set errno, assume problem is no disk space */
!             int save_errno = errno ? errno : ENOSPC;

              if (buffer != NULL)
                  free(buffer);
***************
*** 202,207 ****
--- 204,210 ----
              if (dest_fd != 0)
                  close(dest_fd);

+             errno = save_errno;
              return -1;
          }
      }

Re: pg_upgrade issues

From
Date:
I have encountered another problem with pg_upgrade, while migrating from 8.=
4 to 9.0 (beta2, as well as beta3) on Windows XP Pro.

I have a table with a regclass column, which references other tables in the=
 same database:

CREATE TABLE common_inst.reg_asset
(
  asset_id integer NOT NULL,
  table_name regclass,
  CONSTRAINT asset_registered_pkey PRIMARY KEY (asset_id)
)

Sometimes after I migrate the database, the values in the table_name column=
 show integer numbers (e.g. '284551' for a table named 'common_inst.asset_s=
pot_equity_index') instead of table references. These numbers are the OIDs =
of the tables in the old database, but in the new database these OIDs have =
no referent.

FWIW, when looking at the pg_class entries for the referenced tables, I hav=
e noticed that in the old database the table OID and the column relfilenode=
 have different values. In the migrated database the values are the same an=
d coincide with relfilenode in the old database.

For example,

Old database:

Table name: common_inst.asset_spot_equity_index
pg_class.oid =3D 284551
pg_class.relfilenode =3D 288011

Migrated database:

Table name: common_inst.asset_spot_equity_index
pg_class.oid =3D 288011
pg_class.relfilenode =3D 288011


I am trying to obtain a binary dump of a small test database where this iss=
ue could be reproduced, but so far, no luck. At present, the least such dat=
abase is 1.5 GB compressed and contains a lot of proprietary info. I would =
welcome any suggestions on how to do this.

Thanks,
Dmitry

Re: pg_upgrade issues

From
Bruce Momjian
Date:
depstein@alliedtesting.com wrote:
> I have encountered another problem with pg_upgrade, while migrating
> from 8.4 to 9.0 (beta2, as well as beta3) on Windows XP Pro.

Wow, your testing of pg_upgrade has been excellent!  I hope you can
continue and test other areas of our system too.  I am actually curious
how you are so good at this.

> I have a table with a regclass column, which references other tables
> in the same database:
>
> CREATE TABLE common_inst.reg_asset
> (
>   asset_id integer NOT NULL,
>   table_name regclass,
>   CONSTRAINT asset_registered_pkey PRIMARY KEY (asset_id)
> )
>
> Sometimes after I migrate the database, the values in the table_name
> column show integer numbers (e.g. '284551' for a table named
> 'common_inst.asset_spot_equity_index') instead of table references.
> These numbers are the OIDs of the tables in the old database, but in
> the new database these OIDs have no referent.

Ah, I never thought of the migrations issues of user tables using the
reg* data types:

 pg_catalog | regclass                    | registered class
 pg_catalog | regconfig                   | registered text search configuration
 pg_catalog | regdictionary               | registered text search dictionary
 pg_catalog | regoper                     | registered operator
 pg_catalog | regoperator                 | registered operator (with args)
 pg_catalog | regproc                     | registered procedure
 pg_catalog | regprocedure                | registered procedure (with args)
 pg_catalog | regtype                     | registered type

In fact, I never even considered that user tables would be using these
data types.  The basic problem is that we don't preserve most of these
oids when recreating them in the new cluster --- we only preserve
pg_type.oid, pg_class.relfilenode, and pg_enum.oid.

> FWIW, when looking at the pg_class entries for the referenced tables,
> I have noticed that in the old database the table OID and the column
> relfilenode have different values. In the migrated database the values
> are the same and coincide with relfilenode in the old database.
>
> For example,
>
> Old database:
>
> Table name: common_inst.asset_spot_equity_index
> pg_class.oid = 284551
> pg_class.relfilenode = 288011
>
> Migrated database:
>
> Table name: common_inst.asset_spot_equity_index
> pg_class.oid = 288011
> pg_class.relfilenode = 288011
>
>
> I am trying to obtain a binary dump of a small test database where this
> issue could be reproduced, but so far, no luck. At present, the least
> such database is 1.5 GB compressed and contains a lot of proprietary
> info. I would welcome any suggestions on how to do this.

Your diagnosis is 100% on target, and very perceptive.  Because we
preserve pg_class.relfilenode, if the table has not been rebuilt, for
example by CLUSTER, the old system the pg_class.oid and
pg_class.relfilenode are the same, and hence pg_class.oid is preserved
through pg_class.relfilenode during the migration.  If they are
different, e.g. they ran CLUSTER, pg_upgrade will be wrong because the
oid has changed, and you will see the errors you are reporting.

I am inclined to prevent pg_upgrade from migrating any database that
uses any of these reg* data types, and document this restriction.  I
probably could allow regtype because that pg_type is preserved.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +

Re: pg_upgrade issues

From
Bruce Momjian
Date:
Bruce Momjian wrote:
> depstein@alliedtesting.com wrote:
> > I am trying to obtain a binary dump of a small test database where this
> > issue could be reproduced, but so far, no luck. At present, the least
> > such database is 1.5 GB compressed and contains a lot of proprietary
> > info. I would welcome any suggestions on how to do this.
>
> Your diagnosis is 100% on target, and very perceptive.  Because we
> preserve pg_class.relfilenode, if the table has not been rebuilt, for
> example by CLUSTER, the old system the pg_class.oid and
> pg_class.relfilenode are the same, and hence pg_class.oid is preserved
> through pg_class.relfilenode during the migration.  If they are
> different, e.g. they ran CLUSTER, pg_upgrade will be wrong because the
> oid has changed, and you will see the errors you are reporting.
>
> I am inclined to prevent pg_upgrade from migrating any database that
> uses any of these reg* data types, and document this restriction.  I
> probably could allow regtype because that pg_type is preserved.

I have applied the attached patch to CVS HEAD and 9.0 that prevent
migration when any reg* data type is used in a user table (except
regtype because pg_type.oid is preserved).

I documented this restriction.  Thanks again for the report.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +
Index: contrib/pg_upgrade/check.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/check.c,v
retrieving revision 1.12
diff -c -c -r1.12 check.c
*** contrib/pg_upgrade/check.c    13 Jul 2010 15:56:53 -0000    1.12
--- contrib/pg_upgrade/check.c    25 Jul 2010 03:19:48 -0000
***************
*** 14,19 ****
--- 14,20 ----
  static void check_new_db_is_empty(migratorContext *ctx);
  static void check_locale_and_encoding(migratorContext *ctx, ControlData *oldctrl,
                            ControlData *newctrl);
+ static void check_for_reg_data_type_usage(migratorContext *ctx, Cluster whichCluster);


  void
***************
*** 61,71 ****
       * Check for various failure cases
       */

!     old_8_3_check_for_isn_and_int8_passing_mismatch(ctx, CLUSTER_OLD);

      /* old = PG 8.3 checks? */
      if (GET_MAJOR_VERSION(ctx->old.major_version) <= 803)
      {
          old_8_3_check_for_name_data_type_usage(ctx, CLUSTER_OLD);
          old_8_3_check_for_tsquery_usage(ctx, CLUSTER_OLD);
          if (ctx->check)
--- 62,73 ----
       * Check for various failure cases
       */

!     check_for_reg_data_type_usage(ctx, CLUSTER_OLD);

      /* old = PG 8.3 checks? */
      if (GET_MAJOR_VERSION(ctx->old.major_version) <= 803)
      {
+         old_8_3_check_for_isn_and_int8_passing_mismatch(ctx, CLUSTER_OLD);
          old_8_3_check_for_name_data_type_usage(ctx, CLUSTER_OLD);
          old_8_3_check_for_tsquery_usage(ctx, CLUSTER_OLD);
          if (ctx->check)
***************
*** 439,441 ****
--- 441,544 ----

      check_ok(ctx);
  }
+
+
+ /*
+  * check_for_reg_data_type_usage()
+  *    pg_upgrade only preserves these system values:
+  *        pg_class.relfilenode
+  *        pg_type.oid
+  *        pg_enum.oid
+  *
+  *  Most of the reg* data types reference system catalog info that is
+  *    not preserved, and hence these data types cannot be used in user
+  *    tables upgraded by pg_upgrade.
+  */
+ void
+ check_for_reg_data_type_usage(migratorContext *ctx, Cluster whichCluster)
+ {
+     ClusterInfo *active_cluster = (whichCluster == CLUSTER_OLD) ?
+     &ctx->old : &ctx->new;
+     int            dbnum;
+     FILE       *script = NULL;
+     bool        found = false;
+     char        output_path[MAXPGPATH];
+
+     prep_status(ctx, "Checking for reg* system oid user data types");
+
+     snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
+              ctx->cwd);
+
+     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
+     {
+         PGresult   *res;
+         bool        db_used = false;
+         int            ntups;
+         int            rowno;
+         int            i_nspname,
+                     i_relname,
+                     i_attname;
+         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
+         PGconn       *conn = connectToServer(ctx, active_db->db_name, whichCluster);
+
+         res = executeQueryOrDie(ctx, conn,
+                                 "SELECT n.nspname, c.relname, a.attname "
+                                 "FROM    pg_catalog.pg_class c, "
+                                 "        pg_catalog.pg_namespace n, "
+                                 "        pg_catalog.pg_attribute a "
+                                 "WHERE    c.oid = a.attrelid AND "
+                                 "        NOT a.attisdropped AND "
+                                 "        a.atttypid IN ( "
+                                 "            'pg_catalog.regproc'::pg_catalog.regtype, "
+                                 "            'pg_catalog.regprocedure'::pg_catalog.regtype, "
+                                 "            'pg_catalog.regoper'::pg_catalog.regtype, "
+                                 "            'pg_catalog.regoperator'::pg_catalog.regtype, "
+                                 "            'pg_catalog.regclass'::pg_catalog.regtype, "
+                                 /* regtype.oid is preserved, so 'regtype' is OK */
+                                 "            'pg_catalog.regconfig'::pg_catalog.regtype, "
+                                 "            'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
+                                 "        c.relnamespace = n.oid AND "
+                               "        n.nspname != 'pg_catalog' AND "
+                          "        n.nspname != 'information_schema'");
+
+         ntups = PQntuples(res);
+         i_nspname = PQfnumber(res, "nspname");
+         i_relname = PQfnumber(res, "relname");
+         i_attname = PQfnumber(res, "attname");
+         for (rowno = 0; rowno < ntups; rowno++)
+         {
+             found = true;
+             if (script == NULL && (script = fopen(output_path, "w")) == NULL)
+                 pg_log(ctx, PG_FATAL, "Could not create necessary file:  %s\n", output_path);
+             if (!db_used)
+             {
+                 fprintf(script, "Database:  %s\n", active_db->db_name);
+                 db_used = true;
+             }
+             fprintf(script, "  %s.%s.%s\n",
+                     PQgetvalue(res, rowno, i_nspname),
+                     PQgetvalue(res, rowno, i_relname),
+                     PQgetvalue(res, rowno, i_attname));
+         }
+
+         PQclear(res);
+
+         PQfinish(conn);
+     }
+
+     if (found)
+     {
+         fclose(script);
+         pg_log(ctx, PG_REPORT, "fatal\n");
+         pg_log(ctx, PG_FATAL,
+                "| Your installation contains one of the reg* data types in\n"
+                "| user tables.  These data types reference system oids that\n"
+                "| are not preserved by pg_upgrade, so this cluster cannot\n"
+                "| currently be upgraded.  You can remove the problem tables\n"
+                "| and restart the migration.  A list of the problem columns\n"
+                "| is in the file:\n"
+                "| \t%s\n\n", output_path);
+     }
+     else
+         check_ok(ctx);
+ }
Index: contrib/pg_upgrade/function.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/function.c,v
retrieving revision 1.6
diff -c -c -r1.6 function.c
*** contrib/pg_upgrade/function.c    3 Jul 2010 16:33:14 -0000    1.6
--- contrib/pg_upgrade/function.c    25 Jul 2010 03:19:48 -0000
***************
*** 253,259 ****
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!              "| Your installation uses loadable libraries that are missing\n"
               "| from the new installation.  You can add these libraries to\n"
                 "| the new installation, or remove the functions using them\n"
              "| from the old installation.  A list of the problem libraries\n"
--- 253,259 ----
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!              "| Your installation references loadable libraries that are missing\n"
               "| from the new installation.  You can add these libraries to\n"
                 "| the new installation, or remove the functions using them\n"
              "| from the old installation.  A list of the problem libraries\n"
Index: contrib/pg_upgrade/version_old_8_3.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/version_old_8_3.c,v
retrieving revision 1.6
diff -c -c -r1.6 version_old_8_3.c
*** contrib/pg_upgrade/version_old_8_3.c    3 Jul 2010 16:33:14 -0000    1.6
--- contrib/pg_upgrade/version_old_8_3.c    25 Jul 2010 03:19:48 -0000
***************
*** 94,100 ****
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!                "| Your installation uses the \"name\" data type in\n"
                 "| user tables.  This data type changed its internal\n"
                 "| alignment between your old and new clusters so this\n"
                 "| cluster cannot currently be upgraded.  You can\n"
--- 94,100 ----
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!                "| Your installation contains the \"name\" data type in\n"
                 "| user tables.  This data type changed its internal\n"
                 "| alignment between your old and new clusters so this\n"
                 "| cluster cannot currently be upgraded.  You can\n"
***************
*** 184,190 ****
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!                "| Your installation uses the \"tsquery\" data type.\n"
                 "| This data type added a new internal field between\n"
                 "| your old and new clusters so this cluster cannot\n"
                 "| currently be upgraded.  You can remove the problem\n"
--- 184,190 ----
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!                "| Your installation contains the \"tsquery\" data type.\n"
                 "| This data type added a new internal field between\n"
                 "| your old and new clusters so this cluster cannot\n"
                 "| currently be upgraded.  You can remove the problem\n"
***************
*** 274,280 ****
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!                "| Your installation uses \"/contrib/isn\" functions\n"
                 "| which rely on the bigint data type.  Your old and\n"
                 "| new clusters pass bigint values differently so this\n"
                 "| cluster cannot currently be upgraded.  You can\n"
--- 274,280 ----
          fclose(script);
          pg_log(ctx, PG_REPORT, "fatal\n");
          pg_log(ctx, PG_FATAL,
!                "| Your installation contains \"/contrib/isn\" functions\n"
                 "| which rely on the bigint data type.  Your old and\n"
                 "| new clusters pass bigint values differently so this\n"
                 "| cluster cannot currently be upgraded.  You can\n"
Index: doc/src/sgml/pgupgrade.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/pgupgrade.sgml,v
retrieving revision 1.12
diff -c -c -r1.12 pgupgrade.sgml
*** doc/src/sgml/pgupgrade.sgml    25 May 2010 15:55:28 -0000    1.12
--- doc/src/sgml/pgupgrade.sgml    25 Jul 2010 03:19:49 -0000
***************
*** 445,453 ****
     </listitem>
    </orderedlist>

!   </sect2>

!   <sect2>
    <title>Limitations in migrating <emphasis>from</> PostgreSQL 8.3</title>

    <para>
--- 445,453 ----
     </listitem>
    </orderedlist>

!  </sect2>

!  <sect2>
    <title>Limitations in migrating <emphasis>from</> PostgreSQL 8.3</title>

    <para>
***************
*** 514,529 ****
     version 8.4 or later of the one-click distribution. It is not
     possible to upgrade from the MSI installer to the one-click installer.
    </para>

    <para>
!    All failure, rebuild, and reindex cases will be reported by <application>pg_upgrade</>
!    if they affect your installation; post-migration scripts to rebuild
!    tables and indexes will be automatically generated.
    </para>

    <para>
     For deployment testing, create a schema-only copy of the old cluster,
!    insert dummy data, and migrate that.
    </para>

    <para>
--- 514,543 ----
     version 8.4 or later of the one-click distribution. It is not
     possible to upgrade from the MSI installer to the one-click installer.
    </para>
+
+  </sect2>
+
+  <sect2>
+   <title>Notes</title>
+
+   <para>
+    <application>pg_upgrade</> does not support migration of databases
+    containing these reg* system oid-referencing data types:
+    <type>regproc</>, <type>regprocedure</>, <type>regoper</>,
+    <type>regoperator</>, <type>regclass</>, <type>regconfig</>, and
+    <type>regdictionary</>.  (<type>regtype</> can be migrated.)
+   </para>

    <para>
!    All failure, rebuild, and reindex cases will be reported by
!    <application>pg_upgrade</> if they affect your installation;
!    post-migration scripts to rebuild tables and indexes will be
!    generated automatically.
    </para>

    <para>
     For deployment testing, create a schema-only copy of the old cluster,
!    insert dummy data, and migrate that.
    </para>

    <para>

Re: pg_upgrade issues

From
Bruce Momjian
Date:
Bruce Momjian wrote:
> I have applied the attached patch to CVS HEAD and 9.0 that prevent
> migration when any reg* data type is used in a user table (except
> regtype because pg_type.oid is preserved).
>
> I documented this restriction.  Thanks again for the report.

Attached is a secondary patch for /contrib/isn, in case you want that
too.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +
Index: contrib/pg_upgrade/check.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/check.c,v
retrieving revision 1.13
diff -c -c -r1.13 check.c
*** contrib/pg_upgrade/check.c    25 Jul 2010 03:28:32 -0000    1.13
--- contrib/pg_upgrade/check.c    25 Jul 2010 03:43:07 -0000
***************
*** 14,19 ****
--- 14,21 ----
  static void check_new_db_is_empty(migratorContext *ctx);
  static void check_locale_and_encoding(migratorContext *ctx, ControlData *oldctrl,
                            ControlData *newctrl);
+ static void check_for_isn_and_int8_passing_mismatch(migratorContext *ctx,
+                                                 Cluster whichCluster);
  static void check_for_reg_data_type_usage(migratorContext *ctx, Cluster whichCluster);


***************
*** 63,73 ****
       */

      check_for_reg_data_type_usage(ctx, CLUSTER_OLD);

      /* old = PG 8.3 checks? */
      if (GET_MAJOR_VERSION(ctx->old.major_version) <= 803)
      {
-         old_8_3_check_for_isn_and_int8_passing_mismatch(ctx, CLUSTER_OLD);
          old_8_3_check_for_name_data_type_usage(ctx, CLUSTER_OLD);
          old_8_3_check_for_tsquery_usage(ctx, CLUSTER_OLD);
          if (ctx->check)
--- 65,75 ----
       */

      check_for_reg_data_type_usage(ctx, CLUSTER_OLD);
+     check_for_isn_and_int8_passing_mismatch(ctx, CLUSTER_OLD);

      /* old = PG 8.3 checks? */
      if (GET_MAJOR_VERSION(ctx->old.major_version) <= 803)
      {
          old_8_3_check_for_name_data_type_usage(ctx, CLUSTER_OLD);
          old_8_3_check_for_tsquery_usage(ctx, CLUSTER_OLD);
          if (ctx->check)
***************
*** 444,449 ****
--- 446,543 ----


  /*
+  *     check_for_isn_and_int8_passing_mismatch()
+  *
+  *    /contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
+  *    by value.  The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
+  *    it must match for the old and new servers.
+  */
+ void
+ check_for_isn_and_int8_passing_mismatch(migratorContext *ctx, Cluster whichCluster)
+ {
+     ClusterInfo *active_cluster = (whichCluster == CLUSTER_OLD) ?
+     &ctx->old : &ctx->new;
+     int            dbnum;
+     FILE       *script = NULL;
+     bool        found = false;
+     char        output_path[MAXPGPATH];
+
+     prep_status(ctx, "Checking for /contrib/isn with bigint-passing mismatch");
+
+     if (ctx->old.controldata.float8_pass_by_value ==
+         ctx->new.controldata.float8_pass_by_value)
+     {
+         /* no mismatch */
+         check_ok(ctx);
+         return;
+     }
+
+     snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
+              ctx->cwd);
+
+     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
+     {
+         PGresult   *res;
+         bool        db_used = false;
+         int            ntups;
+         int            rowno;
+         int            i_nspname,
+                     i_proname;
+         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
+         PGconn       *conn = connectToServer(ctx, active_db->db_name, whichCluster);
+
+         /* Find any functions coming from contrib/isn */
+         res = executeQueryOrDie(ctx, conn,
+                                 "SELECT n.nspname, p.proname "
+                                 "FROM    pg_catalog.pg_proc p, "
+                                 "        pg_catalog.pg_namespace n "
+                                 "WHERE    p.pronamespace = n.oid AND "
+                                 "        p.probin = '$libdir/isn'");
+
+         ntups = PQntuples(res);
+         i_nspname = PQfnumber(res, "nspname");
+         i_proname = PQfnumber(res, "proname");
+         for (rowno = 0; rowno < ntups; rowno++)
+         {
+             found = true;
+             if (script == NULL && (script = fopen(output_path, "w")) == NULL)
+                 pg_log(ctx, PG_FATAL, "Could not create necessary file:  %s\n", output_path);
+             if (!db_used)
+             {
+                 fprintf(script, "Database:  %s\n", active_db->db_name);
+                 db_used = true;
+             }
+             fprintf(script, "  %s.%s\n",
+                     PQgetvalue(res, rowno, i_nspname),
+                     PQgetvalue(res, rowno, i_proname));
+         }
+
+         PQclear(res);
+
+         PQfinish(conn);
+     }
+
+     if (found)
+     {
+         fclose(script);
+         pg_log(ctx, PG_REPORT, "fatal\n");
+         pg_log(ctx, PG_FATAL,
+                "| Your installation contains \"/contrib/isn\" functions\n"
+                "| which rely on the bigint data type.  Your old and\n"
+                "| new clusters pass bigint values differently so this\n"
+                "| cluster cannot currently be upgraded.  You can\n"
+                "| manually migrate data that use \"/contrib/isn\"\n"
+                "| facilities and remove \"/contrib/isn\" from the\n"
+                "| old cluster and restart the migration.  A list\n"
+                "| of the problem functions is in the file:\n"
+                "| \t%s\n\n", output_path);
+     }
+     else
+         check_ok(ctx);
+ }
+
+
+ /*
   * check_for_reg_data_type_usage()
   *    pg_upgrade only preserves these system values:
   *        pg_class.relfilenode
Index: contrib/pg_upgrade/pg_upgrade.h
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/pg_upgrade.h,v
retrieving revision 1.15
diff -c -c -r1.15 pg_upgrade.h
*** contrib/pg_upgrade/pg_upgrade.h    6 Jul 2010 19:18:55 -0000    1.15
--- contrib/pg_upgrade/pg_upgrade.h    25 Jul 2010 03:43:07 -0000
***************
*** 388,395 ****
                                         Cluster whichCluster);
  void old_8_3_check_for_tsquery_usage(migratorContext *ctx,
                                  Cluster whichCluster);
- void old_8_3_check_for_isn_and_int8_passing_mismatch(migratorContext *ctx,
-                                                 Cluster whichCluster);
  void old_8_3_rebuild_tsvector_tables(migratorContext *ctx,
                                  bool check_mode, Cluster whichCluster);
  void old_8_3_invalidate_hash_gin_indexes(migratorContext *ctx,
--- 388,393 ----
Index: contrib/pg_upgrade/version_old_8_3.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/pg_upgrade/version_old_8_3.c,v
retrieving revision 1.7
diff -c -c -r1.7 version_old_8_3.c
*** contrib/pg_upgrade/version_old_8_3.c    25 Jul 2010 03:28:32 -0000    1.7
--- contrib/pg_upgrade/version_old_8_3.c    25 Jul 2010 03:43:07 -0000
***************
*** 198,295 ****


  /*
-  * old_8_3_check_for_isn_and_int8_passing_mismatch()
-  *    8.3 -> 8.4
-  *    /contrib/isn relies on data type int8, and in 8.4 int8 is now passed
-  *    by value.  The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
-  *    it must match for the old and new servers.
-  */
- void
- old_8_3_check_for_isn_and_int8_passing_mismatch(migratorContext *ctx, Cluster whichCluster)
- {
-     ClusterInfo *active_cluster = (whichCluster == CLUSTER_OLD) ?
-     &ctx->old : &ctx->new;
-     int            dbnum;
-     FILE       *script = NULL;
-     bool        found = false;
-     char        output_path[MAXPGPATH];
-
-     prep_status(ctx, "Checking for /contrib/isn with bigint-passing mismatch");
-
-     if (ctx->old.controldata.float8_pass_by_value ==
-         ctx->new.controldata.float8_pass_by_value)
-     {
-         /* no mismatch */
-         check_ok(ctx);
-         return;
-     }
-
-     snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
-              ctx->cwd);
-
-     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
-     {
-         PGresult   *res;
-         bool        db_used = false;
-         int            ntups;
-         int            rowno;
-         int            i_nspname,
-                     i_proname;
-         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
-         PGconn       *conn = connectToServer(ctx, active_db->db_name, whichCluster);
-
-         /* Find any functions coming from contrib/isn */
-         res = executeQueryOrDie(ctx, conn,
-                                 "SELECT n.nspname, p.proname "
-                                 "FROM    pg_catalog.pg_proc p, "
-                                 "        pg_catalog.pg_namespace n "
-                                 "WHERE    p.pronamespace = n.oid AND "
-                                 "        p.probin = '$libdir/isn'");
-
-         ntups = PQntuples(res);
-         i_nspname = PQfnumber(res, "nspname");
-         i_proname = PQfnumber(res, "proname");
-         for (rowno = 0; rowno < ntups; rowno++)
-         {
-             found = true;
-             if (script == NULL && (script = fopen(output_path, "w")) == NULL)
-                 pg_log(ctx, PG_FATAL, "Could not create necessary file:  %s\n", output_path);
-             if (!db_used)
-             {
-                 fprintf(script, "Database:  %s\n", active_db->db_name);
-                 db_used = true;
-             }
-             fprintf(script, "  %s.%s\n",
-                     PQgetvalue(res, rowno, i_nspname),
-                     PQgetvalue(res, rowno, i_proname));
-         }
-
-         PQclear(res);
-
-         PQfinish(conn);
-     }
-
-     if (found)
-     {
-         fclose(script);
-         pg_log(ctx, PG_REPORT, "fatal\n");
-         pg_log(ctx, PG_FATAL,
-                "| Your installation contains \"/contrib/isn\" functions\n"
-                "| which rely on the bigint data type.  Your old and\n"
-                "| new clusters pass bigint values differently so this\n"
-                "| cluster cannot currently be upgraded.  You can\n"
-                "| manually migrate data that use \"/contrib/isn\"\n"
-                "| facilities and remove \"/contrib/isn\" from the\n"
-                "| old cluster and restart the migration.  A list\n"
-                "| of the problem functions is in the file:\n"
-                "| \t%s\n\n", output_path);
-     }
-     else
-         check_ok(ctx);
- }
-
-
- /*
   * old_8_3_rebuild_tsvector_tables()
   *    8.3 -> 8.4
   * 8.3 sorts lexemes by its length and if lengths are the same then it uses
--- 198,203 ----

Re: pg_upgrade issues

From
Date:
> Bruce Momjian wrote:
> > depstein@alliedtesting.com wrote:
> > > I am trying to obtain a binary dump of a small test database where
> > > this issue could be reproduced, but so far, no luck. At present,
> the
> > > least such database is 1.5 GB compressed and contains a lot of
> > > proprietary info. I would welcome any suggestions on how to do
> this.
> >
> > Your diagnosis is 100% on target, and very perceptive.  Because we
> > preserve pg_class.relfilenode, if the table has not been rebuilt, for
> > example by CLUSTER, the old system the pg_class.oid and
> > pg_class.relfilenode are the same, and hence pg_class.oid is
> preserved
> > through pg_class.relfilenode during the migration.  If they are
> > different, e.g. they ran CLUSTER, pg_upgrade will be wrong because
> the
> > oid has changed, and you will see the errors you are reporting.
> >
> > I am inclined to prevent pg_upgrade from migrating any database that
> > uses any of these reg* data types, and document this restriction.  I
> > probably could allow regtype because that pg_type is preserved.
>=20
> I have applied the attached patch to CVS HEAD and 9.0 that prevent
> migration when any reg* data type is used in a user table (except
> regtype because pg_type.oid is preserved).
>=20
> I documented this restriction.  Thanks again for the report.

Thank you for the explanation and the swift action.

I just want to note that one reason regclass may be used in user tables (as=
 opposed to, say, regtype) is that in PL/pgSQL trigger procedures there is =
a special variable TG_RELID, which provides a convenient reference to the t=
able that pulled the trigger (this is the case for some of our uses).

Dmitry

Re: pg_upgrade issues

From
Bruce Momjian
Date:
depstein@alliedtesting.com wrote:
> > Bruce Momjian wrote:
> > > depstein@alliedtesting.com wrote:
> > > > I am trying to obtain a binary dump of a small test database where
> > > > this issue could be reproduced, but so far, no luck. At present,
> > the
> > > > least such database is 1.5 GB compressed and contains a lot of
> > > > proprietary info. I would welcome any suggestions on how to do
> > this.
> > >
> > > Your diagnosis is 100% on target, and very perceptive.  Because we
> > > preserve pg_class.relfilenode, if the table has not been rebuilt, for
> > > example by CLUSTER, the old system the pg_class.oid and
> > > pg_class.relfilenode are the same, and hence pg_class.oid is
> > preserved
> > > through pg_class.relfilenode during the migration.  If they are
> > > different, e.g. they ran CLUSTER, pg_upgrade will be wrong because
> > the
> > > oid has changed, and you will see the errors you are reporting.
> > >
> > > I am inclined to prevent pg_upgrade from migrating any database that
> > > uses any of these reg* data types, and document this restriction.  I
> > > probably could allow regtype because that pg_type is preserved.
> >
> > I have applied the attached patch to CVS HEAD and 9.0 that prevent
> > migration when any reg* data type is used in a user table (except
> > regtype because pg_type.oid is preserved).
> >
> > I documented this restriction.  Thanks again for the report.
>
> Thank you for the explanation and the swift action.
>
> I just want to note that one reason regclass may be used in user tables
> (as opposed to, say, regtype) is that in PL/pgSQL trigger procedures
> there is a special variable TG_RELID, which provides a convenient
> reference to the table that pulled the trigger (this is the case for
> some of our uses).

OK, thanks.  I was curious about your usage so I could determine how
widespread usage of those reg* types is.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +

Re: pg_upgrade issues

From
Robert Haas
Date:
On Sat, Jul 24, 2010 at 11:37 PM, Bruce Momjian <bruce@momjian.us> wrote:
>> I am inclined to prevent pg_upgrade from migrating any database that
>> uses any of these reg* data types, and document this restriction. =A0I
>> probably could allow regtype because that pg_type is preserved.
>
> I have applied the attached patch to CVS HEAD and 9.0 that prevent
> migration when any reg* data type is used in a user table (except
> regtype because pg_type.oid is preserved).

This is a good change; however, there is still some potential for
lossage here.  What if the column were declared as type OID?  Then it
would be hard to tell whether migration was safe or not.  Perhaps the
right long-term solution is to try harder to preserve OIDs in more
cases.

--=20
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

Re: pg_upgrade issues

From
Bruce Momjian
Date:
Robert Haas wrote:
> On Sat, Jul 24, 2010 at 11:37 PM, Bruce Momjian <bruce@momjian.us> wrote:
> >> I am inclined to prevent pg_upgrade from migrating any database that
> >> uses any of these reg* data types, and document this restriction. ?I
> >> probably could allow regtype because that pg_type is preserved.
> >
> > I have applied the attached patch to CVS HEAD and 9.0 that prevent
> > migration when any reg* data type is used in a user table (except
> > regtype because pg_type.oid is preserved).
>
> This is a good change; however, there is still some potential for
> lossage here.  What if the column were declared as type OID?  Then it
> would be hard to tell whether migration was safe or not.  Perhaps the
> right long-term solution is to try harder to preserve OIDs in more
> cases.

You are right that an oid column cannot be tracked easily.  It could
refer to a user table with oids, or it might be a system row reference.

I have considered preserving more oids, but that is going to increase
the backend changes for pg_upgrade, and I am hesistant to do that until
there is a claarer demand.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +

Re: pg_upgrade issues

From
Alvaro Herrera
Date:
Excerpts from depstein's message of lun jul 26 08:05:24 -0400 2010:

> I just want to note that one reason regclass may be used in user tables (as opposed to, say, regtype) is that in
PL/pgSQLtrigger procedures there is a special variable TG_RELID, which provides a convenient reference to the table
thatpulled the trigger (this is the case for some of our uses). 

I've wanted to use regclass (and regproc too, for that matter) in some
db designs, but I've refrained precisely because of the movability issues.

Note that you can use TG_SCHEMANAME and TG_RELNAME in plpgsql triggers
anyway.

Re: pg_upgrade issues

From
Bruce Momjian
Date:
Alvaro Herrera wrote:
> Excerpts from depstein's message of lun jul 26 08:05:24 -0400 2010:
>
> > I just want to note that one reason regclass may be used in user tables (as opposed to, say, regtype) is that in
PL/pgSQLtrigger procedures there is a special variable TG_RELID, which provides a convenient reference to the table
thatpulled the trigger (this is the case for some of our uses). 
>
> I've wanted to use regclass (and regproc too, for that matter) in some
> db designs, but I've refrained precisely because of the movability
> issues.

Were you worried about pg_upgrade movability issues, or just general
movability issues?

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +

Re: pg_upgrade issues

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> Excerpts from depstein's message of lun jul 26 08:05:24 -0400 2010:
>> I just want to note that one reason regclass may be used in user tables (as opposed to, say, regtype) is that in
PL/pgSQLtrigger procedures there is a special variable TG_RELID, which provides a convenient reference to the table
thatpulled the trigger (this is the case for some of our uses). 

> I've wanted to use regclass (and regproc too, for that matter) in some
> db designs, but I've refrained precisely because of the movability issues.

> Note that you can use TG_SCHEMANAME and TG_RELNAME in plpgsql triggers
> anyway.

How does TG_RELID lead to wanting to store regclass columns, exactly?
I've always supposed that was a legacy parameter rather than something
anyone would actually use.

            regards, tom lane

Re: pg_upgrade issues

From
Date:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
> > Excerpts from depstein's message of lun jul 26 08:05:24 -0400 2010:
> >> I just want to note that one reason regclass may be used in user
> tables (as opposed to, say, regtype) is that in PL/pgSQL trigger
> procedures there is a special variable TG_RELID, which provides a
> convenient reference to the table that pulled the trigger (this is the
> case for some of our uses).
>=20
> > I've wanted to use regclass (and regproc too, for that matter) in
> some
> > db designs, but I've refrained precisely because of the movability
> issues.
>=20
> > Note that you can use TG_SCHEMANAME and TG_RELNAME in plpgsql
> triggers
> > anyway.
>=20
> How does TG_RELID lead to wanting to store regclass columns, exactly?
> I've always supposed that was a legacy parameter rather than something
> anyone would actually use.

Here is one use case from our database. We store data for financial instrum=
ents. The data has a hierarchical structure. For instance, we have the foll=
owing tables:

asset
    asset_option
        asset_option_american
        asset_option_european

Suppose we have a procedure that takes a list of asset ID's and performs di=
fferent actions depending on the type of asset. One way to implement this w=
ould be through table inheritance (which we do have). In order to find the =
subset of assets that are options, we could search the table a_asset_option=
, from which all option tables are derived. However, working with parent ta=
bles turns out to be very inefficient in some situations. Some queries, suc=
h as joins, result in the materialization of a huge aggregate table, follow=
ed by an inefficient scan of that table.

An alternative implementation is to have a set of registry tables, which pa=
rallel the asset tables. Thus, we have the following tables:

reg_asset
    reg_asset_option
        reg_asset_option_american
        reg_asset_option_european

Each of these tables has two columns: one with an asset ID, the other is a =
regclass column that refers to an asset table. Triggers ensure that wheneve=
r a new asset is added to an asset table, its ID and table OID are added to=
 the registry table for that type of asset, as well as to all registry tabl=
es that are higher in the hierarchy. (This is where TG_RELID comes into pla=
y.) Thus, an American option is registered in the tables reg_asset_option_a=
merican, reg_asset_option and reg_asset. If I wanted to know whether an ass=
et with a given ID is an option, I would only have to search the index of t=
he reg_asset_option table. I can also write dynamic queries, using the tabl=
e OID field of the registry tables as a proxy for the table name.

What makes the table OID an attractive choice for registry tables is that i=
t is just a single integer number, which takes up much less space and is mu=
ch faster when performing comparisons than the qualified table name. And th=
e reason regclass is a natural choice is that that is what trigger procedur=
es make available through the TG_RELID special variable.

Regards,
Dmitry