Have pg_upgrade properly preserve relfrozenxid in toast tables.
authorBruce Momjian
Fri, 8 Apr 2011 15:59:14 +0000 (11:59 -0400)
committerBruce Momjian
Fri, 8 Apr 2011 15:59:38 +0000 (11:59 -0400)
This fixes a pg_upgrade bug that could lead to query errors when clog
files are improperly removed.

src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index f93affd089fcd590a2ac241dbc888b4ca7f5cb8f..8721e6573db81e857f4d79bbbb7dc089b401d503 100644 (file)
@@ -3409,6 +3409,8 @@ getTables(int *numTables)
    int         i_relhasrules;
    int         i_relhasoids;
    int         i_relfrozenxid;
+   int         i_toastoid;
+   int         i_toastfrozenxid;
    int         i_owning_tab;
    int         i_owning_col;
    int         i_reltablespace;
@@ -3451,7 +3453,8 @@ getTables(int *numTables)
                          "(%s c.relowner) AS rolname, "
                          "c.relchecks, c.relhastriggers, "
                          "c.relhasindex, c.relhasrules, c.relhasoids, "
-                         "c.relfrozenxid, "
+                         "c.relfrozenxid, tc.oid AS toid, "
+                         "tc.relfrozenxid AS tfrozenxid, "
                          "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
                          "d.refobjid AS owning_tab, "
                          "d.refobjsubid AS owning_col, "
@@ -3484,7 +3487,8 @@ getTables(int *numTables)
                          "(%s c.relowner) AS rolname, "
                          "c.relchecks, c.relhastriggers, "
                          "c.relhasindex, c.relhasrules, c.relhasoids, "
-                         "c.relfrozenxid, "
+                         "c.relfrozenxid, tc.oid AS toid, "
+                         "tc.relfrozenxid AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "d.refobjid AS owning_tab, "
                          "d.refobjsubid AS owning_col, "
@@ -3518,6 +3522,8 @@ getTables(int *numTables)
                          "relchecks, (reltriggers <> 0) AS relhastriggers, "
                          "relhasindex, relhasrules, relhasoids, "
                          "relfrozenxid, "
+                         "0 AS toid, "
+                         "0 AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "d.refobjid AS owning_tab, "
                          "d.refobjsubid AS owning_col, "
@@ -3550,6 +3556,8 @@ getTables(int *numTables)
                          "relchecks, (reltriggers <> 0) AS relhastriggers, "
                          "relhasindex, relhasrules, relhasoids, "
                          "0 AS relfrozenxid, "
+                         "0 AS toid, "
+                         "0 AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "d.refobjid AS owning_tab, "
                          "d.refobjsubid AS owning_col, "
@@ -3582,6 +3590,8 @@ getTables(int *numTables)
                          "relchecks, (reltriggers <> 0) AS relhastriggers, "
                          "relhasindex, relhasrules, relhasoids, "
                          "0 AS relfrozenxid, "
+                         "0 AS toid, "
+                         "0 AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "d.refobjid AS owning_tab, "
                          "d.refobjsubid AS owning_col, "
@@ -3610,6 +3620,8 @@ getTables(int *numTables)
                          "relchecks, (reltriggers <> 0) AS relhastriggers, "
                          "relhasindex, relhasrules, relhasoids, "
                          "0 AS relfrozenxid, "
+                         "0 AS toid, "
+                         "0 AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "NULL::oid AS owning_tab, "
                          "NULL::int4 AS owning_col, "
@@ -3633,6 +3645,8 @@ getTables(int *numTables)
                          "relhasindex, relhasrules, "
                          "'t'::bool AS relhasoids, "
                          "0 AS relfrozenxid, "
+                         "0 AS toid, "
+                         "0 AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "NULL::oid AS owning_tab, "
                          "NULL::int4 AS owning_col, "
@@ -3666,6 +3680,8 @@ getTables(int *numTables)
                          "relhasindex, relhasrules, "
                          "'t'::bool AS relhasoids, "
                          "0 as relfrozenxid, "
+                         "0 AS toid, "
+                         "0 AS tfrozenxid, "
                          "NULL AS reloftype, "
                          "NULL::oid AS owning_tab, "
                          "NULL::int4 AS owning_col, "
@@ -3711,6 +3727,8 @@ getTables(int *numTables)
    i_relhasrules = PQfnumber(res, "relhasrules");
    i_relhasoids = PQfnumber(res, "relhasoids");
    i_relfrozenxid = PQfnumber(res, "relfrozenxid");
+   i_toastoid = PQfnumber(res, "toid");
+   i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
    i_owning_tab = PQfnumber(res, "owning_tab");
    i_owning_col = PQfnumber(res, "owning_col");
    i_reltablespace = PQfnumber(res, "reltablespace");
@@ -3750,6 +3768,8 @@ getTables(int *numTables)
        tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
        tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
        tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
+       tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
+       tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
        if (PQgetisnull(res, i, i_reloftype))
            tblinfo[i].reloftype = NULL;
        else
@@ -10852,13 +10872,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                }
            }
 
-           appendPQExpBuffer(q, "\n-- For binary upgrade, set relfrozenxid.\n");
+           appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
            appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              "SET relfrozenxid = '%u'\n"
                              "WHERE oid = ",
                              tbinfo->frozenxid);
            appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
            appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+
+           if (tbinfo->toast_oid)
+           {
+               /* We preserve the toast oids, so we can use it during restore */
+               appendPQExpBuffer(q, "\n-- For binary upgrade, set toast's relfrozenxid\n");
+               appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
+                                 "SET relfrozenxid = '%u'\n"
+                                 "WHERE oid = '%u';\n",
+                                 tbinfo->toast_frozenxid, tbinfo->toast_oid);
+           }
        }
 
        /* Loop dumping statistics and storage statements */
index c309f69f7262006477556dac89c9c48f231dc09e..1dc715739e6313b345b8cfa0a24b3d32a9edcead 100644 (file)
@@ -228,6 +228,8 @@ typedef struct _tableInfo
    bool        hastriggers;    /* does it have any triggers? */
    bool        hasoids;        /* does it have OIDs? */
    uint32      frozenxid;      /* for restore frozen xid */
+   Oid         toast_oid;      /* for restore toast frozen xid */
+   uint32      toast_frozenxid;/* for restore toast frozen xid */
    int         ncheck;         /* # of CHECK expressions */
    char       *reloftype;      /* underlying type for typed table */
    /* these two are set only if table is a sequence owned by a column: */