From 55c482b8f94a9967a81c07e097681229b9dc9aef Mon Sep 17 00:00:00 2001 From: Maxim Orlov Date: Fri, 25 Mar 2022 12:36:24 +0300 Subject: [PATCH v47 3/8] Use 64-bit FullTransactionId instead of Epoch:xid NextXid in controldata is now compatible with old format Epoch:xid and the new one. This is next step to make XIDs 64-bit. Author: Alexander Korotkov Author: Teodor Sigaev Author: Nikita Glukhov Author: Maxim Orlov Author: Pavel Borisov Author: Yura Sokolov Author: Aleksander Alekseev Reviewed-by: Aleksander Alekseev Discussion: https://postgr.es/m/CACG%3DezZe1NQSCnfHOr78AtAZxJZeCvxrts0ygrxYwe%3DpyyjVWA%40mail.gmail.com Discussion: https://postgr.es/m/CAJ7c6TPDOYBYrnCAeyndkBktO0WG2xSdYduTF0nxq%2BvfkmTF5Q%40mail.gmail.com --- contrib/amcheck/verify_heapam.c | 75 ++++++++++--------------- contrib/pageinspect/btreefuncs.c | 5 +- src/backend/access/rmgrdesc/gistdesc.c | 10 ++-- src/backend/access/rmgrdesc/nbtdesc.c | 10 ++-- src/backend/access/rmgrdesc/xlogdesc.c | 5 +- src/backend/utils/misc/pg_controldata.c | 5 +- src/bin/pg_controldata/pg_controldata.c | 5 +- src/bin/pg_upgrade/controldata.c | 32 +++++++++-- 8 files changed, 73 insertions(+), 74 deletions(-) diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index f0ab5fabec..c9e71e4e50 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -741,24 +741,21 @@ check_tuple_visibility(HeapCheckContext *ctx) break; case XID_IN_FUTURE: report_corruption(ctx, - psprintf("xmin %llu equals or exceeds next valid transaction ID %u:%llu", + psprintf("xmin %llu equals or exceeds next valid transaction ID %llu", (unsigned long long) xmin, - EpochFromFullTransactionId(ctx->next_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->next_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->next_fxid))); return false; case XID_PRECEDES_CLUSTERMIN: report_corruption(ctx, - psprintf("xmin %llu precedes oldest valid transaction ID %u:%llu", + psprintf("xmin %llu precedes oldest valid transaction ID %llu", (unsigned long long) xmin, - EpochFromFullTransactionId(ctx->oldest_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->oldest_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->oldest_fxid))); return false; case XID_PRECEDES_RELMIN: report_corruption(ctx, - psprintf("xmin %llu precedes relation freeze threshold %u:%llu", + psprintf("xmin %llu precedes relation freeze threshold %llu", (unsigned long long) xmin, - EpochFromFullTransactionId(ctx->relfrozenfxid), - (unsigned long long) XidFromFullTransactionId(ctx->relfrozenfxid))); + (unsigned long long) U64FromFullTransactionId(ctx->relfrozenfxid))); return false; } @@ -782,24 +779,21 @@ check_tuple_visibility(HeapCheckContext *ctx) return false; case XID_IN_FUTURE: report_corruption(ctx, - psprintf("old-style VACUUM FULL transaction ID %llu for moved off tuple equals or exceeds next valid transaction ID %u:%llu", + psprintf("old-style VACUUM FULL transaction ID %llu for moved off tuple equals or exceeds next valid transaction ID %llu", (unsigned long long) xvac, - EpochFromFullTransactionId(ctx->next_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->next_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->next_fxid))); return false; case XID_PRECEDES_RELMIN: report_corruption(ctx, - psprintf("old-style VACUUM FULL transaction ID %llu for moved off tuple precedes relation freeze threshold %u:%llu", + psprintf("old-style VACUUM FULL transaction ID %llu for moved off tuple precedes relation freeze threshold %llu", (unsigned long long) xvac, - EpochFromFullTransactionId(ctx->relfrozenfxid), - (unsigned long long) XidFromFullTransactionId(ctx->relfrozenfxid))); + (unsigned long long) U64FromFullTransactionId(ctx->relfrozenfxid))); return false; case XID_PRECEDES_CLUSTERMIN: report_corruption(ctx, - psprintf("old-style VACUUM FULL transaction ID %llu for moved off tuple precedes oldest valid transaction ID %u:%llu", + psprintf("old-style VACUUM FULL transaction ID %llu for moved off tuple precedes oldest valid transaction ID %llu", (unsigned long long) xvac, - EpochFromFullTransactionId(ctx->oldest_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->oldest_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->oldest_fxid))); return false; case XID_BOUNDS_OK: break; @@ -851,24 +845,21 @@ check_tuple_visibility(HeapCheckContext *ctx) return false; case XID_IN_FUTURE: report_corruption(ctx, - psprintf("old-style VACUUM FULL transaction ID %llu for moved in tuple equals or exceeds next valid transaction ID %u:%llu", + psprintf("old-style VACUUM FULL transaction ID %llu for moved in tuple equals or exceeds next valid transaction ID %llu", (unsigned long long) xvac, - EpochFromFullTransactionId(ctx->next_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->next_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->next_fxid))); return false; case XID_PRECEDES_RELMIN: report_corruption(ctx, - psprintf("old-style VACUUM FULL transaction ID %llu for moved in tuple precedes relation freeze threshold %u:%llu", + psprintf("old-style VACUUM FULL transaction ID %llu for moved in tuple precedes relation freeze threshold %llu", (unsigned long long) xvac, - EpochFromFullTransactionId(ctx->relfrozenfxid), - (unsigned long long) XidFromFullTransactionId(ctx->relfrozenfxid))); + (unsigned long long) U64FromFullTransactionId(ctx->relfrozenfxid))); return false; case XID_PRECEDES_CLUSTERMIN: report_corruption(ctx, - psprintf("old-style VACUUM FULL transaction ID %llu for moved in tuple precedes oldest valid transaction ID %u:%llu", + psprintf("old-style VACUUM FULL transaction ID %llu for moved in tuple precedes oldest valid transaction ID %llu", (unsigned long long) xvac, - EpochFromFullTransactionId(ctx->oldest_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->oldest_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->oldest_fxid))); return false; case XID_BOUNDS_OK: break; @@ -1014,24 +1005,21 @@ check_tuple_visibility(HeapCheckContext *ctx) return true; case XID_IN_FUTURE: report_corruption(ctx, - psprintf("update xid %llu equals or exceeds next valid transaction ID %u:%llu", + psprintf("update xid %llu equals or exceeds next valid transaction ID %llu", (unsigned long long) xmax, - EpochFromFullTransactionId(ctx->next_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->next_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->next_fxid))); return true; case XID_PRECEDES_RELMIN: report_corruption(ctx, - psprintf("update xid %llu precedes relation freeze threshold %u:%llu", + psprintf("update xid %llu precedes relation freeze threshold %llu", (unsigned long long) xmax, - EpochFromFullTransactionId(ctx->relfrozenfxid), - (unsigned long long) XidFromFullTransactionId(ctx->relfrozenfxid))); + (unsigned long long) U64FromFullTransactionId(ctx->relfrozenfxid))); return true; case XID_PRECEDES_CLUSTERMIN: report_corruption(ctx, - psprintf("update xid %llu precedes oldest valid transaction ID %u:%llu", + psprintf("update xid %llu precedes oldest valid transaction ID %llu", (unsigned long long) xmax, - EpochFromFullTransactionId(ctx->oldest_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->oldest_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->oldest_fxid))); return true; case XID_BOUNDS_OK: break; @@ -1076,24 +1064,21 @@ check_tuple_visibility(HeapCheckContext *ctx) { case XID_IN_FUTURE: report_corruption(ctx, - psprintf("xmax %llu equals or exceeds next valid transaction ID %u:%llu", + psprintf("xmax %llu equals or exceeds next valid transaction ID %llu", (unsigned long long) xmax, - EpochFromFullTransactionId(ctx->next_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->next_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->next_fxid))); return false; /* corrupt */ case XID_PRECEDES_RELMIN: report_corruption(ctx, - psprintf("xmax %llu precedes relation freeze threshold %u:%llu", + psprintf("xmax %llu precedes relation freeze threshold %llu", (unsigned long long) xmax, - EpochFromFullTransactionId(ctx->relfrozenfxid), - (unsigned long long) XidFromFullTransactionId(ctx->relfrozenfxid))); + (unsigned long long) U64FromFullTransactionId(ctx->relfrozenfxid))); return false; /* corrupt */ case XID_PRECEDES_CLUSTERMIN: report_corruption(ctx, - psprintf("xmax %llu precedes oldest valid transaction ID %u:%llu", + psprintf("xmax %llu precedes oldest valid transaction ID %llu", (unsigned long long) xmax, - EpochFromFullTransactionId(ctx->oldest_fxid), - (unsigned long long) XidFromFullTransactionId(ctx->oldest_fxid))); + (unsigned long long) U64FromFullTransactionId(ctx->oldest_fxid))); return false; /* corrupt */ case XID_BOUNDS_OK: case XID_INVALID: diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c index 9f120a7bf3..b18aa0af7f 100644 --- a/contrib/pageinspect/btreefuncs.c +++ b/contrib/pageinspect/btreefuncs.c @@ -125,9 +125,8 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat) { FullTransactionId safexid = BTPageGetDeleteXid(page); - elog(DEBUG2, "deleted page from block %u has safexid %u:%llu", - blkno, EpochFromFullTransactionId(safexid), - (unsigned long long) XidFromFullTransactionId(safexid)); + elog(DEBUG2, "deleted page from block %u has safexid %llu", + blkno, (unsigned long long) U64FromFullTransactionId(safexid)); } else elog(DEBUG2, "deleted page from block %u has safexid %u", diff --git a/src/backend/access/rmgrdesc/gistdesc.c b/src/backend/access/rmgrdesc/gistdesc.c index bda471f5d4..ad855894be 100644 --- a/src/backend/access/rmgrdesc/gistdesc.c +++ b/src/backend/access/rmgrdesc/gistdesc.c @@ -26,11 +26,10 @@ out_gistxlogPageUpdate(StringInfo buf, gistxlogPageUpdate *xlrec) static void out_gistxlogPageReuse(StringInfo buf, gistxlogPageReuse *xlrec) { - appendStringInfo(buf, "rel %u/%u/%u; blk %u; latestRemovedXid %u:%llu", + appendStringInfo(buf, "rel %u/%u/%u; blk %u; latestRemovedXid %llu", xlrec->locator.spcOid, xlrec->locator.dbOid, xlrec->locator.relNumber, xlrec->block, - EpochFromFullTransactionId(xlrec->latestRemovedFullXid), - (unsigned long long) XidFromFullTransactionId(xlrec->latestRemovedFullXid)); + (unsigned long long) U64FromFullTransactionId(xlrec->latestRemovedFullXid)); } static void @@ -51,9 +50,8 @@ out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec) static void out_gistxlogPageDelete(StringInfo buf, gistxlogPageDelete *xlrec) { - appendStringInfo(buf, "deleteXid %u:%llu; downlink %u", - EpochFromFullTransactionId(xlrec->deleteXid), - (unsigned long long) XidFromFullTransactionId(xlrec->deleteXid), + appendStringInfo(buf, "deleteXid %llu; downlink %u", + (unsigned long long) U64FromFullTransactionId(xlrec->deleteXid), xlrec->downlinkOffset); } diff --git a/src/backend/access/rmgrdesc/nbtdesc.c b/src/backend/access/rmgrdesc/nbtdesc.c index 9ad2287a71..bf25c941e4 100644 --- a/src/backend/access/rmgrdesc/nbtdesc.c +++ b/src/backend/access/rmgrdesc/nbtdesc.c @@ -81,10 +81,9 @@ btree_desc(StringInfo buf, XLogReaderState *record) { xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) rec; - appendStringInfo(buf, "left %u; right %u; level %u; safexid %u:%llu; ", + appendStringInfo(buf, "left %u; right %u; level %u; safexid %llu; ", xlrec->leftsib, xlrec->rightsib, xlrec->level, - EpochFromFullTransactionId(xlrec->safexid), - (unsigned long long) XidFromFullTransactionId(xlrec->safexid)); + (unsigned long long) U64FromFullTransactionId(xlrec->safexid)); appendStringInfo(buf, "leafleft %u; leafright %u; leaftopparent %u", xlrec->leafleftsib, xlrec->leafrightsib, xlrec->leaftopparent); @@ -101,11 +100,10 @@ btree_desc(StringInfo buf, XLogReaderState *record) { xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec; - appendStringInfo(buf, "rel %u/%u/%u; latestRemovedXid %u:%llu", + appendStringInfo(buf, "rel %u/%u/%u; latestRemovedXid %llu", xlrec->locator.spcOid, xlrec->locator.dbOid, xlrec->locator.relNumber, - EpochFromFullTransactionId(xlrec->latestRemovedFullXid), - (unsigned long long) XidFromFullTransactionId(xlrec->latestRemovedFullXid)); + (unsigned long long) U64FromFullTransactionId(xlrec->latestRemovedFullXid)); break; } case XLOG_BTREE_META_CLEANUP: diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c index 3d30cc18c6..647d64dc9a 100644 --- a/src/backend/access/rmgrdesc/xlogdesc.c +++ b/src/backend/access/rmgrdesc/xlogdesc.c @@ -45,7 +45,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record) CheckPoint *checkpoint = (CheckPoint *) rec; appendStringInfo(buf, "redo %X/%X; " - "tli %u; prev tli %u; fpw %s; xid %u:%llu; oid %u; multi %llu; offset %u; " + "tli %u; prev tli %u; fpw %s; xid %llu; oid %u; multi %llu; offset %u; " "oldest xid %llu in DB %u; oldest multi %llu in DB %u; " "oldest/newest commit timestamp xid: %llu/%llu; " "oldest running xid %llu; %s", @@ -53,8 +53,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record) checkpoint->ThisTimeLineID, checkpoint->PrevTimeLineID, checkpoint->fullPageWrites ? "true" : "false", - EpochFromFullTransactionId(checkpoint->nextXid), - (unsigned long long) XidFromFullTransactionId(checkpoint->nextXid), + (unsigned long long) U64FromFullTransactionId(checkpoint->nextXid), checkpoint->nextOid, (unsigned long long) checkpoint->nextMulti, checkpoint->nextMultiOffset, diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index 88f6f33ef5..4ab4a0a701 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -164,9 +164,8 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites); nulls[5] = false; - values[6] = CStringGetTextDatum(psprintf("%u:%llu", - EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid), - (unsigned long long) XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid))); + values[6] = CStringGetTextDatum(psprintf("%llu", + (unsigned long long) U64FromFullTransactionId(ControlFile->checkPointCopy.nextXid))); nulls[6] = false; values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid); diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index 2c10322355..a8a46d5bf0 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -247,9 +247,8 @@ main(int argc, char *argv[]) ControlFile->checkPointCopy.PrevTimeLineID); printf(_("Latest checkpoint's full_page_writes: %s\n"), ControlFile->checkPointCopy.fullPageWrites ? _("on") : _("off")); - printf(_("Latest checkpoint's NextXID: %u:%llu\n"), - EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid), - (unsigned long long) XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)); + printf(_("Latest checkpoint's NextXID: %llu\n"), + (unsigned long long) U64FromFullTransactionId(ControlFile->checkPointCopy.nextXid)); printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile->checkPointCopy.nextOid); printf(_("Latest checkpoint's NextMultiXactId: %llu\n"), diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index 018cd310f7..a5b4a77570 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -8,6 +8,7 @@ */ #include "postgres_fe.h" +#include "access/transam.h" #include @@ -265,13 +266,22 @@ get_control_data(ClusterInfo *cluster, bool live_check) } else if ((p = strstr(bufin, "Latest checkpoint's NextXID:")) != NULL) { + FullTransactionId xid; + p = strchr(p, ':'); if (p == NULL || strlen(p) <= 1) pg_fatal("%d: controldata retrieval problem", __LINE__); p++; /* remove ':' char */ - cluster->controldata.chkpnt_nxtepoch = str2uint(p); + + /* + * NextXID representation in controldata file changed from Epoch:Xid + * to 64-bit FullTransactionId representation as a part of making + * xids 64-bit in the future. Here we support both controldata + * formats. + */ + xid.value = strtou64(p, NULL, 10); /* * Delimiter changed from '/' to ':' in 9.6. We don't test for @@ -286,11 +296,23 @@ get_control_data(ClusterInfo *cluster, bool live_check) else p = NULL; - if (p == NULL || strlen(p) <= 1) - pg_fatal("%d: controldata retrieval problem", __LINE__); + if (p == NULL) + { + /* FullTransactionId representation */ + cluster->controldata.chkpnt_nxtxid = XidFromFullTransactionId(xid); + cluster->controldata.chkpnt_nxtepoch = EpochFromFullTransactionId(xid); + } + else + { + if (strlen(p) <= 1) + pg_fatal("%d: controldata retrieval problem", __LINE__); + + /* Epoch:Xid representation */ + p++; /* remove '/' or ':' char */ + cluster->controldata.chkpnt_nxtxid = str2uint(p); + cluster->controldata.chkpnt_nxtepoch = (TransactionId) XidFromFullTransactionId(xid); + } - p++; /* remove '/' or ':' char */ - cluster->controldata.chkpnt_nxtxid = str2uint(p); got_xid = true; } else if ((p = strstr(bufin, "Latest checkpoint's NextOID:")) != NULL) -- 2.37.0 (Apple Git-136)