]> granicus.if.org Git - postgresql/commitdiff
pg_upgrade: preserve database and relation minmxid values
authorBruce Momjian <bruce@momjian.us>
Wed, 2 Jul 2014 19:29:38 +0000 (15:29 -0400)
committerBruce Momjian <bruce@momjian.us>
Wed, 2 Jul 2014 19:29:38 +0000 (15:29 -0400)
Also set these values for pre-9.3 old clusters that don't have values to
preserve.

Analysis by Alvaro

Backpatch through 9.3

contrib/pg_upgrade/pg_upgrade.c
contrib/pg_upgrade/server.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_dumpall.c

index 47ae3cab34e861f58c112d9c9781107f0db1fc90..0c198c28a5eb00a7294aa9a96da808011d61559e 100644 (file)
@@ -46,7 +46,7 @@ static void prepare_new_cluster(void);
 static void prepare_new_databases(void);
 static void create_new_objects(void);
 static void copy_clog_xlog_xid(void);
-static void set_frozenxids(void);
+static void set_frozenxids(bool minmxid_only);
 static void setup(char *argv0, bool *live_check);
 static void cleanup(void);
 
@@ -250,8 +250,8 @@ prepare_new_cluster(void)
        /*
         * 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.
+        * datfrozenxid, relfrozenxids, and relminmxid later to match the new xid
+        * counter later.
         */
        prep_status("Freezing all rows on the new cluster");
        exec_prog(UTILITY_LOG_FILE, NULL, true,
@@ -273,7 +273,7 @@ prepare_new_databases(void)
         * set.
         */
 
-       set_frozenxids();
+       set_frozenxids(false);
 
        prep_status("Restoring global objects in the new cluster");
 
@@ -356,6 +356,13 @@ create_new_objects(void)
        end_progress_output();
        check_ok();
 
+       /*
+        * We don't have minmxids for databases or relations in pre-9.3
+        * clusters, so set those after we have restores the schemas.
+        */
+       if (GET_MAJOR_VERSION(old_cluster.major_version) < 903)
+               set_frozenxids(true);
+
        /* regenerate now that we have objects in the databases */
        get_db_and_rel_infos(&new_cluster);
 
@@ -489,15 +496,15 @@ copy_clog_xlog_xid(void)
 /*
  *     set_frozenxids()
  *
- *     We have frozen all xids, so set relfrozenxid and datfrozenxid
- *     to be the old cluster's xid counter, which we just set in the new
- *     cluster.  User-table frozenxid values will be set by pg_dump
- *     --binary-upgrade, but objects not set by the pg_dump must have
- *     proper frozen counters.
+ *     We have frozen all xids, so set datfrozenxid, relfrozenxid, and
+ *     relminmxid to be the old cluster's xid counter, which we just set
+ *     in the new cluster.  User-table frozenxid and minmxid values will
+ *     be set by pg_dump --binary-upgrade, but objects not set by the pg_dump
+ *     must have proper frozen counters.
  */
 static
 void
-set_frozenxids(void)
+set_frozenxids(bool minmxid_only)
 {
        int                     dbnum;
        PGconn     *conn,
@@ -507,15 +514,25 @@ set_frozenxids(void)
        int                     i_datname;
        int                     i_datallowconn;
 
-       prep_status("Setting frozenxid counters in new cluster");
+       if (!minmxid_only)
+               prep_status("Setting frozenxid and minmxid counters in new cluster");
+       else
+               prep_status("Setting minmxid counter in new cluster");
 
        conn_template1 = connectToServer(&new_cluster, "template1");
 
-       /* set pg_database.datfrozenxid */
+       if (!minmxid_only)
+               /* set pg_database.datfrozenxid */
+               PQclear(executeQueryOrDie(conn_template1,
+                                                                 "UPDATE pg_catalog.pg_database "
+                                                                 "SET  datfrozenxid = '%u'",
+                                                                 old_cluster.controldata.chkpnt_nxtxid));
+
+       /* set pg_database.datminmxid */
        PQclear(executeQueryOrDie(conn_template1,
                                                          "UPDATE pg_catalog.pg_database "
-                                                         "SET  datfrozenxid = '%u'",
-                                                         old_cluster.controldata.chkpnt_nxtxid));
+                                                         "SET  datminmxid = '%u'",
+                                                         old_cluster.controldata.chkpnt_nxtmulti));
 
        /* get database names */
        dbres = executeQueryOrDie(conn_template1,
@@ -533,10 +550,10 @@ set_frozenxids(void)
 
                /*
                 * 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.
+                * template0, because autovacuum increments their datfrozenxids,
+                * relfrozenxids, and relminmxid  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(conn_template1,
@@ -546,13 +563,22 @@ set_frozenxids(void)
 
                conn = connectToServer(&new_cluster, datname);
 
-               /* set pg_class.relfrozenxid */
+               if (!minmxid_only)
+                       /* set pg_class.relfrozenxid */
+                       PQclear(executeQueryOrDie(conn,
+                                                                         "UPDATE       pg_catalog.pg_class "
+                                                                         "SET  relfrozenxid = '%u' "
+                       /* only heap, materialized view, and TOAST are vacuumed */
+                                                                         "WHERE        relkind IN ('r', 'm', 't')",
+                                                                         old_cluster.controldata.chkpnt_nxtxid));
+
+               /* set pg_class.relminmxid */
                PQclear(executeQueryOrDie(conn,
                                                                  "UPDATE       pg_catalog.pg_class "
-                                                                 "SET  relfrozenxid = '%u' "
+                                                                 "SET  relminmxid = '%u' "
                /* only heap, materialized view, and TOAST are vacuumed */
                                                                  "WHERE        relkind IN ('r', 'm', 't')",
-                                                                 old_cluster.controldata.chkpnt_nxtxid));
+                                                                 old_cluster.controldata.chkpnt_nxtmulti));
                PQfinish(conn);
 
                /* Reset datallowconn flag */
index 5f4b5307cbad79ef5e9a68109b2c271b1fe4329f..901aa21f2e9b97ec5aa87f92e4561bdcf029ba12 100644 (file)
@@ -203,10 +203,11 @@ start_postmaster(ClusterInfo *cluster, bool throw_error)
 
        /*
         * Using autovacuum=off disables cleanup vacuum and analyze, but freeze
-        * vacuums can still happen, so we set autovacuum_freeze_max_age to its
-        * maximum.  We assume all datfrozenxid and relfrozen values are less than
-        * a gap of 2000000000 from the current xid counter, so autovacuum will
-        * not touch them.
+        * vacuums can still happen, so we set autovacuum_freeze_max_age and
+        * autovacuum_multixact_freeze_max_age to their maximums.  We assume all
+        * datfrozenxid, relfrozenxid, and relminmxid values are less than a gap
+        * of 2000000000 from the current xid counter, so autovacuum will not
+        * touch them.
         *
         * Turn off durability requirements to improve object creation speed, and
         * we only modify the new cluster, so only use it there.  If there is a
@@ -214,11 +215,13 @@ start_postmaster(ClusterInfo *cluster, bool throw_error)
         * win on ext4.
         */
        snprintf(cmd, sizeof(cmd),
-                 "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s %s%s\" start",
+                 "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s %s%s%s\" start",
                  cluster->bindir, SERVER_LOG_FILE, cluster->pgconfig, cluster->port,
                         (cluster->controldata.cat_ver >=
                          BINARY_UPGRADE_SERVER_FLAG_CAT_VER) ? " -b" :
                         " -c autovacuum=off -c autovacuum_freeze_max_age=2000000000",
+                        (GET_MAJOR_VERSION(cluster->major_version) >= 903) ?
+                        " -c autovacuum_multixact_freeze_max_age=2000000000" : "",
                         (cluster == &new_cluster) ?
          " -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "",
                         cluster->pgopts ? cluster->pgopts : "", socket_string);
index 6a4278784b4ea368ae85033e5dfe652c5708e83d..493df5455ec803fabde40c9a3a3187cfded3474c 100644 (file)
@@ -2156,6 +2156,7 @@ dumpDatabase(Archive *fout)
                                i_collate,
                                i_ctype,
                                i_frozenxid,
+                               i_minmxid,
                                i_tablespace;
        CatalogId       dbCatId;
        DumpId          dbDumpId;
@@ -2165,7 +2166,7 @@ dumpDatabase(Archive *fout)
                           *collate,
                           *ctype,
                           *tablespace;
-       uint32          frozenxid;
+       uint32          frozenxid, minmxid;
 
        datname = PQdb(conn);
 
@@ -2176,12 +2177,26 @@ dumpDatabase(Archive *fout)
        selectSourceSchema(fout, "pg_catalog");
 
        /* Get the database owner and parameters from pg_database */
-       if (fout->remoteVersion >= 80400)
+       if (fout->remoteVersion >= 90300)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
                                                  "pg_encoding_to_char(encoding) AS encoding, "
-                                                 "datcollate, datctype, datfrozenxid, "
+                                                 "datcollate, datctype, datfrozenxid, datminmxid, "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
+                                         "shobj_description(oid, 'pg_database') AS description "
+
+                                                 "FROM pg_database "
+                                                 "WHERE datname = ",
+                                                 username_subquery);
+               appendStringLiteralAH(dbQry, datname, fout);
+       }
+       else if (fout->remoteVersion >= 80400)
+       {
+               appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
+                                                 "(%s datdba) AS dba, "
+                                                 "pg_encoding_to_char(encoding) AS encoding, "
+                                                 "datcollate, datctype, datfrozenxid, 0 AS datminmxid, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                                          "shobj_description(oid, 'pg_database') AS description "
 
@@ -2195,7 +2210,7 @@ dumpDatabase(Archive *fout)
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
                                                  "pg_encoding_to_char(encoding) AS encoding, "
-                                          "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
+                                          "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                                          "shobj_description(oid, 'pg_database') AS description "
 
@@ -2209,7 +2224,7 @@ dumpDatabase(Archive *fout)
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
                                                  "pg_encoding_to_char(encoding) AS encoding, "
-                                          "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
+                                          "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace "
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
@@ -2222,7 +2237,7 @@ dumpDatabase(Archive *fout)
                                                  "(%s datdba) AS dba, "
                                                  "pg_encoding_to_char(encoding) AS encoding, "
                                                  "NULL AS datcollate, NULL AS datctype, "
-                                                 "0 AS datfrozenxid, "
+                                                 "0 AS datfrozenxid, 0 AS datminmxid, "
                                                  "NULL AS tablespace "
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
@@ -2237,7 +2252,7 @@ dumpDatabase(Archive *fout)
                                                  "(%s datdba) AS dba, "
                                                  "pg_encoding_to_char(encoding) AS encoding, "
                                                  "NULL AS datcollate, NULL AS datctype, "
-                                                 "0 AS datfrozenxid, "
+                                                 "0 AS datfrozenxid, 0 AS datminmxid, "
                                                  "NULL AS tablespace "
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
@@ -2254,6 +2269,7 @@ dumpDatabase(Archive *fout)
        i_collate = PQfnumber(res, "datcollate");
        i_ctype = PQfnumber(res, "datctype");
        i_frozenxid = PQfnumber(res, "datfrozenxid");
+       i_minmxid = PQfnumber(res, "datminmxid");
        i_tablespace = PQfnumber(res, "tablespace");
 
        dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
@@ -2263,6 +2279,7 @@ dumpDatabase(Archive *fout)
        collate = PQgetvalue(res, 0, i_collate);
        ctype = PQgetvalue(res, 0, i_ctype);
        frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
+       minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
        tablespace = PQgetvalue(res, 0, i_tablespace);
 
        appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
@@ -2289,11 +2306,11 @@ dumpDatabase(Archive *fout)
 
        if (binary_upgrade)
        {
-               appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
+               appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
                appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
-                                                 "SET datfrozenxid = '%u'\n"
+                                                 "SET datfrozenxid = '%u', datminmxid = '%u'\n"
                                                  "WHERE        datname = ",
-                                                 frozenxid);
+                                                 frozenxid, minmxid);
                appendStringLiteralAH(creaQry, datname, fout);
                appendPQExpBufferStr(creaQry, ";\n");
 
@@ -2324,32 +2341,40 @@ dumpDatabase(Archive *fout)
 
        /*
         * pg_largeobject and pg_largeobject_metadata come from the old system
-        * intact, so set their relfrozenxids.
+        * intact, so set their relfrozenxids and relminmxids.
         */
        if (binary_upgrade)
        {
                PGresult   *lo_res;
                PQExpBuffer loFrozenQry = createPQExpBuffer();
                PQExpBuffer loOutQry = createPQExpBuffer();
-               int                     i_relfrozenxid;
+               int                     i_relfrozenxid, i_relminmxid;
 
                /*
                 * pg_largeobject
                 */
-               appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
-                                                 "FROM pg_catalog.pg_class\n"
-                                                 "WHERE oid = %u;\n",
-                                                 LargeObjectRelationId);
+               if (fout->remoteVersion >= 90300)
+                       appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid\n"
+                                                         "FROM pg_catalog.pg_class\n"
+                                                         "WHERE oid = %u;\n",
+                                                         LargeObjectRelationId);
+               else
+                       appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid\n"
+                                                         "FROM pg_catalog.pg_class\n"
+                                                         "WHERE oid = %u;\n",
+                                                         LargeObjectRelationId);
 
                lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
 
                i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
+               i_relminmxid = PQfnumber(lo_res, "relminmxid");
 
-               appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n");
+               appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
                appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
-                                                 "SET relfrozenxid = '%u'\n"
+                                                 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                                                  "WHERE oid = %u;\n",
                                                  atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
+                                                 atoi(PQgetvalue(lo_res, 0, i_relminmxid)),
                                                  LargeObjectRelationId);
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                         "pg_largeobject", NULL, NULL, "",
@@ -2368,7 +2393,13 @@ dumpDatabase(Archive *fout)
                        resetPQExpBuffer(loFrozenQry);
                        resetPQExpBuffer(loOutQry);
 
-                       appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
+               if (fout->remoteVersion >= 90300)
+                       appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid\n"
+                                                         "FROM pg_catalog.pg_class\n"
+                                                         "WHERE oid = %u;\n",
+                                                         LargeObjectMetadataRelationId);
+               else
+                       appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid\n"
                                                          "FROM pg_catalog.pg_class\n"
                                                          "WHERE oid = %u;\n",
                                                          LargeObjectMetadataRelationId);
@@ -2376,12 +2407,14 @@ dumpDatabase(Archive *fout)
                        lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
 
                        i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
+                       i_relminmxid = PQfnumber(lo_res, "relminmxid");
 
-                       appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n");
+                       appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata relfrozenxid and relminmxid\n");
                        appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
-                                                         "SET relfrozenxid = '%u'\n"
+                                                         "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                                                          "WHERE oid = %u;\n",
                                                          atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
+                                                         atoi(PQgetvalue(lo_res, 0, i_relminmxid)),
                                                          LargeObjectMetadataRelationId);
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 "pg_largeobject_metadata", NULL, NULL, "",
@@ -4255,8 +4288,10 @@ getTables(Archive *fout, int *numTables)
        int                     i_relhasrules;
        int                     i_relhasoids;
        int                     i_relfrozenxid;
+       int                     i_relminmxid;
        int                     i_toastoid;
        int                     i_toastfrozenxid;
+       int                     i_toastminmxid;
        int                     i_relpersistence;
        int                     i_relispopulated;
        int                     i_relreplident;
@@ -4304,8 +4339,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s c.relowner) AS rolname, "
                                                  "c.relchecks, c.relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
-                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "c.relfrozenxid, c.relminmxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
+                                                 "tc.relminmxid AS tminmxid, "
                                                  "c.relpersistence, c.relispopulated, "
                                                  "c.relreplident, c.relpages, "
                                                  "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4343,8 +4379,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s c.relowner) AS rolname, "
                                                  "c.relchecks, c.relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
-                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "c.relfrozenxid, c.relminmxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
+                                                 "tc.relminmxid AS tminmxid, "
                                                  "c.relpersistence, c.relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
                                                  "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4382,8 +4419,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s c.relowner) AS rolname, "
                                                  "c.relchecks, c.relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
-                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "c.relfrozenxid, 0 AS relminmxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
+                                                 "0 AS tminmxid, "
                                                  "c.relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
                                                  "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4419,8 +4457,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s c.relowner) AS rolname, "
                                                  "c.relchecks, c.relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
-                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "c.relfrozenxid, 0 AS relminmxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
+                                                 "0 AS tminmxid, "
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
                                                  "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4455,8 +4494,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s c.relowner) AS rolname, "
                                                  "c.relchecks, c.relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
-                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "c.relfrozenxid, 0 AS relminmxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
+                                                 "0 AS tminmxid, "
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
                                                  "NULL AS reloftype, "
@@ -4491,8 +4531,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s c.relowner) AS rolname, "
                                          "c.relchecks, (c.reltriggers <> 0) AS relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
-                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "c.relfrozenxid, 0 AS relminmxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
+                                                 "0 AS tminmxid, "
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, c.relpages, "
                                                  "NULL AS reloftype, "
@@ -4527,9 +4568,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s relowner) AS rolname, "
                                                  "relchecks, (reltriggers <> 0) AS relhastriggers, "
                                                  "relhasindex, relhasrules, relhasoids, "
-                                                 "0 AS relfrozenxid, "
+                                                 "0 AS relfrozenxid, 0 AS relminmxid,"
                                                  "0 AS toid, "
-                                                 "0 AS tfrozenxid, "
+                                                 "0 AS tfrozenxid, 0 AS tminmxid,"
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
@@ -4563,9 +4604,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s relowner) AS rolname, "
                                                  "relchecks, (reltriggers <> 0) AS relhastriggers, "
                                                  "relhasindex, relhasrules, relhasoids, "
-                                                 "0 AS relfrozenxid, "
+                                                 "0 AS relfrozenxid, 0 AS relminmxid,"
                                                  "0 AS toid, "
-                                                 "0 AS tfrozenxid, "
+                                                 "0 AS tfrozenxid, 0 AS tminmxid,"
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
@@ -4595,9 +4636,9 @@ getTables(Archive *fout, int *numTables)
                                                  "(%s relowner) AS rolname, "
                                                  "relchecks, (reltriggers <> 0) AS relhastriggers, "
                                                  "relhasindex, relhasrules, relhasoids, "
-                                                 "0 AS relfrozenxid, "
+                                                 "0 AS relfrozenxid, 0 AS relminmxid,"
                                                  "0 AS toid, "
-                                                 "0 AS tfrozenxid, "
+                                                 "0 AS tfrozenxid, 0 AS tminmxid,"
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
@@ -4622,9 +4663,9 @@ getTables(Archive *fout, int *numTables)
                                                  "relchecks, (reltriggers <> 0) AS relhastriggers, "
                                                  "relhasindex, relhasrules, "
                                                  "'t'::bool AS relhasoids, "
-                                                 "0 AS relfrozenxid, "
+                                                 "0 AS relfrozenxid, 0 AS relminmxid,"
                                                  "0 AS toid, "
-                                                 "0 AS tfrozenxid, "
+                                                 "0 AS tfrozenxid, 0 AS tminmxid,"
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
@@ -4659,9 +4700,9 @@ getTables(Archive *fout, int *numTables)
                                                  "relchecks, (reltriggers <> 0) AS relhastriggers, "
                                                  "relhasindex, relhasrules, "
                                                  "'t'::bool AS relhasoids, "
-                                                 "0 as relfrozenxid, "
+                                                 "0 AS relfrozenxid, 0 AS relminmxid,"
                                                  "0 AS toid, "
-                                                 "0 AS tfrozenxid, "
+                                                 "0 AS tfrozenxid, 0 AS tminmxid,"
                                                  "'p' AS relpersistence, 't' as relispopulated, "
                                                  "'d' AS relreplident, 0 AS relpages, "
                                                  "NULL AS reloftype, "
@@ -4708,8 +4749,10 @@ getTables(Archive *fout, int *numTables)
        i_relhasrules = PQfnumber(res, "relhasrules");
        i_relhasoids = PQfnumber(res, "relhasoids");
        i_relfrozenxid = PQfnumber(res, "relfrozenxid");
+       i_relminmxid = PQfnumber(res, "relminmxid");
        i_toastoid = PQfnumber(res, "toid");
        i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
+       i_toastminmxid = PQfnumber(res, "tminmxid");
        i_relpersistence = PQfnumber(res, "relpersistence");
        i_relispopulated = PQfnumber(res, "relispopulated");
        i_relreplident = PQfnumber(res, "relreplident");
@@ -4760,8 +4803,10 @@ getTables(Archive *fout, int *numTables)
                tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
                tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
                tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
+               tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
                tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
                tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
+               tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
                if (PQgetisnull(res, i, i_reloftype))
                        tblinfo[i].reloftype = NULL;
                else
@@ -13525,22 +13570,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                                  tbinfo->reloftype);
                        }
 
-                       appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
+                       appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
                        appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
-                                                         "SET relfrozenxid = '%u'\n"
+                                                         "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                                                          "WHERE oid = ",
-                                                         tbinfo->frozenxid);
+                                                         tbinfo->frozenxid, tbinfo->minmxid);
                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
                        appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
 
                        if (tbinfo->toast_oid)
                        {
                                /* We preserve the toast oids, so we can use it during restore */
-                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid\n");
+                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
                                appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
-                                                                 "SET relfrozenxid = '%u'\n"
+                                                                 "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                                                                  "WHERE oid = '%u';\n",
-                                                                 tbinfo->toast_frozenxid, tbinfo->toast_oid);
+                                                                 tbinfo->toast_frozenxid,
+                                                                 tbinfo->toast_minmxid, tbinfo->toast_oid);
                        }
                }
 
index daf98bcb54f763d3e8fc05ec79fdf5bfe6fce328..d18418758070286a4abf3b326f5849e2d2be01c5 100644 (file)
@@ -247,8 +247,10 @@ typedef struct _tableInfo
        bool            hastriggers;    /* does it have any triggers? */
        bool            hasoids;                /* does it have OIDs? */
        uint32          frozenxid;              /* for restore frozen xid */
+       uint32          minmxid;                /* for restore min multi xid */
        Oid                     toast_oid;              /* for restore toast frozen xid */
        uint32          toast_frozenxid;        /* for restore toast frozen xid */
+       uint32          toast_minmxid;  /* for restore toast min multi 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: */
index 0cc4329b1a1add56042198355c6d1ab1a8f96311..bd19da661e8aec0eca8418cd03a20923269328e1 100644 (file)
@@ -1241,12 +1241,22 @@ dumpCreateDB(PGconn *conn)
        PQclear(res);
 
        /* Now collect all the information about databases to dump */
-       if (server_version >= 80400)
+       if (server_version >= 90300)
+               res = executeQuery(conn,
+                                                  "SELECT datname, "
+                                                  "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
+                                                  "pg_encoding_to_char(d.encoding), "
+                                                  "datcollate, datctype, datfrozenxid, datminmxid, "
+                                                  "datistemplate, datacl, datconnlimit, "
+                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
+                         "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
+                                                  "WHERE datallowconn ORDER BY 1");
+       else if (server_version >= 80400)
                res = executeQuery(conn,
                                                   "SELECT datname, "
                                                   "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
-                                                  "datcollate, datctype, datfrozenxid, "
+                                                  "datcollate, datctype, datfrozenxid, 0 AS datminmxid, "
                                                   "datistemplate, datacl, datconnlimit, "
                                                   "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
                          "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
@@ -1256,7 +1266,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                                   "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
-                  "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
+                  "null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
                                                   "datistemplate, datacl, datconnlimit, "
                                                   "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
                          "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
@@ -1266,7 +1276,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                                   "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
-                  "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
+                  "null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
                                                   "datistemplate, datacl, -1 as datconnlimit, "
                                                   "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
                   "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
@@ -1276,7 +1286,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                                   "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
-                  "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
+                  "null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
                                                   "datistemplate, datacl, -1 as datconnlimit, "
                                                   "'pg_default' AS dattablespace "
                   "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
@@ -1288,7 +1298,7 @@ dumpCreateDB(PGconn *conn)
                                        "(select usename from pg_shadow where usesysid=datdba), "
                                                   "(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
-                                                  "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, "
+                                                  "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, 0 AS datminmxid, "
                                                   "datistemplate, '' as datacl, -1 as datconnlimit, "
                                                   "'pg_default' AS dattablespace "
                                                   "FROM pg_database d "
@@ -1303,7 +1313,7 @@ dumpCreateDB(PGconn *conn)
                                                   "SELECT datname, "
                                        "(select usename from pg_shadow where usesysid=datdba), "
                                                   "pg_encoding_to_char(d.encoding), "
-                                                  "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, "
+                                                  "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, 0 AS datminmxid, "
                                                   "'f' as datistemplate, "
                                                   "'' as datacl, -1 as datconnlimit, "
                                                   "'pg_default' AS dattablespace "
@@ -1319,10 +1329,11 @@ dumpCreateDB(PGconn *conn)
                char       *dbcollate = PQgetvalue(res, i, 3);
                char       *dbctype = PQgetvalue(res, i, 4);
                uint32          dbfrozenxid = atooid(PQgetvalue(res, i, 5));
-               char       *dbistemplate = PQgetvalue(res, i, 6);
-               char       *dbacl = PQgetvalue(res, i, 7);
-               char       *dbconnlimit = PQgetvalue(res, i, 8);
-               char       *dbtablespace = PQgetvalue(res, i, 9);
+               uint32          dbminmxid = atooid(PQgetvalue(res, i, 6));
+               char       *dbistemplate = PQgetvalue(res, i, 7);
+               char       *dbacl = PQgetvalue(res, i, 8);
+               char       *dbconnlimit = PQgetvalue(res, i, 9);
+               char       *dbtablespace = PQgetvalue(res, i, 10);
                char       *fdbname;
 
                fdbname = pg_strdup(fmtId(dbname));
@@ -1389,11 +1400,11 @@ dumpCreateDB(PGconn *conn)
 
                        if (binary_upgrade)
                        {
-                               appendPQExpBufferStr(buf, "-- For binary upgrade, set datfrozenxid.\n");
+                               appendPQExpBufferStr(buf, "-- For binary upgrade, set datfrozenxid and datminmxid.\n");
                                appendPQExpBuffer(buf, "UPDATE pg_catalog.pg_database "
-                                                                 "SET datfrozenxid = '%u' "
+                                                                 "SET datfrozenxid = '%u', datminmxid = '%u' "
                                                                  "WHERE datname = ",
-                                                                 dbfrozenxid);
+                                                                 dbfrozenxid, dbminmxid);
                                appendStringLiteralConn(buf, dbname, conn);
                                appendPQExpBufferStr(buf, ";\n");
                        }