From 573e446f6f5963a0edad575130743eb75887d087 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 19 May 2010 18:27:43 +0000 Subject: [PATCH] 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. --- contrib/pg_upgrade/pg_upgrade.c | 57 ++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c index fc692fc96a..7d7abe6c23 100644 --- a/contrib/pg_upgrade/pg_upgrade.c +++ b/contrib/pg_upgrade/pg_upgrade.c @@ -164,7 +164,10 @@ prepare_new_cluster(migratorContext *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"); exec_prog(ctx, true, @@ -292,48 +295,72 @@ void set_frozenxids(migratorContext *ctx) { int dbnum; - PGconn *conn; + PGconn *conn, *conn_template1; PGresult *dbres; int ntups; + int i_datname; + int i_datallowconn; 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 */ - PQclear(executeQueryOrDie(ctx, conn, + PQclear(executeQueryOrDie(ctx, conn_template1, "UPDATE pg_catalog.pg_database " - "SET datfrozenxid = '%u' " - "WHERE datallowconn = true", + "SET datfrozenxid = '%u'", ctx->old.controldata.chkpnt_nxtxid)); /* get database names */ - dbres = executeQueryOrDie(ctx, conn, - "SELECT datname " - "FROM pg_catalog.pg_database " - "WHERE datallowconn = true"); + dbres = executeQueryOrDie(ctx, conn_template1, + "SELECT datname, datallowconn " + "FROM pg_catalog.pg_database"); - /* free dbres below */ - PQfinish(conn); + i_datname = PQfnumber(dbres, "datname"); + i_datallowconn = PQfnumber(dbres, "datallowconn"); ntups = PQntuples(dbres); 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 */ PQclear(executeQueryOrDie(ctx, conn, "UPDATE pg_catalog.pg_class " "SET relfrozenxid = '%u' " /* only heap and TOAST are vacuumed */ - "WHERE relkind = 'r' OR " - " relkind = 't'", + "WHERE relkind IN ('r', 't')", ctx->old.controldata.chkpnt_nxtxid)); 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); + PQfinish(conn_template1); + check_ok(ctx); } -- 2.40.0