Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+47-21
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

+8-5
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)