Skip to content

Commit 3d2e185

Browse files
committed
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
1 parent 110d293 commit 3d2e185

File tree

5 files changed

+164
-77
lines changed

5 files changed

+164
-77
lines changed

contrib/pg_upgrade/pg_upgrade.c

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static void prepare_new_cluster(void);
4747
static void prepare_new_databases(void);
4848
static void create_new_objects(void);
4949
static void copy_clog_xlog_xid(void);
50-
static void set_frozenxids(void);
50+
static void set_frozenxids(bool minmxid_only);
5151
static void setup(char *argv0, bool *live_check);
5252
static void cleanup(void);
5353

@@ -251,8 +251,8 @@ prepare_new_cluster(void)
251251
/*
252252
* We do freeze after analyze so pg_statistic is also frozen. template0 is
253253
* not frozen here, but data rows were frozen by initdb, and we set its
254-
* datfrozenxid and relfrozenxids later to match the new xid counter
255-
* later.
254+
* datfrozenxid, relfrozenxids, and relminmxid later to match the new xid
255+
* counter later.
256256
*/
257257
prep_status("Freezing all rows on the new cluster");
258258
exec_prog(UTILITY_LOG_FILE, NULL, true,
@@ -274,7 +274,7 @@ prepare_new_databases(void)
274274
* set.
275275
*/
276276

277-
set_frozenxids();
277+
set_frozenxids(false);
278278

279279
prep_status("Restoring global objects in the new cluster");
280280

@@ -357,6 +357,13 @@ create_new_objects(void)
357357
end_progress_output();
358358
check_ok();
359359

360+
/*
361+
* We don't have minmxids for databases or relations in pre-9.3
362+
* clusters, so set those after we have restores the schemas.
363+
*/
364+
if (GET_MAJOR_VERSION(old_cluster.major_version) < 903)
365+
set_frozenxids(true);
366+
360367
/* regenerate now that we have objects in the databases */
361368
get_db_and_rel_infos(&new_cluster);
362369

@@ -498,7 +505,7 @@ copy_clog_xlog_xid(void)
498505
*/
499506
static
500507
void
501-
set_frozenxids(void)
508+
set_frozenxids(bool minmxid_only)
502509
{
503510
int dbnum;
504511
PGconn *conn,
@@ -508,15 +515,25 @@ set_frozenxids(void)
508515
int i_datname;
509516
int i_datallowconn;
510517

511-
prep_status("Setting frozenxid counters in new cluster");
518+
if (!minmxid_only)
519+
prep_status("Setting frozenxid and minmxid counters in new cluster");
520+
else
521+
prep_status("Setting minmxid counter in new cluster");
512522

513523
conn_template1 = connectToServer(&new_cluster, "template1");
514524

515-
/* set pg_database.datfrozenxid */
525+
if (!minmxid_only)
526+
/* set pg_database.datfrozenxid */
527+
PQclear(executeQueryOrDie(conn_template1,
528+
"UPDATE pg_catalog.pg_database "
529+
"SET datfrozenxid = '%u'",
530+
old_cluster.controldata.chkpnt_nxtxid));
531+
532+
/* set pg_database.datminmxid */
516533
PQclear(executeQueryOrDie(conn_template1,
517534
"UPDATE pg_catalog.pg_database "
518-
"SET datfrozenxid = '%u'",
519-
old_cluster.controldata.chkpnt_nxtxid));
535+
"SET datminmxid = '%u'",
536+
old_cluster.controldata.chkpnt_nxtmulti));
520537

521538
/* get database names */
522539
dbres = executeQueryOrDie(conn_template1,
@@ -534,10 +551,10 @@ set_frozenxids(void)
534551

535552
/*
536553
* We must update databases where datallowconn = false, e.g.
537-
* template0, because autovacuum increments their datfrozenxids and
538-
* relfrozenxids even if autovacuum is turned off, and even though all
539-
* the data rows are already frozen To enable this, we temporarily
540-
* change datallowconn.
554+
* template0, because autovacuum increments their datfrozenxids,
555+
* relfrozenxids, and relminmxid even if autovacuum is turned off,
556+
* and even though all the data rows are already frozen To enable
557+
* this, we temporarily change datallowconn.
541558
*/
542559
if (strcmp(datallowconn, "f") == 0)
543560
PQclear(executeQueryOrDie(conn_template1,
@@ -547,13 +564,22 @@ set_frozenxids(void)
547564

548565
conn = connectToServer(&new_cluster, datname);
549566

550-
/* set pg_class.relfrozenxid */
567+
if (!minmxid_only)
568+
/* set pg_class.relfrozenxid */
569+
PQclear(executeQueryOrDie(conn,
570+
"UPDATE pg_catalog.pg_class "
571+
"SET relfrozenxid = '%u' "
572+
/* only heap, materialized view, and TOAST are vacuumed */
573+
"WHERE relkind IN ('r', 'm', 't')",
574+
old_cluster.controldata.chkpnt_nxtxid));
575+
576+
/* set pg_class.relminmxid */
551577
PQclear(executeQueryOrDie(conn,
552578
"UPDATE pg_catalog.pg_class "
553-
"SET relfrozenxid = '%u' "
579+
"SET relminmxid = '%u' "
554580
/* only heap, materialized view, and TOAST are vacuumed */
555581
"WHERE relkind IN ('r', 'm', 't')",
556-
old_cluster.controldata.chkpnt_nxtxid));
582+
old_cluster.controldata.chkpnt_nxtmulti));
557583
PQfinish(conn);
558584

559585
/* Reset datallowconn flag */

contrib/pg_upgrade/server.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,22 +203,25 @@ start_postmaster(ClusterInfo *cluster, bool throw_error)
203203

204204
/*
205205
* Using autovacuum=off disables cleanup vacuum and analyze, but freeze
206-
* vacuums can still happen, so we set autovacuum_freeze_max_age to its
207-
* maximum. We assume all datfrozenxid and relfrozen values are less than
208-
* a gap of 2000000000 from the current xid counter, so autovacuum will
209-
* not touch them.
206+
* vacuums can still happen, so we set autovacuum_freeze_max_age and
207+
* autovacuum_multixact_freeze_max_age to their maximums. We assume all
208+
* datfrozenxid, relfrozenxid, and relminmxid values are less than a gap
209+
* of 2000000000 from the current xid counter, so autovacuum will not
210+
* touch them.
210211
*
211212
* Turn off durability requirements to improve object creation speed, and
212213
* we only modify the new cluster, so only use it there. If there is a
213214
* crash, the new cluster has to be recreated anyway. fsync=off is a big
214215
* win on ext4.
215216
*/
216217
snprintf(cmd, sizeof(cmd),
217-
"\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s %s%s\" start",
218+
"\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s %s%s%s\" start",
218219
cluster->bindir, SERVER_LOG_FILE, cluster->pgconfig, cluster->port,
219220
(cluster->controldata.cat_ver >=
220221
BINARY_UPGRADE_SERVER_FLAG_CAT_VER) ? " -b" :
221222
" -c autovacuum=off -c autovacuum_freeze_max_age=2000000000",
223+
(GET_MAJOR_VERSION(cluster->major_version) >= 903) ?
224+
" -c autovacuum_multixact_freeze_max_age=2000000000" : "",
222225
(cluster == &new_cluster) ?
223226
" -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "",
224227
cluster->pgopts ? cluster->pgopts : "", socket_string);

0 commit comments

Comments
 (0)