pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Bruce Momjian <bruce@momjian.us>
To: Alvaro Herrera <alvherre@2ndquadrant.com>
Cc: Andres Freund <andres@2ndquadrant.com>
Cc: PostgreSQL Bugs <pgsql-bugs@postgresql.org>
Subject: Re: pg_upgrade < 9.3 -> >=9.3 misses a step around multixacts
Date: Tue, 1 Jul 2014 12:14:19 -0400
Message-ID: <20140701161419.GA16033@momjian.us> (raw)
In-Reply-To: <20140627210520.GP7340@eldon.alvh.no-ip.org>
References: <20140619020633.GA20469@momjian.us>
	<20140619015205.GD3806@momjian.us>
	<20140619014034.GC3806@momjian.us>
	<20140619220425.GQ18688@eldon.alvh.no-ip.org>
	<20140620010653.GS18688@eldon.alvh.no-ip.org>
	<20140620180725.GD29143@momjian.us>
	<20140624201346.GB17110@momjian.us>
	<20140627210520.GP7340@eldon.alvh.no-ip.org>
List-Unsubscribe: <mailto:majordomo@postgresql.org?body=unsub%20pgsql-bugs>

On Fri, Jun 27, 2014 at 05:05:21PM -0400, Alvaro Herrera wrote:
> Another thing probably worth doing is have pg_upgrade set
> pg_database.datminmxid to the minimum of pg_class.relminmxid on each
> database.  Right now these values are all initialized to 1, which is a
> problem.  We have set_frozenxids() which appears to be related, although
> I don't readily understand what that is doing.

Yikes, OK.  What pg_upgrade's set_frozenxids() does is to set the
database and relation frozen xids to be the current xid, particularly
template0 and the system tables, then pg_dump --binary-upgrade adjusts
many of them to match the old cluster.  What isn't happening, as you
pointed out, is that we are not dealing with the new database and
relation-level minmxid values in pg_upgrade or pg_dump --binary-upgrade.
The attached 1k-line patch fixes that.

What I am not sure about is how to set values from pre-9.3 clusters, and
whether 9.3 pg_upgrade upgrades from pre-9.3 clusters are a problem. 
Are users who used pg_upgrade to go to 9.4 beta in trouble?

I also have no way to know what value to use for pre-9.3 clusters --- I
used controldata.chkpnt_nxtmulti in pg_upgrade (because the value was
accessible), but 0 in pg_dump/pg_dumpall, like we already do for frozen
xid values, but that usage is for major versions that pg_upgrade doesn't
support, so it might be the wrong default.  I am thinking that should be
using controldata.chkpnt_nxtmulti, which exists back to 8.4, but I have
no access to that value from pg_dump.  In fact, the patch as it exists
is flawed because it uses controldata.chkpnt_nxtmulti to set values from
set_frozenxids(), because the value is accessible, but uses zero in
pg_dump and pg_dumpall for pre-9.3 old clusters.  :-(

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

  + Everyone has their own god. +

-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Attachments:

pg_upgrade.diff (text/x-diff, 41.7K) download diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c new file mode 100644 index ea1f9f6..9cea94f *** a/contrib/pg_upgrade/pg_upgrade.c --- b/contrib/pg_upgrade/pg_upgrade.c *************** prepare_new_cluster(void) *** 250,257 **** /* * 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("Freezing all rows on the new cluster"); exec_prog(UTILITY_LOG_FILE, NULL, true, --- 250,257 ---- /* * 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, 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, *************** copy_clog_xlog_xid(void) *** 489,499 **** /* * 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. */ static void --- 489,499 ---- /* * set_frozenxids() * ! * 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) *** 507,521 **** int i_datname; int i_datallowconn; ! prep_status("Setting frozenxid counters in new cluster"); conn_template1 = connectToServer(&new_cluster, "template1"); ! /* set pg_database.datfrozenxid */ PQclear(executeQueryOrDie(conn_template1, "UPDATE pg_catalog.pg_database " ! "SET datfrozenxid = '%u'", ! old_cluster.controldata.chkpnt_nxtxid)); /* get database names */ dbres = executeQueryOrDie(conn_template1, --- 507,522 ---- int i_datname; int i_datallowconn; ! prep_status("Setting frozenxid and minmxid counters in new cluster"); conn_template1 = connectToServer(&new_cluster, "template1"); ! /* set pg_database.datfrozenxid and pg_database.datminmxid */ PQclear(executeQueryOrDie(conn_template1, "UPDATE pg_catalog.pg_database " ! "SET datfrozenxid = '%u', datminmxid = '%u'", ! old_cluster.controldata.chkpnt_nxtxid, ! old_cluster.controldata.chkpnt_nxtmulti)); /* get database names */ dbres = executeQueryOrDie(conn_template1, *************** set_frozenxids(void) *** 533,542 **** /* * 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(conn_template1, --- 534,543 ---- /* * We must update databases where datallowconn = false, e.g. ! * 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, *************** set_frozenxids(void) *** 546,558 **** conn = connectToServer(&new_cluster, datname); ! /* 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)); PQfinish(conn); /* Reset datallowconn flag */ --- 547,560 ---- conn = connectToServer(&new_cluster, datname); ! /* set pg_class relfrozenxid and relminmxid */ PQclear(executeQueryOrDie(conn, "UPDATE pg_catalog.pg_class " ! "SET relfrozenxid = '%u', 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 */ diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c new file mode 100644 index 5f4b530..901aa21 *** a/contrib/pg_upgrade/server.c --- b/contrib/pg_upgrade/server.c *************** start_postmaster(ClusterInfo *cluster, b *** 203,212 **** /* * 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. * * 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 --- 203,213 ---- /* * Using autovacuum=off disables cleanup vacuum and analyze, but freeze ! * 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 *************** start_postmaster(ClusterInfo *cluster, b *** 214,224 **** * win on ext4. */ snprintf(cmd, sizeof(cmd), ! "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%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", (cluster == &new_cluster) ? " -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "", cluster->pgopts ? cluster->pgopts : "", socket_string); --- 215,227 ---- * win on ext4. */ snprintf(cmd, sizeof(cmd), ! "\"%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); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c new file mode 100644 index 799637d..412f52f *** a/src/bin/pg_dump/pg_dump.c --- b/src/bin/pg_dump/pg_dump.c *************** dumpDatabase(Archive *fout) *** 2156,2161 **** --- 2156,2162 ---- i_collate, i_ctype, i_frozenxid, + i_minmxid, i_tablespace; CatalogId dbCatId; DumpId dbDumpId; *************** dumpDatabase(Archive *fout) *** 2165,2171 **** *collate, *ctype, *tablespace; ! uint32 frozenxid; datname = PQdb(conn); --- 2166,2172 ---- *collate, *ctype, *tablespace; ! uint32 frozenxid, minmxid; datname = PQdb(conn); *************** dumpDatabase(Archive *fout) *** 2176,2187 **** selectSourceSchema(fout, "pg_catalog"); /* Get the database owner and parameters from pg_database */ ! if (fout->remoteVersion >= 80400) { appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " ! "datcollate, datctype, datfrozenxid, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, " "shobj_description(oid, 'pg_database') AS description " --- 2177,2202 ---- selectSourceSchema(fout, "pg_catalog"); /* Get the database owner and parameters from pg_database */ ! 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, 0 AS datminmxid, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, " "shobj_description(oid, 'pg_database') AS description " *************** dumpDatabase(Archive *fout) *** 2195,2201 **** appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " ! "NULL AS datcollate, NULL AS datctype, datfrozenxid, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, " "shobj_description(oid, 'pg_database') AS description " --- 2210,2216 ---- appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " ! "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 " *************** dumpDatabase(Archive *fout) *** 2209,2215 **** appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " ! "NULL AS datcollate, NULL AS datctype, datfrozenxid, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace " "FROM pg_database " "WHERE datname = ", --- 2224,2230 ---- appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " ! "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 = ", *************** dumpDatabase(Archive *fout) *** 2222,2228 **** "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "NULL AS datcollate, NULL AS datctype, " ! "0 AS datfrozenxid, " "NULL AS tablespace " "FROM pg_database " "WHERE datname = ", --- 2237,2243 ---- "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "NULL AS datcollate, NULL AS datctype, " ! "0 AS datfrozenxid, 0 AS datminmxid, " "NULL AS tablespace " "FROM pg_database " "WHERE datname = ", *************** dumpDatabase(Archive *fout) *** 2237,2243 **** "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "NULL AS datcollate, NULL AS datctype, " ! "0 AS datfrozenxid, " "NULL AS tablespace " "FROM pg_database " "WHERE datname = ", --- 2252,2258 ---- "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "NULL AS datcollate, NULL AS datctype, " ! "0 AS datfrozenxid, 0 AS datminmxid, " "NULL AS tablespace " "FROM pg_database " "WHERE datname = ", *************** dumpDatabase(Archive *fout) *** 2254,2259 **** --- 2269,2275 ---- 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)); *************** dumpDatabase(Archive *fout) *** 2263,2268 **** --- 2279,2285 ---- 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", *************** dumpDatabase(Archive *fout) *** 2289,2299 **** if (binary_upgrade) { ! appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n"); appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n" ! "SET datfrozenxid = '%u'\n" "WHERE datname = ", ! frozenxid); appendStringLiteralAH(creaQry, datname, fout); appendPQExpBufferStr(creaQry, ";\n"); --- 2306,2316 ---- if (binary_upgrade) { ! appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n"); appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n" ! "SET datfrozenxid = '%u', datminmxid = '%u'\n" "WHERE datname = ", ! frozenxid, minmxid); appendStringLiteralAH(creaQry, datname, fout); appendPQExpBufferStr(creaQry, ";\n"); *************** dumpDatabase(Archive *fout) *** 2324,2355 **** /* * pg_largeobject and pg_largeobject_metadata come from the old system ! * intact, so set their relfrozenxids. */ if (binary_upgrade) { PGresult *lo_res; PQExpBuffer loFrozenQry = createPQExpBuffer(); PQExpBuffer loOutQry = createPQExpBuffer(); ! int i_relfrozenxid; /* * pg_largeobject */ ! appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n" ! "FROM pg_catalog.pg_class\n" ! "WHERE oid = %u;\n", ! LargeObjectRelationId); lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data); i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); ! appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n"); appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" ! "SET relfrozenxid = '%u'\n" "WHERE oid = %u;\n", atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)), LargeObjectRelationId); ArchiveEntry(fout, nilCatalogId, createDumpId(), "pg_largeobject", NULL, NULL, "", --- 2341,2380 ---- /* * pg_largeobject and pg_largeobject_metadata come from the old system ! * intact, so set their relfrozenxids and relminmxids. */ if (binary_upgrade) { PGresult *lo_res; PQExpBuffer loFrozenQry = createPQExpBuffer(); PQExpBuffer loOutQry = createPQExpBuffer(); ! int i_relfrozenxid, i_relminmxid; /* * pg_largeobject */ ! 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 and relminmxid\n"); appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\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, "", *************** dumpDatabase(Archive *fout) *** 2368,2374 **** resetPQExpBuffer(loFrozenQry); resetPQExpBuffer(loOutQry); ! appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n" "FROM pg_catalog.pg_class\n" "WHERE oid = %u;\n", LargeObjectMetadataRelationId); --- 2393,2405 ---- resetPQExpBuffer(loFrozenQry); resetPQExpBuffer(loOutQry); ! 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); *************** dumpDatabase(Archive *fout) *** 2376,2387 **** lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data); i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); ! appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n"); appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" ! "SET relfrozenxid = '%u'\n" "WHERE oid = %u;\n", atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)), LargeObjectMetadataRelationId); ArchiveEntry(fout, nilCatalogId, createDumpId(), "pg_largeobject_metadata", NULL, NULL, "", --- 2407,2420 ---- 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 and relminmxid\n"); appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\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, "", *************** getTables(Archive *fout, int *numTables) *** 4255,4262 **** --- 4288,4297 ---- 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; *************** getTables(Archive *fout, int *numTables) *** 4304,4311 **** "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "c.relpersistence, c.relispopulated, " "c.relreplident, c.relpages, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " --- 4339,4347 ---- "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "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, " *************** getTables(Archive *fout, int *numTables) *** 4343,4350 **** "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "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, " --- 4379,4387 ---- "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "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, " *************** getTables(Archive *fout, int *numTables) *** 4382,4389 **** "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "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,4427 ---- "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "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, " *************** getTables(Archive *fout, int *numTables) *** 4419,4426 **** "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "'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, " --- 4457,4465 ---- "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "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, " *************** getTables(Archive *fout, int *numTables) *** 4455,4462 **** "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, c.relpages, " "NULL AS reloftype, " --- 4494,4502 ---- "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "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, " *************** getTables(Archive *fout, int *numTables) *** 4491,4498 **** "(%s c.relowner) AS rolname, " "c.relchecks, (c.reltriggers <> 0) AS relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, c.relpages, " "NULL AS reloftype, " --- 4531,4539 ---- "(%s c.relowner) AS rolname, " "c.relchecks, (c.reltriggers <> 0) AS relhastriggers, " "c.relhasindex, c.relhasrules, c.relhasoids, " ! "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, " *************** getTables(Archive *fout, int *numTables) *** 4527,4535 **** "(%s relowner) AS rolname, " "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, relhasoids, " ! "0 AS relfrozenxid, " "0 AS toid, " ! "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " --- 4568,4576 ---- "(%s relowner) AS rolname, " "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, relhasoids, " ! "0 AS relfrozenxid, 0 AS relminmxid," "0 AS toid, " ! "0 AS tfrozenxid, 0 AS tminmxid," "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " *************** getTables(Archive *fout, int *numTables) *** 4563,4571 **** "(%s relowner) AS rolname, " "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, relhasoids, " ! "0 AS relfrozenxid, " "0 AS toid, " ! "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " --- 4604,4612 ---- "(%s relowner) AS rolname, " "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, relhasoids, " ! "0 AS relfrozenxid, 0 AS relminmxid," "0 AS toid, " ! "0 AS tfrozenxid, 0 AS tminmxid," "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " *************** getTables(Archive *fout, int *numTables) *** 4595,4603 **** "(%s relowner) AS rolname, " "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, relhasoids, " ! "0 AS relfrozenxid, " "0 AS toid, " ! "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " --- 4636,4644 ---- "(%s relowner) AS rolname, " "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, relhasoids, " ! "0 AS relfrozenxid, 0 AS relminmxid," "0 AS toid, " ! "0 AS tfrozenxid, 0 AS tminmxid," "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " *************** getTables(Archive *fout, int *numTables) *** 4622,4630 **** "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, " "'t'::bool AS relhasoids, " ! "0 AS relfrozenxid, " "0 AS toid, " ! "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " --- 4663,4671 ---- "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, " "'t'::bool AS relhasoids, " ! "0 AS relfrozenxid, 0 AS relminmxid," "0 AS toid, " ! "0 AS tfrozenxid, 0 AS tminmxid," "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " "NULL AS reloftype, " *************** getTables(Archive *fout, int *numTables) *** 4659,4667 **** "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, " "'t'::bool AS relhasoids, " ! "0 as relfrozenxid, " "0 AS toid, " ! "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, 0 AS relpages, " "NULL AS reloftype, " --- 4700,4708 ---- "relchecks, (reltriggers <> 0) AS relhastriggers, " "relhasindex, relhasrules, " "'t'::bool AS relhasoids, " ! "0 AS relfrozenxid, 0 AS relminmxid," "0 AS toid, " ! "0 AS tfrozenxid, 0 AS tminmxid," "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, 0 AS relpages, " "NULL AS reloftype, " *************** getTables(Archive *fout, int *numTables) *** 4708,4715 **** --- 4749,4758 ---- 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"); *************** getTables(Archive *fout, int *numTables) *** 4760,4767 **** --- 4803,4812 ---- 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 *************** dumpTableSchema(Archive *fout, TableInfo *** 13525,13546 **** tbinfo->reloftype); } ! appendPQExpBufferStr(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); 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"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" ! "SET relfrozenxid = '%u'\n" "WHERE oid = '%u';\n", ! tbinfo->toast_frozenxid, tbinfo->toast_oid); } } --- 13570,13592 ---- tbinfo->reloftype); } ! appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" ! "SET relfrozenxid = '%u', relminmxid = '%u'\n" "WHERE oid = ", ! 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 and relminmxid\n"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" ! "SET relfrozenxid = '%u', relminmxid = '%u'\n" "WHERE oid = '%u';\n", ! tbinfo->toast_frozenxid, ! tbinfo->toast_minmxid, tbinfo->toast_oid); } } diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h new file mode 100644 index daf98bc..d184187 *** a/src/bin/pg_dump/pg_dump.h --- b/src/bin/pg_dump/pg_dump.h *************** typedef struct _tableInfo *** 247,254 **** --- 247,256 ---- 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: */ diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c new file mode 100644 index 0cc4329..bd19da6 *** a/src/bin/pg_dump/pg_dumpall.c --- b/src/bin/pg_dump/pg_dumpall.c *************** dumpCreateDB(PGconn *conn) *** 1241,1252 **** PQclear(res); /* Now collect all the information about databases to dump */ ! 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, " "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) " --- 1241,1262 ---- PQclear(res); /* Now collect all the information about databases to dump */ ! 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, 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) " *************** dumpCreateDB(PGconn *conn) *** 1256,1262 **** "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, " "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,1272 ---- "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, 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) " *************** dumpCreateDB(PGconn *conn) *** 1266,1272 **** "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, " "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,1282 ---- "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, 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) " *************** dumpCreateDB(PGconn *conn) *** 1276,1282 **** "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, " "datistemplate, datacl, -1 as datconnlimit, " "'pg_default' AS dattablespace " "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) " --- 1286,1292 ---- "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, 0 AS datminmxid, " "datistemplate, datacl, -1 as datconnlimit, " "'pg_default' AS dattablespace " "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) " *************** dumpCreateDB(PGconn *conn) *** 1288,1294 **** "(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, " "datistemplate, '' as datacl, -1 as datconnlimit, " "'pg_default' AS dattablespace " "FROM pg_database d " --- 1298,1304 ---- "(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, 0 AS datminmxid, " "datistemplate, '' as datacl, -1 as datconnlimit, " "'pg_default' AS dattablespace " "FROM pg_database d " *************** dumpCreateDB(PGconn *conn) *** 1303,1309 **** "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, " "'f' as datistemplate, " "'' as datacl, -1 as datconnlimit, " "'pg_default' AS dattablespace " --- 1313,1319 ---- "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, 0 AS datminmxid, " "'f' as datistemplate, " "'' as datacl, -1 as datconnlimit, " "'pg_default' AS dattablespace " *************** dumpCreateDB(PGconn *conn) *** 1319,1328 **** 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); char *fdbname; fdbname = pg_strdup(fmtId(dbname)); --- 1329,1339 ---- char *dbcollate = PQgetvalue(res, i, 3); char *dbctype = PQgetvalue(res, i, 4); uint32 dbfrozenxid = atooid(PQgetvalue(res, i, 5)); ! 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)); *************** dumpCreateDB(PGconn *conn) *** 1389,1399 **** if (binary_upgrade) { ! appendPQExpBufferStr(buf, "-- For binary upgrade, set datfrozenxid.\n"); appendPQExpBuffer(buf, "UPDATE pg_catalog.pg_database " ! "SET datfrozenxid = '%u' " "WHERE datname = ", ! dbfrozenxid); appendStringLiteralConn(buf, dbname, conn); appendPQExpBufferStr(buf, ";\n"); } --- 1400,1410 ---- if (binary_upgrade) { ! appendPQExpBufferStr(buf, "-- For binary upgrade, set datfrozenxid and datminmxid.\n"); appendPQExpBuffer(buf, "UPDATE pg_catalog.pg_database " ! "SET datfrozenxid = '%u', datminmxid = '%u' " "WHERE datname = ", ! dbfrozenxid, dbminmxid); appendStringLiteralConn(buf, dbname, conn); appendPQExpBufferStr(buf, ";\n"); }

view thread (78+ messages)  latest in thread

Message-ID: <20140701161419.GA16033@momjian.us>
Permalink:  ../20140701161419.GA16033@momjian.us/
Also on:    postgresql.org/message-id/20140701161419.GA16033@momjian.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: bruce@momjian.us, alvherre@2ndquadrant.com, andres@2ndquadrant.com
  Subject: Re: pg_upgrade < 9.3 -> >=9.3 misses a step around multixacts
  In-Reply-To: <20140701161419.GA16033@momjian.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox