Skip to content

Commit a61daa1

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 a36a8fa commit a61daa1

File tree

5 files changed

+171
-83
lines changed

5 files changed

+171
-83
lines changed

contrib/pg_upgrade/pg_upgrade.c

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static void prepare_new_cluster(void);
4646
static void prepare_new_databases(void);
4747
static void create_new_objects(void);
4848
static void copy_clog_xlog_xid(void);
49-
static void set_frozenxids(void);
49+
static void set_frozenxids(bool minmxid_only);
5050
static void setup(char *argv0, bool *live_check);
5151
static void cleanup(void);
5252

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

276-
set_frozenxids();
276+
set_frozenxids(false);
277277

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

@@ -356,6 +356,13 @@ create_new_objects(void)
356356
end_progress_output();
357357
check_ok();
358358

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

@@ -489,15 +496,15 @@ copy_clog_xlog_xid(void)
489496
/*
490497
* set_frozenxids()
491498
*
492-
* We have frozen all xids, so set relfrozenxid and datfrozenxid
493-
* to be the old cluster's xid counter, which we just set in the new
494-
* cluster. User-table frozenxid values will be set by pg_dump
495-
* --binary-upgrade, but objects not set by the pg_dump must have
496-
* proper frozen counters.
499+
* We have frozen all xids, so set datfrozenxid, relfrozenxid, and
500+
* relminmxid to be the old cluster's xid counter, which we just set
501+
* in the new cluster. User-table frozenxid and minmxid values will
502+
* be set by pg_dump --binary-upgrade, but objects not set by the pg_dump
503+
* must have proper frozen counters.
497504
*/
498505
static
499506
void
500-
set_frozenxids(void)
507+
set_frozenxids(bool minmxid_only)
501508
{
502509
int dbnum;
503510
PGconn *conn,
@@ -507,15 +514,25 @@ set_frozenxids(void)
507514
int i_datname;
508515
int i_datallowconn;
509516

510-
prep_status("Setting frozenxid counters in new cluster");
517+
if (!minmxid_only)
518+
prep_status("Setting frozenxid and minmxid counters in new cluster");
519+
else
520+
prep_status("Setting minmxid counter in new cluster");
511521

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

514-
/* set pg_database.datfrozenxid */
524+
if (!minmxid_only)
525+
/* set pg_database.datfrozenxid */
526+
PQclear(executeQueryOrDie(conn_template1,
527+
"UPDATE pg_catalog.pg_database "
528+
"SET datfrozenxid = '%u'",
529+
old_cluster.controldata.chkpnt_nxtxid));
530+
531+
/* set pg_database.datminmxid */
515532
PQclear(executeQueryOrDie(conn_template1,
516533
"UPDATE pg_catalog.pg_database "
517-
"SET datfrozenxid = '%u'",
518-
old_cluster.controldata.chkpnt_nxtxid));
534+
"SET datminmxid = '%u'",
535+
old_cluster.controldata.chkpnt_nxtmulti));
519536

520537
/* get database names */
521538
dbres = executeQueryOrDie(conn_template1,
@@ -533,10 +550,10 @@ set_frozenxids(void)
533550

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

546563
conn = connectToServer(&new_cluster, datname);
547564

548-
/* set pg_class.relfrozenxid */
565+
if (!minmxid_only)
566+
/* set pg_class.relfrozenxid */
567+
PQclear(executeQueryOrDie(conn,
568+
"UPDATE pg_catalog.pg_class "
569+
"SET relfrozenxid = '%u' "
570+
/* only heap, materialized view, and TOAST are vacuumed */
571+
"WHERE relkind IN ('r', 'm', 't')",
572+
old_cluster.controldata.chkpnt_nxtxid));
573+
574+
/* set pg_class.relminmxid */
549575
PQclear(executeQueryOrDie(conn,
550576
"UPDATE pg_catalog.pg_class "
551-
"SET relfrozenxid = '%u' "
577+
"SET relminmxid = '%u' "
552578
/* only heap, materialized view, and TOAST are vacuumed */
553579
"WHERE relkind IN ('r', 'm', 't')",
554-
old_cluster.controldata.chkpnt_nxtxid));
580+
old_cluster.controldata.chkpnt_nxtmulti));
555581
PQfinish(conn);
556582

557583
/* 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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy