pg_upgrade: preserve database and relation minmxid values
authorBruce Momjian
Wed, 2 Jul 2014 19:29:38 +0000 (15:29 -0400)
committerBruce Momjian
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 7e73f7e1ae49ebd896aaf5a1b880871124bc5ba7..db21ec0f776015b53f641bab070689704279b912 100644 (file)
@@ -47,7 +47,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);
 
@@ -251,8 +251,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,
@@ -274,7 +274,7 @@ prepare_new_databases(void)
     * set.
     */
 
-   set_frozenxids();
+   set_frozenxids(false);
 
    prep_status("Restoring global objects in the new cluster");
 
@@ -357,6 +357,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);
 
@@ -498,7 +505,7 @@ copy_clog_xlog_xid(void)
  */
 static
 void
-set_frozenxids(void)
+set_frozenxids(bool minmxid_only)
 {
    int         dbnum;
    PGconn     *conn,
@@ -508,15 +515,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,
@@ -534,10 +551,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,
@@ -547,13 +564,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 1ad85cf71516baadaea921427beb4d4b8193afc3..c6261071f482d76829613b59350afda7e886652f 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 5f3b5dc0d59e7b34329535f87c16f6b0de74a15b..b441915428c0cded4b85d02a7573b9fd11f91ced 100644 (file)
@@ -2119,6 +2119,7 @@ dumpDatabase(Archive *fout)
                i_collate,
                i_ctype,
                i_frozenxid,
+               i_minmxid,
                i_tablespace;
    CatalogId   dbCatId;
    DumpId      dbDumpId;
@@ -2128,7 +2129,7 @@ dumpDatabase(Archive *fout)
               *collate,
               *ctype,
               *tablespace;
-   uint32      frozenxid;
+   uint32      frozenxid, minmxid;
 
    datname = PQdb(conn);
 
@@ -2139,12 +2140,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, 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, "
+                         "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 "
 
@@ -2158,7 +2173,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 "
 
@@ -2172,7 +2187,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 = ",
@@ -2185,7 +2200,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 = ",
@@ -2200,7 +2215,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 = ",
@@ -2217,6 +2232,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));
@@ -2226,6 +2242,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",
@@ -2252,11 +2269,11 @@ dumpDatabase(Archive *fout)
 
    if (binary_upgrade)
    {
-       appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
+       appendPQExpBuffer(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);
        appendPQExpBuffer(creaQry, ";\n");
 
@@ -2287,32 +2304,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");
 
-       appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n");
+       appendPQExpBuffer(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, "",
@@ -2331,7 +2356,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);
@@ -2339,12 +2370,14 @@ dumpDatabase(Archive *fout)
            lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
 
            i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
+           i_relminmxid = PQfnumber(lo_res, "relminmxid");
 
-           appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n");
+           appendPQExpBuffer(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, "",
@@ -4216,8 +4249,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_owning_tab;
@@ -4263,8 +4298,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.relpages, "
                          "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4300,8 +4336,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, "
                          "c.relpages, "
                          "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4337,8 +4374,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, "
                          "c.relpages, "
                          "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
@@ -4373,8 +4411,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, "
                          "c.relpages, "
                          "NULL AS reloftype, "
@@ -4409,8 +4448,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, "
                          "c.relpages, "
                          "NULL AS reloftype, "
@@ -4445,9 +4485,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, "
                          "relpages, "
                          "NULL AS reloftype, "
@@ -4481,9 +4521,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, "
                          "relpages, "
                          "NULL AS reloftype, "
@@ -4513,9 +4553,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, "
                          "relpages, "
                          "NULL AS reloftype, "
@@ -4540,9 +4580,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, "
                          "relpages, "
                          "NULL AS reloftype, "
@@ -4577,9 +4617,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, "
                          "0 AS relpages, "
                          "NULL AS reloftype, "
@@ -4626,8 +4666,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_relpages = PQfnumber(res, "relpages");
@@ -4675,8 +4717,10 @@ getTables(Archive *fout, int *numTables)
        tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
        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
@@ -13220,22 +13264,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                  tbinfo->reloftype);
            }
 
-           appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
+           appendPQExpBuffer(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);
            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, "\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 05b5971fb6f9ab6f2cb8bc24317ecdd5261024fd..75c9b0db8639241208b7fad91fd6c1594d94f736 100644 (file)
@@ -245,8 +245,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 558c1f9f9aa6164aa791073c41385dc2b3dc04ad..052cfdaa5da214a1312a26cae9587f7da6f5f16f 100644 (file)
@@ -1225,12 +1225,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) "
@@ -1240,7 +1250,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) "
@@ -1250,7 +1260,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) "
@@ -1260,7 +1270,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) "
@@ -1272,7 +1282,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 "
@@ -1287,7 +1297,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 "
@@ -1303,10 +1313,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));
@@ -1373,11 +1384,11 @@ dumpCreateDB(PGconn *conn)
 
            if (binary_upgrade)
            {
-               appendPQExpBuffer(buf, "-- For binary upgrade, set datfrozenxid.\n");
+               appendPQExpBuffer(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);
                appendPQExpBuffer(buf, ";\n");
            }