v1-0001-pg-upgrade-keep-oldestxid.patch
text/plain
Filename: v1-0001-pg-upgrade-keep-oldestxid.patch
Type: text/plain
Part: 0
Patch
Format: unified
Series: patch v1-0001
| File | + | − |
|---|---|---|
| src/bin/pg_resetwal/pg_resetwal.c | 35 | 26 |
| src/bin/pg_upgrade/controldata.c | 16 | 1 |
| src/bin/pg_upgrade/pg_upgrade.c | 6 | 0 |
| src/bin/pg_upgrade/pg_upgrade.h | 1 | 0 |
src/bin/pg_resetwal/pg_resetwal.c | 61 ++++++++++++++++++++++-----------------
src/bin/pg_upgrade/controldata.c | 17 ++++++++++-
src/bin/pg_upgrade/pg_upgrade.c | 6 ++++
src/bin/pg_upgrade/pg_upgrade.h | 1 +
4 files changed, 58 insertions(+), 27 deletions(-)
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index 805dafef07..66c746de11 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -65,6 +65,7 @@ static bool guessed = false; /* T if we had to guess at any values */
static const char *progname;
static uint32 set_xid_epoch = (uint32) -1;
static TransactionId set_xid = 0;
+static TransactionId set_oldest_unfrozen_xid = 0;
static TransactionId set_oldest_commit_ts_xid = 0;
static TransactionId set_newest_commit_ts_xid = 0;
static Oid set_oid = 0;
@@ -102,6 +103,7 @@ main(int argc, char *argv[])
{"next-oid", required_argument, NULL, 'o'},
{"multixact-offset", required_argument, NULL, 'O'},
{"next-transaction-id", required_argument, NULL, 'x'},
+ {"oldest-transaction-id", required_argument, NULL, 'u'},
{"wal-segsize", required_argument, NULL, 1},
{NULL, 0, NULL, 0}
};
@@ -135,7 +137,7 @@ main(int argc, char *argv[])
}
- while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:x:", long_options, NULL)) != -1)
+ while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:x:u:", long_options, NULL)) != -1)
{
switch (c)
{
@@ -183,6 +185,21 @@ main(int argc, char *argv[])
}
break;
+ case 'u':
+ set_oldest_unfrozen_xid = strtoul(optarg, &endptr, 0);
+ if (endptr == optarg || *endptr != '\0')
+ {
+ pg_log_error("invalid argument for option %s", "-u");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
+ }
+ if (set_oldest_unfrozen_xid == 0)
+ {
+ pg_log_error("oldest unfrozen transaction ID (-u) must not be 0");
+ exit(1);
+ }
+ break;
+
case 'c':
set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
if (endptr == optarg || *endptr != ',')
@@ -429,21 +446,12 @@ main(int argc, char *argv[])
XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid));
if (set_xid != 0)
- {
ControlFile.checkPointCopy.nextXid =
FullTransactionIdFromEpochAndXid(EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid),
set_xid);
- /*
- * For the moment, just set oldestXid to a value that will force
- * immediate autovacuum-for-wraparound. It's not clear whether adding
- * user control of this is useful, so let's just do something that's
- * reasonably safe. The magic constant here corresponds to the
- * maximum allowed value of autovacuum_freeze_max_age.
- */
- ControlFile.checkPointCopy.oldestXid = set_xid - 2000000000;
- if (ControlFile.checkPointCopy.oldestXid < FirstNormalTransactionId)
- ControlFile.checkPointCopy.oldestXid += FirstNormalTransactionId;
+ if (set_oldest_unfrozen_xid != 0) {
+ ControlFile.checkPointCopy.oldestXid = set_oldest_unfrozen_xid;
ControlFile.checkPointCopy.oldestXidDB = InvalidOid;
}
@@ -1209,20 +1217,21 @@ usage(void)
printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
printf(_("Options:\n"));
printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
- " set oldest and newest transactions bearing\n"
- " commit timestamp (zero means no change)\n"));
- printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
- printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
- printf(_(" -f, --force force update to be done\n"));
- printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
- printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
- printf(_(" -n, --dry-run no update, just show what would be done\n"));
- printf(_(" -o, --next-oid=OID set next OID\n"));
- printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
- printf(_(" -V, --version output version information, then exit\n"));
- printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
- printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
- printf(_(" -?, --help show this help, then exit\n"));
+ " set oldest and newest transactions bearing\n"
+ " commit timestamp (zero means no change)\n"));
+ printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
+ printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
+ printf(_(" -f, --force force update to be done\n"));
+ printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
+ printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
+ printf(_(" -n, --dry-run no update, just show what would be done\n"));
+ printf(_(" -o, --next-oid=OID set next OID\n"));
+ printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
+ printf(_(" -u, --oldest-transaction-id=XID set oldest unfrozen transaction ID\n"));
+ printf(_(" -V, --version output version information, then exit\n"));
+ printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
+ printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
+ printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
}
diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c
index 4f647cdf33..a4b6375403 100644
--- a/src/bin/pg_upgrade/controldata.c
+++ b/src/bin/pg_upgrade/controldata.c
@@ -44,6 +44,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
bool got_oid = false;
bool got_multi = false;
bool got_oldestmulti = false;
+ bool got_oldestxid = false;
bool got_mxoff = false;
bool got_nextxlogfile = false;
bool got_float8_pass_by_value = false;
@@ -312,6 +313,17 @@ get_control_data(ClusterInfo *cluster, bool live_check)
cluster->controldata.chkpnt_nxtmulti = str2uint(p);
got_multi = true;
}
+ else if ((p = strstr(bufin, "Latest checkpoint's oldestXID:")) != NULL)
+ {
+ p = strchr(p, ':');
+
+ if (p == NULL || strlen(p) <= 1)
+ pg_fatal("%d: controldata retrieval problem\n", __LINE__);
+
+ p++; /* remove ':' char */
+ cluster->controldata.chkpnt_oldstxid = str2uint(p);
+ got_oldestxid = true;
+ }
else if ((p = strstr(bufin, "Latest checkpoint's oldestMultiXid:")) != NULL)
{
p = strchr(p, ':');
@@ -544,7 +556,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
/* verify that we got all the mandatory pg_control data */
if (!got_xid || !got_oid ||
- !got_multi ||
+ !got_multi || !got_oldestxid ||
(!got_oldestmulti &&
cluster->controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER) ||
!got_mxoff || (!live_check && !got_nextxlogfile) ||
@@ -575,6 +587,9 @@ get_control_data(ClusterInfo *cluster, bool live_check)
cluster->controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER)
pg_log(PG_REPORT, " latest checkpoint oldest MultiXactId\n");
+ if (!got_oldestxid)
+ pg_log(PG_REPORT, " latest checkpoint oldestXID\n");
+
if (!got_mxoff)
pg_log(PG_REPORT, " latest checkpoint next MultiXactOffset\n");
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index e23b8ca88d..950ff24980 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -473,6 +473,12 @@ copy_xact_xlog_xid(void)
"\"%s/pg_resetwal\" -f -x %u \"%s\"",
new_cluster.bindir, old_cluster.controldata.chkpnt_nxtxid,
new_cluster.pgdata);
+ check_ok();
+ prep_status("Setting oldest XID for new cluster");
+ exec_prog(UTILITY_LOG_FILE, NULL, true, true,
+ "\"%s/pg_resetwal\" -f -u %u \"%s\"",
+ new_cluster.bindir, old_cluster.controldata.chkpnt_oldstxid,
+ new_cluster.pgdata);
exec_prog(UTILITY_LOG_FILE, NULL, true, true,
"\"%s/pg_resetwal\" -f -e %u \"%s\"",
new_cluster.bindir, old_cluster.controldata.chkpnt_nxtepoch,
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index d7666da3f2..b775ba31e5 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -207,6 +207,7 @@ typedef struct
uint32 chkpnt_nxtmulti;
uint32 chkpnt_nxtmxoff;
uint32 chkpnt_oldstMulti;
+ uint32 chkpnt_oldstxid;
uint32 align;
uint32 blocksz;
uint32 largesz;