For pg_upgrade, update template0's datfrozenxid and its relfrozenxids to

match the behavior of autovacuum, which does this as the xid advances
even if autovacuum is turned off.
This commit is contained in:
Bruce Momjian 2010-05-19 18:27:43 +00:00
parent 3ef9574102
commit 573e446f6f

View File

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