]> granicus.if.org Git - postgresql/commitdiff
For pg_upgrade, update template0's datfrozenxid and its relfrozenxids to
authorBruce Momjian <bruce@momjian.us>
Wed, 19 May 2010 18:27:43 +0000 (18:27 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 19 May 2010 18:27:43 +0000 (18:27 +0000)
match the behavior of autovacuum, which does this as the xid advances
even if autovacuum is turned off.

contrib/pg_upgrade/pg_upgrade.c

index fc692fc96a1eece54406508c053255dbbdfbcbc5..7d7abe6c23cb11ca78647f5dd4020abfa2ea30dc 100644 (file)
@@ -164,7 +164,10 @@ prepare_new_cluster(migratorContext *ctx)
        check_ok(ctx);
 
        /*
-        * We do freeze after analyze so pg_statistic is also frozen
+        * We do freeze after analyze so pg_statistic is also frozen.
+        * template0 is not frozen here, but data rows were frozen by initdb,
+        * and we set its datfrozenxid and relfrozenxids later to match the
+        * new xid counter later.
         */
        prep_status(ctx, "Freezing all rows on the new cluster");
        exec_prog(ctx, true,
@@ -292,48 +295,72 @@ void
 set_frozenxids(migratorContext *ctx)
 {
        int                     dbnum;
-       PGconn     *conn;
+       PGconn     *conn, *conn_template1;
        PGresult   *dbres;
        int                     ntups;
+       int                     i_datname;
+       int                     i_datallowconn;
 
        prep_status(ctx, "Setting frozenxid counters in new cluster");
 
-       conn = connectToServer(ctx, "template1", CLUSTER_NEW);
+       conn_template1 = connectToServer(ctx, "template1", CLUSTER_NEW);
 
        /* set pg_database.datfrozenxid */
-       PQclear(executeQueryOrDie(ctx, conn,
+       PQclear(executeQueryOrDie(ctx, conn_template1,
                                                          "UPDATE pg_catalog.pg_database "
-                                                         "SET  datfrozenxid = '%u' "
-                                                         "WHERE datallowconn = true",
+                                                         "SET  datfrozenxid = '%u'",
                                                          ctx->old.controldata.chkpnt_nxtxid));
 
        /* get database names */
-       dbres = executeQueryOrDie(ctx, conn,
-                                                         "SELECT       datname "
-                                                         "FROM pg_catalog.pg_database "
-                                                         "WHERE datallowconn = true");
+       dbres = executeQueryOrDie(ctx, conn_template1,
+                                                         "SELECT       datname, datallowconn "
+                                                         "FROM pg_catalog.pg_database");
 
-       /* free dbres below */
-       PQfinish(conn);
+       i_datname = PQfnumber(dbres, "datname");
+       i_datallowconn = PQfnumber(dbres, "datallowconn");
 
        ntups = PQntuples(dbres);
        for (dbnum = 0; dbnum < ntups; dbnum++)
        {
-               conn = connectToServer(ctx, PQgetvalue(dbres, dbnum, 0), CLUSTER_NEW);
+               char *datname = PQgetvalue(dbres, dbnum, i_datname);
+               char *datallowconn= PQgetvalue(dbres, dbnum, i_datallowconn);
+
+               /*
+                *      We must update databases where datallowconn = false, e.g.
+                *      template0, because autovacuum increments their datfrozenxids and
+                *      relfrozenxids even if autovacuum is turned off, and even though
+                *      all the data rows are already frozen  To enable this, we
+                *      temporarily change datallowconn.
+                */
+               if (strcmp(datallowconn, "f") == 0)
+                       PQclear(executeQueryOrDie(ctx, conn_template1,
+                                                                 "UPDATE pg_catalog.pg_database "
+                                                                 "SET  datallowconn = true "
+                                                                 "WHERE datname = '%s'", datname));
+
+               conn = connectToServer(ctx, datname, CLUSTER_NEW);
 
                /* set pg_class.relfrozenxid */
                PQclear(executeQueryOrDie(ctx, conn,
                                                                  "UPDATE       pg_catalog.pg_class "
                                                                  "SET  relfrozenxid = '%u' "
                /* only heap and TOAST are vacuumed */
-                                                                 "WHERE        relkind = 'r' OR "
-                                                                 "             relkind = 't'",
+                                                                 "WHERE        relkind IN ('r', 't')",
                                                                  ctx->old.controldata.chkpnt_nxtxid));
                PQfinish(conn);
+
+               /* Reset datallowconn flag */
+               if (strcmp(datallowconn, "f") == 0)
+                       PQclear(executeQueryOrDie(ctx, conn_template1,
+                                                                 "UPDATE pg_catalog.pg_database "
+                                                                 "SET  datallowconn = false "
+                                                                 "WHERE datname = '%s'", datname));
        }
 
        PQclear(dbres);
 
+       PQfinish(conn_template1);
+
        check_ok(ctx);
 }