mirror of https://github.com/postgres/postgres
pg_upgrade: preserve database and relation minmxid values
Also set these values for pre-9.3 old clusters that don't have values to preserve. Analysis by Alvaro Backpatch through 9.3
This commit is contained in:
parent
a36a8fa376
commit
a61daa14d5
|
@ -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,
|
||||
|
@ -545,13 +562,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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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, "
|
||||
"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) "
|
||||
|
@ -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));
|
||||
|
@ -1385,11 +1396,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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue