diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c
index 2d40c14e00..f04455da12 100644
--- a/contrib/pageinspect/heapfuncs.c
+++ b/contrib/pageinspect/heapfuncs.c
@@ -211,7 +211,6 @@ heap_page_items(PG_FUNCTION_ARGS)
 			lp_offset == MAXALIGN(lp_offset) &&
 			lp_offset + lp_len <= raw_page_size)
 		{
-			HeapTupleData	tup;
 			HeapTupleHeader tuphdr;
 			bytea	   *tuple_data_bytea;
 			int			tuple_data_len;
@@ -219,18 +218,9 @@ heap_page_items(PG_FUNCTION_ARGS)
 			/* Extract information from the tuple header */
 
 			tuphdr = (HeapTupleHeader) PageGetItem(page, id);
-			tup.t_data = tuphdr;
-			HeapTupleCopyBaseFromPage(&tup, page);
 
 			values[4] = UInt32GetDatum(HeapTupleHeaderGetRawXmin(tuphdr));
 			values[5] = UInt32GetDatum(HeapTupleHeaderGetRawXmax(tuphdr));
-#ifdef UNUSED
-			// TBD 64bit XID - replace values[4] and [5] above
--			values[4] = UInt32GetDatum(HeapTupleHeaderGetRawXmin(tuphdr));
--			values[5] = UInt32GetDatum(HeapTupleHeaderGetRawXmax(tuphdr));
-+			values[4] = TransactionIdGetDatum(HeapTupleGetXmin(&tup));
-+			values[5] = TransactionIdGetDatum(HeapTupleGetRawXmax(&tup));
-#endif
 			/* shared with xvac */
 			values[6] = UInt32GetDatum(HeapTupleHeaderGetRawCommandId(tuphdr));
 			values[7] = PointerGetDatum(&tuphdr->t_ctid);
diff --git a/contrib/pageinspect/pageinspect--1.5.sql b/contrib/pageinspect/pageinspect--1.5.sql
index afd0f565ff..1e40c3c97e 100644
--- a/contrib/pageinspect/pageinspect--1.5.sql
+++ b/contrib/pageinspect/pageinspect--1.5.sql
@@ -28,9 +28,7 @@ CREATE FUNCTION page_header(IN page bytea,
     OUT special smallint,
     OUT pagesize smallint,
     OUT version smallint,
-    OUT prune_xid xid,  -- TBD FIXME: the original patch had this last, but it is output [9] in page_header
-    OUT xid_base xid,   -- TBD FIXME: this should be an xid8 for true 64-bit xids, shouldn't it?
-    OUT multi_base xid) -- TBD FIXME: xid8?
+    OUT prune_xid xid)
 AS 'MODULE_PATHNAME', 'page_header'
 LANGUAGE C STRICT PARALLEL SAFE;
 
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index 576d1edaaa..c0181506a5 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -224,8 +224,9 @@ page_header(PG_FUNCTION_ARGS)
 
 	Datum		result;
 	HeapTuple	tuple;
-	Datum		values[11];
-	bool		nulls[11];
+	Datum		values[9];
+	bool		nulls[9];
+
 	PageHeader	page;
 	XLogRecPtr	lsn;
 
@@ -266,7 +267,6 @@ page_header(PG_FUNCTION_ARGS)
 	}
 	else
 		values[0] = LSNGetDatum(lsn);
-	
 	values[1] = UInt16GetDatum(page->pd_checksum);
 	values[2] = UInt16GetDatum(page->pd_flags);
 	values[3] = UInt16GetDatum(page->pd_lower);
@@ -276,29 +276,6 @@ page_header(PG_FUNCTION_ARGS)
 	values[7] = UInt16GetDatum(PageGetPageLayoutVersion(page));
 	values[8] = TransactionIdGetDatum(page->pd_prune_xid);
 
-	if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HeapPageSpecialData)))
-	{
-		HeapPageSpecial pageSpecial = HeapPageGetSpecial(page);
-		if (pageSpecial->pd_magic == HEAP_PAGE_MAGIC ||
-			pageSpecial->pd_magic == SEQ_PAGE_MAGIC)
-		{
-			values[9] = TransactionIdGetDatum(pageSpecial->pd_multi_base);
-			values[10] = TransactionIdGetDatum(HeapPageGetPruneXid(page));
-			nulls[9] = false;
-			nulls[10] = false;
-		}
-		else
-		{
-			nulls[9] = true;
-			nulls[10] = true;
-		}
-	}
-	else
-	{
-		nulls[9] = true;
-		nulls[10] = true;
-	}
-	
 	/* Build and return the tuple. */
 
 	memset(nulls, 0, sizeof(nulls));
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 1ca88dcd02..54e47b810f 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -762,7 +762,7 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer)
 	 * be set here.  So just check the xmin.
 	 */
 
-	xmin = HeapTupleGetXmin(tup);
+	xmin = HeapTupleHeaderGetXmin(tup->t_data);
 	if (!TransactionIdPrecedes(xmin, OldestXmin))
 		return false;			/* xmin not old enough for all to see */
 
diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c
index 80e022ceaf..23306e11a7 100644
--- a/contrib/pgstattuple/pgstatapprox.c
+++ b/contrib/pgstattuple/pgstatapprox.c
@@ -153,7 +153,6 @@ statapprox_heap(Relation rel, output_type *stat)
 			tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
 			tuple.t_len = ItemIdGetLength(itemid);
 			tuple.t_tableOid = RelationGetRelid(rel);
-			HeapTupleCopyBaseFromPage(&tuple, page);
 
 			/*
 			 * We follow VACUUM's lead in counting INSERT_IN_PROGRESS tuples
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index a604f8587a..b1ce0d77d7 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -620,7 +620,7 @@ pgstathashindex(PG_FUNCTION_ARGS)
 	metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
 	metap = HashPageGetMeta(BufferGetPage(metabuf));
 	stats.version = metap->hashm_version;
-	stats.space_per_page = BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(HashPageOpaqueData));
+	stats.space_per_page = metap->hashm_bsize;
 	_hash_relbuf(rel, metabuf);
 
 	/* Get the current relation length */
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 8e7796e6b0..4d5640275c 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -260,6 +260,58 @@ static relopt_int intRelOpts[] =
 		},
 		-1, 1, 10000
 	},
+	{
+		{
+			"autovacuum_freeze_min_age",
+			"Minimum age at which VACUUM should freeze a table row, for autovacuum",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		-1, 0, 1000000000
+	},
+	{
+		{
+			"autovacuum_multixact_freeze_min_age",
+			"Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		-1, 0, 1000000000
+	},
+	{
+		{
+			"autovacuum_freeze_max_age",
+			"Age at which to autovacuum a table to prevent transaction ID wraparound",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		-1, 100000, 2000000000
+	},
+	{
+		{
+			"autovacuum_multixact_freeze_max_age",
+			"Multixact age at which to autovacuum a table to prevent multixact wraparound",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		-1, 10000, 2000000000
+	},
+	{
+		{
+			"autovacuum_freeze_table_age",
+			"Age at which VACUUM should perform a full table sweep to freeze row versions",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		}, -1, 0, 2000000000
+	},
+	{
+		{
+			"autovacuum_multixact_freeze_table_age",
+			"Age of multixact at which VACUUM should perform a full table sweep to freeze row versions",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		}, -1, 0, 2000000000
+	},
 	{
 		{
 			"log_autovacuum_min_duration",
@@ -338,60 +390,6 @@ static relopt_int intRelOpts[] =
 
 static relopt_int64 int64RelOpts[] =
 {
-	{
-		{
-			"autovacuum_freeze_min_age",
-			"Minimum age at which VACUUM should freeze a table row, for autovacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		INT64CONST(-1), INT64CONST(0), INT64CONST(1000000000)
-	},
-	{
-		{
-			"autovacuum_multixact_freeze_min_age",
-			"Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		INT64CONST(-1), INT64CONST(0), INT64CONST(1000000000)
-	},
-	{
-		{
-			"autovacuum_freeze_max_age",
-			"Age at which to autovacuum a table to prevent transaction ID wraparound",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		INT64CONST(-1), INT64CONST(100000), INT64CONST(2000000000)
-	},
-	{
-		{
-			"autovacuum_multixact_freeze_max_age",
-			"Multixact age at which to autovacuum a table to prevent multixact wraparound",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		INT64CONST(-1), INT64CONST(10000), INT64CONST(2000000000)
-	},
-	{
-		{
-			"autovacuum_freeze_table_age",
-			"Age at which VACUUM should perform a full table sweep to freeze row versions",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		INT64CONST(-1), INT64CONST(0), INT64CONST(2000000000)
-	},
-	{
-		{
-			"autovacuum_multixact_freeze_table_age",
-			"Age of multixact at which VACUUM should perform a full table sweep to freeze row versions",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		INT64CONST(-1), INT64CONST(0), INT64CONST(2000000000)
-	},
 
 	/* list terminator */
 	{{NULL}}
@@ -1907,17 +1905,17 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)},
 		{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)},
-		{"autovacuum_freeze_min_age", RELOPT_TYPE_INT64,
+		{"autovacuum_freeze_min_age", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_min_age)},
-		{"autovacuum_freeze_max_age", RELOPT_TYPE_INT64,
+		{"autovacuum_freeze_max_age", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_max_age)},
-		{"autovacuum_freeze_table_age", RELOPT_TYPE_INT64,
+		{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_table_age)},
-		{"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT64,
+		{"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_min_age)},
-		{"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT64,
+		{"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_max_age)},
-		{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT64,
+		{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_table_age)},
 		{"log_autovacuum_min_duration", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)},
diff --git a/src/backend/access/heap/heapam_visibility.c b/src/backend/access/heap/heapam_visibility.c
index 8a3e4de2bc..80bd494076 100644
--- a/src/backend/access/heap/heapam_visibility.c
+++ b/src/backend/access/heap/heapam_visibility.c
@@ -217,7 +217,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 				}
 			}
 		}
-		else if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */
 				return true;
@@ -229,7 +229,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 			{
 				TransactionId xmax;
 
-				xmax = HeapTupleGetUpdateXid(htup);
+				xmax = HeapTupleGetUpdateXid(tuple);
 
 				/* not LOCKED_ONLY, so it has to have an xmax */
 				Assert(TransactionIdIsValid(xmax));
@@ -241,7 +241,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 					return false;
 			}
 
-			if (!TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 			{
 				/* deleting subtransaction must have aborted */
 				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -251,15 +251,11 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
 			return false;
 		}
-		else if (CheckIllegalUnfrozenTuple(tuple, buffer))
-		{
-			// transaction committed, hint bits set in function above
-		}
-		else if (TransactionIdIsInProgress(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 			return false;
-		else if (TransactionIdDidCommit(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-						HeapTupleGetRawXmin(htup));
+						HeapTupleHeaderGetRawXmin(tuple));
 		else
 		{
 			/* it must have aborted or crashed */
@@ -288,7 +284,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 		if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 			return true;
 
-		xmax = HeapTupleGetUpdateXid(htup);
+		xmax = HeapTupleGetUpdateXid(tuple);
 
 		/* not LOCKED_ONLY, so it has to have an xmax */
 		Assert(TransactionIdIsValid(xmax));
@@ -303,17 +299,17 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 		return true;
 	}
 
-	if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+	if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 			return true;
 		return false;
 	}
 
-	if (TransactionIdIsInProgress(HeapTupleGetRawXmax(htup)))
+	if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 		return true;
 
-	if (!TransactionIdDidCommit(HeapTupleGetRawXmax(htup)))
+	if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		/* it must have aborted or crashed */
 		SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -331,7 +327,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
 	}
 
 	SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
-				HeapTupleGetRawXmax(htup));
+				HeapTupleHeaderGetRawXmax(tuple));
 	return false;
 }
 
@@ -420,7 +416,7 @@ HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot,
 		 * is canceled by super-deleting the tuple.  This also applies to
 		 * TOAST tuples created during speculative insertion.
 		 */
-		else if (!TransactionIdIsValid(HeapTupleGetXmin(htup)))
+		else if (!TransactionIdIsValid(HeapTupleHeaderGetXmin(tuple)))
 			return false;
 	}
 
@@ -510,7 +506,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 				}
 			}
 		}
-		else if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			if (HeapTupleHeaderGetCmin(tuple) >= curcid)
 				return TM_Invisible;	/* inserted after scan started */
@@ -522,7 +518,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 			{
 				TransactionId xmax;
 
-				xmax = HeapTupleGetRawXmax(htup);
+				xmax = HeapTupleHeaderGetRawXmax(tuple);
 
 				/*
 				 * Careful here: even though this tuple was created by our own
@@ -553,7 +549,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 			{
 				TransactionId xmax;
 
-				xmax = HeapTupleGetUpdateXid(htup);
+				xmax = HeapTupleGetUpdateXid(tuple);
 
 				/* not LOCKED_ONLY, so it has to have an xmax */
 				Assert(TransactionIdIsValid(xmax));
@@ -561,7 +557,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 				/* deleting subtransaction must have aborted */
 				if (!TransactionIdIsCurrentTransactionId(xmax))
 				{
-					if (MultiXactIdIsRunning(HeapTupleGetRawXmax(htup),
+					if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
 											 false))
 						return TM_BeingModified;
 					return TM_Ok;
@@ -575,7 +571,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 				}
 			}
 
-			if (!TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 			{
 				/* deleting subtransaction must have aborted */
 				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -588,15 +584,11 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 			else
 				return TM_Invisible;	/* updated before scan started */
 		}
-		else if (CheckIllegalUnfrozenTuple(tuple, buffer))  // FIXME - should this be referring to htup after the 64-bit patch changes are applied?
-		{
-			// transaction committed, hint bits set in function above
-		}
-		else if (TransactionIdIsInProgress(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 			return TM_Invisible;
-		else if (TransactionIdDidCommit(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-						HeapTupleGetRawXmin(htup));
+						HeapTupleHeaderGetRawXmin(tuple));
 		else
 		{
 			/* it must have aborted or crashed */
@@ -631,17 +623,17 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 
 		if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 		{
-			if (MultiXactIdIsRunning(HeapTupleGetRawXmax(htup), true))
+			if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), true))
 				return TM_BeingModified;
 
 			SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
 			return TM_Ok;
 		}
 
-		xmax = HeapTupleGetUpdateXid(htup);
+		xmax = HeapTupleGetUpdateXid(tuple);
 		if (!TransactionIdIsValid(xmax))
 		{
-			if (MultiXactIdIsRunning(HeapTupleGetRawXmax(htup), false))
+			if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 				return TM_BeingModified;
 		}
 
@@ -656,7 +648,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 				return TM_Invisible;	/* updated before scan started */
 		}
 
-		if (MultiXactIdIsRunning(HeapTupleGetRawXmax(htup), false))
+		if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 			return TM_BeingModified;
 
 		if (TransactionIdDidCommit(xmax))
@@ -673,7 +665,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 		 * what about the other members?
 		 */
 
-		if (!MultiXactIdIsRunning(HeapTupleGetRawXmax(htup), false))
+		if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 		{
 			/*
 			 * There's no member, even just a locker, alive anymore, so we can
@@ -690,7 +682,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 		}
 	}
 
-	if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+	if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 			return TM_BeingModified;
@@ -700,10 +692,10 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 			return TM_Invisible;	/* updated before scan started */
 	}
 
-	if (TransactionIdIsInProgress(HeapTupleGetRawXmax(htup)))
+	if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 		return TM_BeingModified;
 
-	if (!TransactionIdDidCommit(HeapTupleGetRawXmax(htup)))
+	if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		/* it must have aborted or crashed */
 		SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -721,7 +713,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
 	}
 
 	SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
-				HeapTupleGetRawXmax(htup));
+				HeapTupleHeaderGetRawXmax(tuple));
 	if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) ||
 		HeapTupleHeaderIndicatesMovedPartitions(tuple))
 		return TM_Updated;		/* updated by other */
@@ -805,7 +797,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 				}
 			}
 		}
-		else if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */
 				return true;
@@ -817,7 +809,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 			{
 				TransactionId xmax;
 
-				xmax = HeapTupleGetUpdateXid(htup);
+				xmax = HeapTupleGetUpdateXid(tuple);
 
 				/* not LOCKED_ONLY, so it has to have an xmax */
 				Assert(TransactionIdIsValid(xmax));
@@ -829,7 +821,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 					return false;
 			}
 
-			if (!TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 			{
 				/* deleting subtransaction must have aborted */
 				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -839,11 +831,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 
 			return false;
 		}
-		else if (CheckIllegalUnfrozenTuple(tuple, buffer))  // FIXME - should this be referring to htup after the 64-bit patch changes are applied?
-		{
-			// transaction committed, hint bits set in function above
-		}
-		else if (TransactionIdIsInProgress(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			/*
 			 * Return the speculative token to caller.  Caller can worry about
@@ -859,13 +847,13 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 				Assert(snapshot->speculativeToken != 0);
 			}
 
-			snapshot->xmin = HeapTupleGetRawXmin(htup);
+			snapshot->xmin = HeapTupleHeaderGetRawXmin(tuple);
 			/* XXX shouldn't we fall through to look at xmax? */
 			return true;		/* in insertion by other */
 		}
-		else if (TransactionIdDidCommit(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-						HeapTupleGetRawXmin(htup));
+						HeapTupleHeaderGetRawXmin(tuple));
 		else
 		{
 			/* it must have aborted or crashed */
@@ -894,7 +882,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 		if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 			return true;
 
-		xmax = HeapTupleGetUpdateXid(htup);
+		xmax = HeapTupleGetUpdateXid(tuple);
 
 		/* not LOCKED_ONLY, so it has to have an xmax */
 		Assert(TransactionIdIsValid(xmax));
@@ -912,21 +900,21 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 		return true;
 	}
 
-	if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+	if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 			return true;
 		return false;
 	}
 
-	if (TransactionIdIsInProgress(HeapTupleGetRawXmax(htup)))
+	if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		if (!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
-			snapshot->xmax = HeapTupleGetRawXmax(htup);
+			snapshot->xmax = HeapTupleHeaderGetRawXmax(tuple);
 		return true;
 	}
 
-	if (!TransactionIdDidCommit(HeapTupleGetRawXmax(htup)))
+	if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 	{
 		/* it must have aborted or crashed */
 		SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -944,7 +932,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
 	}
 
 	SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
-				HeapTupleGetRawXmax(htup));
+				HeapTupleHeaderGetRawXmax(tuple));
 	return false;				/* updated by other */
 }
 
@@ -1023,7 +1011,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 				}
 			}
 		}
-		else if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
 				return false;	/* inserted after scan started */
@@ -1038,7 +1026,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 			{
 				TransactionId xmax;
 
-				xmax = HeapTupleGetUpdateXid(htup);
+				xmax = HeapTupleGetUpdateXid(tuple);
 
 				/* not LOCKED_ONLY, so it has to have an xmax */
 				Assert(TransactionIdIsValid(xmax));
@@ -1052,7 +1040,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 					return false;	/* updated before scan started */
 			}
 
-			if (!TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 			{
 				/* deleting subtransaction must have aborted */
 				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -1065,15 +1053,11 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 			else
 				return false;	/* deleted before scan started */
 		}
-		else if (XidInMVCCSnapshot(HeapTupleGetRawXmin(htup), snapshot))
+		else if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
 			return false;
-		else if (CheckIllegalUnfrozenTuple(tuple, buffer))
-		{
-			// transaction committed, hint bits set in function above
-		}
-		else if (TransactionIdDidCommit(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-						HeapTupleGetRawXmin(htup));
+						HeapTupleHeaderGetRawXmin(tuple));
 		else
 		{
 			/* it must have aborted or crashed */
@@ -1086,7 +1070,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 	{
 		/* xmin is committed, but maybe not according to our snapshot */
 		if (!HeapTupleHeaderXminFrozen(tuple) &&
-			XidInMVCCSnapshot(HeapTupleGetRawXmin(htup), snapshot))
+			XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
 			return false;		/* treat as still in progress */
 	}
 
@@ -1105,7 +1089,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 		/* already checked above */
 		Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
 
-		xmax = HeapTupleGetUpdateXid(htup);
+		xmax = HeapTupleGetUpdateXid(tuple);
 
 		/* not LOCKED_ONLY, so it has to have an xmax */
 		Assert(TransactionIdIsValid(xmax));
@@ -1127,7 +1111,7 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 
 	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
 	{
-		if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmax(htup)))
+		if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
 		{
 			if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 				return true;	/* deleted after scan started */
@@ -1135,10 +1119,10 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 				return false;	/* deleted before scan started */
 		}
 
-		if (XidInMVCCSnapshot(HeapTupleGetRawXmax(htup), snapshot))
+		if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
 			return true;
 
-		if (!TransactionIdDidCommit(HeapTupleGetRawXmax(htup)))
+		if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 		{
 			/* it must have aborted or crashed */
 			SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
@@ -1148,12 +1132,12 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
 
 		/* xmax transaction committed */
 		SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
-					HeapTupleGetRawXmax(htup));
+					HeapTupleHeaderGetRawXmax(tuple));
 	}
 	else
 	{
 		/* xmax is committed, but maybe not according to our snapshot */
-		if (XidInMVCCSnapshot(HeapTupleGetRawXmax(htup), snapshot))
+		if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
 			return true;		/* treat as still in progress */
 	}
 
@@ -1268,25 +1252,21 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 				return HEAPTUPLE_DEAD;
 			}
 		}
-		else if (TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */
 				return HEAPTUPLE_INSERT_IN_PROGRESS;
 			/* only locked? run infomask-only check first, for performance */
 			if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) ||
-				HeapTupleHeaderIsOnlyLocked(htup))
+				HeapTupleHeaderIsOnlyLocked(tuple))
 				return HEAPTUPLE_INSERT_IN_PROGRESS;
 			/* inserted and then deleted by same xact */
-			if (TransactionIdIsCurrentTransactionId(HeapTupleGetUpdateXidAny(htup)))
+			if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple)))
 				return HEAPTUPLE_DELETE_IN_PROGRESS;
 			/* deleting subtransaction must have aborted */
 			return HEAPTUPLE_INSERT_IN_PROGRESS;
 		}
-		else if (CheckIllegalUnfrozenTuple(tuple, buffer))  // FIXME - should this be referring to htup after the 64-bit patch changes are applied?
-		{
-			// transaction committed, hint bits set in function above
-		}
-		else if (TransactionIdIsInProgress(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 		{
 			/*
 			 * It'd be possible to discern between INSERT/DELETE in progress
@@ -1298,9 +1278,9 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 			 */
 			return HEAPTUPLE_INSERT_IN_PROGRESS;
 		}
-		else if (TransactionIdDidCommit(HeapTupleGetRawXmin(htup)))
+		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-						HeapTupleGetRawXmin(htup));
+						HeapTupleHeaderGetRawXmin(tuple));
 		else
 		{
 			/*
@@ -1342,14 +1322,14 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 				 * possibly be running; otherwise have to check.
 				 */
 				if (!HEAP_LOCKED_UPGRADED(tuple->t_infomask) &&
-					MultiXactIdIsRunning(HeapTupleGetRawXmax(htup),
+					MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
 										 true))
 					return HEAPTUPLE_LIVE;
 				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
 			}
 			else
 			{
-				if (TransactionIdIsInProgress(HeapTupleGetRawXmax(htup)))
+				if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 					return HEAPTUPLE_LIVE;
 				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
 							InvalidTransactionId);
@@ -1367,7 +1347,7 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 
 	if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
 	{
-		TransactionId xmax = HeapTupleGetUpdateXid(htup);
+		TransactionId xmax = HeapTupleGetUpdateXid(tuple);
 
 		/* already checked above */
 		Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
@@ -1390,7 +1370,7 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 			*dead_after = xmax;
 			return HEAPTUPLE_RECENTLY_DEAD;
 		}
-		else if (!MultiXactIdIsRunning(HeapTupleGetRawXmax(htup), false))
+		else if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 		{
 			/*
 			 * Not in Progress, Not Committed, so either Aborted or crashed.
@@ -1404,11 +1384,11 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 
 	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
 	{
-		if (TransactionIdIsInProgress(HeapTupleGetRawXmax(htup)))
+		if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 			return HEAPTUPLE_DELETE_IN_PROGRESS;
-		else if (TransactionIdDidCommit(HeapTupleGetRawXmax(htup)))
+		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 			SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
-						HeapTupleGetRawXmax(htup));
+						HeapTupleHeaderGetRawXmax(tuple));
 		else
 		{
 			/*
@@ -1430,7 +1410,7 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
 	 * Deleter committed, allow caller to check if it was recent enough that
 	 * some open transactions could still see the tuple.
 	 */
-	*dead_after = HeapTupleGetRawXmax(htup);
+	*dead_after = HeapTupleHeaderGetRawXmax(tuple);
 	return HEAPTUPLE_RECENTLY_DEAD;
 }
 
@@ -1526,7 +1506,7 @@ HeapTupleIsSurelyDead(HeapTuple htup, GlobalVisState *vistest)
 
 	/* Deleter committed, so tuple is dead if the XID is old enough. */
 	return GlobalVisTestIsRemovableXid(vistest,
-									   HeapTupleGetRawXmax(htup));
+									   HeapTupleHeaderGetRawXmax(tuple));
 }
 
 /*
@@ -1539,9 +1519,8 @@ HeapTupleIsSurelyDead(HeapTuple htup, GlobalVisState *vistest)
  * at the top of this file.
  */
 bool
-HeapTupleHeaderIsOnlyLocked(HeapTuple htup)
+HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
 {
-	HeapTupleHeader tuple = htup->t_data;
 	TransactionId xmax;
 
 	/* if there's no valid Xmax, then there's obviously no update either */
@@ -1552,7 +1531,7 @@ HeapTupleHeaderIsOnlyLocked(HeapTuple htup)
 		return true;
 
 	/* invalid xmax means no update */
-	if (!TransactionIdIsValid(HeapTupleGetRawXmax(htup)))
+	if (!TransactionIdIsValid(HeapTupleHeaderGetRawXmax(tuple)))
 		return true;
 
 	/*
@@ -1563,7 +1542,7 @@ HeapTupleHeaderIsOnlyLocked(HeapTuple htup)
 		return false;
 
 	/* ... but if it's a multi, then perhaps the updating Xid aborted. */
-	xmax = HeapTupleGetUpdateXid(htup);
+	xmax = HeapTupleGetUpdateXid(tuple);
 
 	/* not LOCKED_ONLY, so it has to have an xmax */
 	Assert(TransactionIdIsValid(xmax));
@@ -1611,8 +1590,8 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
 							   Buffer buffer)
 {
 	HeapTupleHeader tuple = htup->t_data;
-	TransactionId xmin = HeapTupleGetXmin(htup);
-	TransactionId xmax = HeapTupleGetRawXmax(htup);
+	TransactionId xmin = HeapTupleHeaderGetXmin(tuple);
+	TransactionId xmax = HeapTupleHeaderGetRawXmax(tuple);
 
 	Assert(ItemPointerIsValid(&htup->t_self));
 	Assert(htup->t_tableOid != InvalidOid);
@@ -1712,7 +1691,7 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
 	 */
 	else if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
 	{
-		xmax = HeapTupleGetUpdateXid(htup);
+		xmax = HeapTupleGetUpdateXid(tuple);
 	}
 
 	/* check if it's one of our txids, toplevel is also in there */
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 562fb7f5e0..9e04bc712c 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -188,7 +188,7 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
 			/* OK to prune */
 			(void) heap_page_prune(relation, buffer, vistest,
 								   limited_xmin, limited_ts,
-								   true, &ignore, NULL, true);
+								   true, &ignore, NULL);
 		}
 
 		/* And release buffer lock */
@@ -225,7 +225,7 @@ heap_page_prune(Relation relation, Buffer buffer,
 				TransactionId old_snap_xmin,
 				TimestampTz old_snap_ts,
 				bool report_stats, TransactionId *latestRemovedXid,
-				OffsetNumber *off_loc, bool repairFragmentation))
+				OffsetNumber *off_loc)
 {
 	int			ndeleted = 0;
 	Page		page = BufferGetPage(buffer);
@@ -299,27 +299,20 @@ heap_page_prune(Relation relation, Buffer buffer,
 		heap_page_prune_execute(buffer,
 								prstate.redirected, prstate.nredirected,
 								prstate.nowdead, prstate.ndead,
-								prstate.nowunused, prstate.nunused,
-								repairFragmentation);
+								prstate.nowunused, prstate.nunused);
 
 		/*
 		 * Update the page's pd_prune_xid field to either zero, or the lowest
 		 * XID of any soon-prunable tuple.
 		 */
-		HeapPageSetPruneXid(page, prstate.new_prune_xid);
+		((PageHeader) page)->pd_prune_xid = prstate.new_prune_xid;
 
 		/*
 		 * Also clear the "page is full" flag, since there's no point in
 		 * repeating the prune/defrag process until something else happens to
 		 * the page.
 		 */
-		if (HeapPageGetPruneXid(page) != prstate.new_prune_xid ||
- 			PageIsFull(page))
-		{
-			HeapPageSetPruneXid(page, prstate.new_prune_xid);
- 			PageClearFull(page);
- 			MarkBufferDirtyHint(buffer, true);
-		}
+		PageClearFull(page);
 
 		MarkBufferDirty(buffer);
 
@@ -512,7 +505,6 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 	HeapTupleData tup;
 
 	tup.t_tableOid = RelationGetRelid(prstate->rel);
-	HeapTupleCopyBaseFromPage(&tup, dp);
 
 	rootlp = PageGetItemId(dp, rootoffnum);
 
@@ -551,7 +543,7 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 				== HEAPTUPLE_DEAD && !HeapTupleHeaderIsHotUpdated(htup))
 			{
 				heap_prune_record_unused(prstate, rootoffnum);
-				HeapTupleHeaderAdvanceLatestRemovedXid(&tup,
+				HeapTupleHeaderAdvanceLatestRemovedXid(htup,
 													   &prstate->latestRemovedXid);
 				ndeleted++;
 			}
@@ -612,14 +604,13 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 
 		tup.t_data = htup;
 		tup.t_len = ItemIdGetLength(lp);
-		HeapTupleCopyBaseFromPage(&tup, dp);
 		ItemPointerSet(&(tup.t_self), BufferGetBlockNumber(buffer), offnum);
 
 		/*
 		 * Check the tuple XMIN against prior XMAX, if any
 		 */
 		if (TransactionIdIsValid(priorXmax) &&
-			!TransactionIdEquals(HeapTupleGetXmin(&tup), priorXmax))
+			!TransactionIdEquals(HeapTupleHeaderGetXmin(htup), priorXmax))
 			break;
 
 		/*
@@ -646,7 +637,7 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 				 * that the page is reconsidered for pruning in future.
 				 */
 				heap_prune_record_prunable(prstate,
-										   HeapTupleGetUpdateXidAny(&tup));
+										   HeapTupleHeaderGetUpdateXid(htup));
 				break;
 
 			case HEAPTUPLE_DELETE_IN_PROGRESS:
@@ -656,7 +647,7 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 				 * that the page is reconsidered for pruning in future.
 				 */
 				heap_prune_record_prunable(prstate,
-										   HeapTupleGetUpdateXidAny(&tup));
+										   HeapTupleHeaderGetUpdateXid(htup));
 				break;
 
 			case HEAPTUPLE_LIVE:
@@ -685,7 +676,7 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 		if (tupdead)
 		{
 			latestdead = offnum;
-			HeapTupleHeaderAdvanceLatestRemovedXid(htup,  // TBD 64bit XID FIXME - verify that arg 1 should not be &tup
+			HeapTupleHeaderAdvanceLatestRemovedXid(htup,
 												   &prstate->latestRemovedXid);
 		}
 		else if (!recent_dead)
@@ -707,7 +698,7 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
 		Assert(ItemPointerGetBlockNumber(&htup->t_ctid) ==
 			   BufferGetBlockNumber(buffer));
 		offnum = ItemPointerGetOffsetNumber(&htup->t_ctid);
-		priorXmax = HeapTupleGetUpdateXidAny(&tup);
+		priorXmax = HeapTupleHeaderGetUpdateXid(htup);
 	}
 
 	/*
@@ -828,8 +819,7 @@ void
 heap_page_prune_execute(Buffer buffer,
 						OffsetNumber *redirected, int nredirected,
 						OffsetNumber *nowdead, int ndead,
-						OffsetNumber *nowunused, int nunused,
-						bool repairFragmentation)
+						OffsetNumber *nowunused, int nunused)
 {
 	Page		page = (Page) BufferGetPage(buffer);
 	OffsetNumber *offnum;
@@ -870,8 +860,7 @@ heap_page_prune_execute(Buffer buffer,
 	 * Finally, repair any fragmentation, and update the page's hint bit about
 	 * whether it has free pointers.
 	 */
-	if (repairFragmentation)
-		PageRepairFragmentation(page);
+	PageRepairFragmentation(page);
 }
 
 
@@ -906,7 +895,6 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
 		HeapTupleHeader htup;
 		OffsetNumber nextoffnum;
 		TransactionId priorXmax;
-		HeapTupleData tup;
 
 		/* skip unused and dead items */
 		if (!ItemIdIsUsed(lp) || ItemIdIsDead(lp))
@@ -915,8 +903,6 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
 		if (ItemIdIsNormal(lp))
 		{
 			htup = (HeapTupleHeader) PageGetItem(page, lp);
-			tup.t_data = htup;
-			HeapTupleCopyBaseFromPage(&tup, page);
 
 			/*
 			 * Check if this tuple is part of a HOT-chain rooted at some other
@@ -938,7 +924,7 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
 
 			/* Set up to scan the HOT-chain */
 			nextoffnum = ItemPointerGetOffsetNumber(&htup->t_ctid);
-			priorXmax = HeapTupleGetUpdateXidAny(&tup);
+			priorXmax = HeapTupleHeaderGetUpdateXid(htup);
 		}
 		else
 		{
@@ -966,11 +952,9 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
 				break;
 
 			htup = (HeapTupleHeader) PageGetItem(page, lp);
-			tup.t_data = htup;
-			HeapTupleCopyBaseFromPage(&tup, page);
 
 			if (TransactionIdIsValid(priorXmax) &&
-				!TransactionIdEquals(priorXmax, HeapTupleGetXmin(&tup)))
+				!TransactionIdEquals(priorXmax, HeapTupleHeaderGetXmin(htup)))
 				break;
 
 			/* Remember the root line pointer for this item */
@@ -984,7 +968,7 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
 			Assert(!HeapTupleHeaderIndicatesMovedPartitions(htup));
 
 			nextoffnum = ItemPointerGetOffsetNumber(&htup->t_ctid);
-			priorXmax = HeapTupleGetUpdateXidAny(&tup);
+			priorXmax = HeapTupleHeaderGetUpdateXid(htup);
 		}
 	}
 }
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 62e82bc25b..65942cc428 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -380,7 +380,6 @@ rewrite_heap_tuple(RewriteState state,
 		   &old_tuple->t_data->t_choice.t_heap,
 		   sizeof(HeapTupleFields));
 
-	HeapTupleCopyBase(new_tuple, old_tuple);
 	new_tuple->t_data->t_infomask &= ~HEAP_XACT_MASK;
 	new_tuple->t_data->t_infomask2 &= ~HEAP2_XACT_MASK;
 	new_tuple->t_data->t_infomask |=
@@ -390,7 +389,7 @@ rewrite_heap_tuple(RewriteState state,
 	 * While we have our hands on the tuple, we may as well freeze any
 	 * eligible xmin or xmax, so that future VACUUM effort can be saved.
 	 */
-	heap_freeze_tuple(new_tuple,
+	heap_freeze_tuple(new_tuple->t_data,
 					  state->rs_old_rel->rd_rel->relfrozenxid,
 					  state->rs_old_rel->rd_rel->relminmxid,
 					  state->rs_freeze_xid,
@@ -406,7 +405,7 @@ rewrite_heap_tuple(RewriteState state,
 	 * If the tuple has been updated, check the old-to-new mapping hash table.
 	 */
 	if (!((old_tuple->t_data->t_infomask & HEAP_XMAX_INVALID) ||
-		  HeapTupleHeaderIsOnlyLocked(old_tuple)) &&
+		  HeapTupleHeaderIsOnlyLocked(old_tuple->t_data)) &&
 		!HeapTupleHeaderIndicatesMovedPartitions(old_tuple->t_data) &&
 		!(ItemPointerEquals(&(old_tuple->t_self),
 							&(old_tuple->t_data->t_ctid))))
@@ -414,7 +413,7 @@ rewrite_heap_tuple(RewriteState state,
 		OldToNewMapping mapping;
 
 		memset(&hashkey, 0, sizeof(hashkey));
-		hashkey.xmin = HeapTupleGetUpdateXidAny(old_tuple);
+		hashkey.xmin = HeapTupleHeaderGetUpdateXid(old_tuple->t_data);
 		hashkey.tid = old_tuple->t_data->t_ctid;
 
 		mapping = (OldToNewMapping)
@@ -487,7 +486,7 @@ rewrite_heap_tuple(RewriteState state,
 		 * RECENTLY_DEAD if and only if the xmin is not before OldestXmin.
 		 */
 		if ((new_tuple->t_data->t_infomask & HEAP_UPDATED) &&
-			!TransactionIdPrecedes(HeapTupleGetXmin(new_tuple),
+			!TransactionIdPrecedes(HeapTupleHeaderGetXmin(new_tuple->t_data),
 								   state->rs_oldest_xmin))
 		{
 			/*
@@ -496,7 +495,7 @@ rewrite_heap_tuple(RewriteState state,
 			UnresolvedTup unresolved;
 
 			memset(&hashkey, 0, sizeof(hashkey));
-			hashkey.xmin = HeapTupleGetXmin(new_tuple);
+			hashkey.xmin = HeapTupleHeaderGetXmin(new_tuple->t_data);
 			hashkey.tid = old_tid;
 
 			unresolved = hash_search(state->rs_unresolved_tups, &hashkey,
@@ -584,7 +583,7 @@ rewrite_heap_dead_tuple(RewriteState state, HeapTuple old_tuple)
 	bool		found;
 
 	memset(&hashkey, 0, sizeof(hashkey));
-	hashkey.xmin = HeapTupleGetXmin(old_tuple);
+	hashkey.xmin = HeapTupleHeaderGetXmin(old_tuple->t_data);
 	hashkey.tid = old_tuple->t_self;
 
 	unresolved = hash_search(state->rs_unresolved_tups, &hashkey,
@@ -620,7 +619,6 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
 	Size		len;
 	OffsetNumber newoff;
 	HeapTuple	heaptup;
-	TransactionId xmin, xmax;
 
 	/*
 	 * If the new tuple is too big for storage or contains already toasted
@@ -704,20 +702,10 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
 	if (!state->rs_buffer_valid)
 	{
 		/* Initialize a new empty page */
-		PageInit(page, BLCKSZ, sizeof(HeapPageSpecialData));
-		HeapPageGetSpecial(page)->pd_magic = HEAP_PAGE_MAGIC;
+		PageInit(page, BLCKSZ, 0);
 		state->rs_buffer_valid = true;
 	}
 
-	// TBD 64bit XID rewrite_page_prepare_for_xid(page, HeapTupleGetXmin(heaptup), false);
-	// TBD 64bit XID rewrite_page_prepare_for_xid(page, HeapTupleGetRawXmax(heaptup),
-	// TBD 64bit XID 	(heaptup->t_data->t_infomask & HEAP_XMAX_IS_MULTI) ? true : false);
-	xmin = HeapTupleGetXmin(heaptup);
-	xmax = HeapTupleGetRawXmax(heaptup);
-	HeapTupleCopyBaseFromPage(heaptup, page);
-	HeapTupleSetXmin(heaptup, xmin);
-	HeapTupleSetXmax(heaptup, xmax);
-
 	/* And now we can insert the tuple into the page */
 	newoff = PageAddItem(page, (Item) heaptup->t_data, heaptup->t_len,
 						 InvalidOffsetNumber, false, true);
@@ -1012,10 +1000,6 @@ logical_rewrite_log_mapping(RewriteState state, TransactionId xid,
 				 (uint32) (state->rs_begin_lsn >> 32),
 				 (uint32) state->rs_begin_lsn,
 				 xid, GetCurrentTransactionId());
-		// TBD 64bit XID (uint32) (xid >> 32),
-		// TBD 64bit XID		 (uint32) xid,
-		// TBD 64bit XID		 (uint32) (GetCurrentTransactionId() >> 32),
-		// TBD 64bit XID		 (uint32) GetCurrentTransactionId());
 
 		dlist_init(&src->mappings);
 		src->num_mappings = 0;
@@ -1064,9 +1048,9 @@ logical_rewrite_heap_tuple(RewriteState state, ItemPointerData old_tid,
 	if (!state->rs_logical_rewrite)
 		return;
 
-	xmin = HeapTupleGetXmin(new_tuple);
+	xmin = HeapTupleHeaderGetXmin(new_tuple->t_data);
 	/* use *GetUpdateXid to correctly deal with multixacts */
-	xmax = HeapTupleGetUpdateXidAny(new_tuple);
+	xmax = HeapTupleHeaderGetUpdateXid(new_tuple->t_data);
 
 	/*
 	 * Log the mapping iff the tuple has been created recently.
@@ -1139,14 +1123,6 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
 			 (uint32) (xlrec->start_lsn >> 32),
 			 (uint32) xlrec->start_lsn,
 			 xlrec->mapped_xid, XLogRecGetXid(r));
-#ifdef UNUSED
-	// TBD 64bit XID 
--			 xlrec->mapped_xid, XLogRecGetXid(r));
-+			 (uint32) (xlrec->mapped_xid >> 32),
-+			 (uint32) xlrec->mapped_xid,
-+			 (uint32) (XLogRecGetXid(r) >> 32),
-+			 (uint32) XLogRecGetXid(r));
-#endif
 
 	fd = OpenTransientFile(path,
 						   O_CREAT | O_WRONLY | PG_BINARY);
@@ -1242,12 +1218,10 @@ CheckPointLogicalRewriteHeap(void)
 		Oid			dboid;
 		Oid			relid;
 		XLogRecPtr	lsn;
-		uint32		lsn_hi,
-					lsn_lo,
-					rewrite_xid_hi,
-					rewrite_xid_lo,
-					create_xid_hi,
-					create_xid_lo;
+		TransactionId rewrite_xid;
+		TransactionId create_xid;
+		uint32		hi,
+					lo;
 
 		if (strcmp(mapping_de->d_name, ".") == 0 ||
 			strcmp(mapping_de->d_name, "..") == 0)
@@ -1262,12 +1236,10 @@ CheckPointLogicalRewriteHeap(void)
 			continue;
 
 		if (sscanf(mapping_de->d_name, LOGICAL_REWRITE_FORMAT,
-				   &dboid, &relid, &lsn_hi, &lsn_lo,
-				   &rewrite_xid_hi, &rewrite_xid_lo,
-				   &create_xid_hi, &create_xid_lo) != 8)
+				   &dboid, &relid, &hi, &lo, &rewrite_xid, &create_xid) != 6)
 			elog(ERROR, "could not parse filename \"%s\"", mapping_de->d_name);
 
-		lsn = ((uint64) lsn_hi) << 32 | lsn_lo;
+		lsn = ((uint64) hi) << 32 | lo;
 
 		if (lsn < cutoff || cutoff == InvalidXLogRecPtr)
 		{
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index b845ae9390..fa2eea8af2 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -55,6 +55,16 @@
  */
 #define SEQ_LOG_VALS	32
 
+/*
+ * The "special area" of a sequence's buffer page looks like this.
+ */
+#define SEQ_MAGIC	  0x1717
+
+typedef struct sequence_magic
+{
+	uint32		magic;
+} sequence_magic;
+
 /*
  * We store a SeqTable item for every sequence we have touched in the current
  * session.  This is needed to hold onto nextval/currval state.  (We can't
@@ -332,9 +342,10 @@ ResetSequence(Oid seq_relid)
 static void
 fill_seq_with_data(Relation rel, HeapTuple tuple)
 {
-	Buffer			buf;
-	Page			page;
-	OffsetNumber	offnum;
+	Buffer		buf;
+	Page		page;
+	sequence_magic *sm;
+	OffsetNumber offnum;
 
 	/* Initialize first page of relation with special magic number */
 
@@ -343,9 +354,9 @@ fill_seq_with_data(Relation rel, HeapTuple tuple)
 
 	page = BufferGetPage(buf);
 
-	PageInit(page, BufferGetPageSize(buf), sizeof(HeapPageSpecialData));
-	HeapPageGetSpecial(page)->pd_xid_base = RecentXmin - FirstNormalTransactionId;
-	HeapPageGetSpecial(page)->pd_magic = SEQ_PAGE_MAGIC;
+	PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
+	sm = (sequence_magic *) PageGetSpecialPointer(page);
+	sm->magic = SEQ_MAGIC;
 
 	/* Now insert sequence tuple */
 
@@ -358,10 +369,10 @@ fill_seq_with_data(Relation rel, HeapTuple tuple)
 	 * because if the current transaction aborts, no other xact will ever
 	 * examine the sequence tuple anyway.
 	 */
-	HeapTupleSetXmin(tuple, FrozenTransactionId);
+	HeapTupleHeaderSetXmin(tuple->t_data, FrozenTransactionId);
 	HeapTupleHeaderSetXminFrozen(tuple->t_data);
 	HeapTupleHeaderSetCmin(tuple->t_data, FirstCommandId);
-	HeapTupleSetXmax(tuple, InvalidTransactionId);
+	HeapTupleHeaderSetXmax(tuple->t_data, InvalidTransactionId);
 	tuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
 	ItemPointerSet(&tuple->t_data->t_ctid, 0, FirstOffsetNumber);
 
@@ -1159,18 +1170,18 @@ read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
 {
 	Page		page;
 	ItemId		lp;
-	HeapPageSpecial pageSpecial;
+	sequence_magic *sm;
 	Form_pg_sequence_data seq;
 
 	*buf = ReadBuffer(rel, 0);
 	LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
 
 	page = BufferGetPage(*buf);
-	pageSpecial = HeapPageGetSpecial(page);
+	sm = (sequence_magic *) PageGetSpecialPointer(page);
 
-	if (pageSpecial->pd_magic != SEQ_PAGE_MAGIC)
+	if (sm->magic != SEQ_MAGIC)
 		elog(ERROR, "bad magic number in sequence \"%s\": %08X",
-			 RelationGetRelationName(rel), pageSpecial->pd_magic);
+			 RelationGetRelationName(rel), sm->magic);
 
 	lp = PageGetItemId(page, FirstOffsetNumber);
 	Assert(ItemIdIsNormal(lp));
@@ -1178,7 +1189,6 @@ read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
 	/* Note we currently only bother to set these two fields of *seqdatatuple */
 	seqdatatuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
 	seqdatatuple->t_len = ItemIdGetLength(lp);
-	HeapTupleCopyBaseFromPage(seqdatatuple, page);
 
 	/*
 	 * Previous releases of Postgres neglected to prevent SELECT FOR UPDATE on
@@ -1189,9 +1199,9 @@ read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
 	 * this again if the update gets lost.
 	 */
 	Assert(!(seqdatatuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI));
-	if (HeapTupleGetRawXmax(seqdatatuple) != InvalidTransactionId)
+	if (HeapTupleHeaderGetRawXmax(seqdatatuple->t_data) != InvalidTransactionId)
 	{
-		HeapTupleSetXmax(seqdatatuple, InvalidTransactionId);
+		HeapTupleHeaderSetXmax(seqdatatuple->t_data, InvalidTransactionId);
 		seqdatatuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED;
 		seqdatatuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
 		MarkBufferDirtyHint(*buf, true);
@@ -1879,6 +1889,7 @@ seq_redo(XLogReaderState *record)
 	char	   *item;
 	Size		itemsz;
 	xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
+	sequence_magic *sm;
 
 	if (info != XLOG_SEQ_LOG)
 		elog(PANIC, "seq_redo: unknown op code %u", info);
@@ -1897,9 +1908,9 @@ seq_redo(XLogReaderState *record)
 	 */
 	localpage = (Page) palloc(BufferGetPageSize(buffer));
 
-	PageInit(localpage, BufferGetPageSize(buffer), sizeof(HeapPageSpecialData));
-	HeapPageGetSpecial(page)->pd_xid_base = RecentXmin - FirstNormalTransactionId;
-	HeapPageGetSpecial(page)->pd_magic = SEQ_PAGE_MAGIC;
+	PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
+	sm = (sequence_magic *) PageGetSpecialPointer(localpage);
+	sm->magic = SEQ_MAGIC;
 
 	item = (char *) xlrec + sizeof(xl_seq_rec);
 	itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 4f060d5039..98270a1049 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -58,12 +58,10 @@
 /*
  * GUC parameters
  */
-int64		vacuum_freeze_min_age;
-int64		vacuum_freeze_table_age;
-int64		vacuum_multixact_freeze_min_age;
-int64		vacuum_multixact_freeze_table_age;
-bool		vacuum_disable_page_skipping;
-bool		vacuum_disable_truncate;
+int			vacuum_freeze_min_age;
+int			vacuum_freeze_table_age;
+int			vacuum_multixact_freeze_min_age;
+int			vacuum_multixact_freeze_table_age;
 
 
 /* A few variables that don't seem worth passing around as parameters */
@@ -931,26 +929,24 @@ get_all_vacuum_rels(int options)
  */
 void
 vacuum_set_xid_limits(Relation rel,
-					  int64 freeze_min_age,
-					  int64 freeze_table_age,
-					  int64 multixact_freeze_min_age,
-					  int64 multixact_freeze_table_age,
+					  int freeze_min_age,
+					  int freeze_table_age,
+					  int multixact_freeze_min_age,
+					  int multixact_freeze_table_age,
 					  TransactionId *oldestXmin,
 					  TransactionId *freezeLimit,
 					  TransactionId *xidFullScanLimit,
 					  MultiXactId *multiXactCutoff,
 					  MultiXactId *mxactFullScanLimit)
 {
-	int64			freezemin;
-	int64			mxid_freezemin;
-	int64			effective_multixact_freeze_max_age;
+	int			freezemin;
+	int			mxid_freezemin;
+	int			effective_multixact_freeze_max_age;
 	TransactionId limit;
 	TransactionId safeLimit;
-	TransactionId nextXid;
 	MultiXactId oldestMxact;
 	MultiXactId mxactLimit;
 	MultiXactId safeMxactLimit;
-	MultiXactId nextMxactId;
 
 	/*
 	 * We can always ignore processes running lazy vacuum.  This is because we
@@ -999,10 +995,8 @@ vacuum_set_xid_limits(Relation rel,
 	/*
 	 * Compute the cutoff XID, being careful not to generate a "permanent" XID
 	 */
-	limit = *oldestXmin;
-	if (limit > FirstNormalTransactionId + freezemin)
-		limit -= freezemin;
-	else
+	limit = *oldestXmin - freezemin;
+	if (!TransactionIdIsNormal(limit))
 		limit = FirstNormalTransactionId;
 
 	/*
@@ -1010,10 +1004,8 @@ vacuum_set_xid_limits(Relation rel,
 	 * autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum
 	 * freeze age of zero.
 	 */
-	nextXid = ReadNewTransactionId();
-	if (nextXid > FirstNormalTransactionId + autovacuum_freeze_max_age)
-		safeLimit = nextXid - autovacuum_freeze_max_age;
-	else
+	safeLimit = ReadNewTransactionId() - autovacuum_freeze_max_age;
+	if (!TransactionIdIsNormal(safeLimit))
 		safeLimit = FirstNormalTransactionId;
 
 	if (TransactionIdPrecedes(limit, safeLimit))
@@ -1032,7 +1024,7 @@ vacuum_set_xid_limits(Relation rel,
 	 * normally autovacuum_multixact_freeze_max_age, but may be less if we are
 	 * short of multixact member space.
 	 */
-	effective_multixact_freeze_max_age = autovacuum_multixact_freeze_max_age;
+	effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
 
 	/*
 	 * Determine the minimum multixact freeze age to use: as specified by
@@ -1049,27 +1041,19 @@ vacuum_set_xid_limits(Relation rel,
 
 	/* compute the cutoff multi, being careful to generate a valid value */
 	oldestMxact = GetOldestMultiXactId();
-	if (oldestMxact > FirstMultiXactId + mxid_freezemin)
-		mxactLimit = oldestMxact - mxid_freezemin;
-	else
- 		mxactLimit = FirstMultiXactId;
+	mxactLimit = oldestMxact - mxid_freezemin;
+	if (mxactLimit < FirstMultiXactId)
+		mxactLimit = FirstMultiXactId;
 
-	nextMxactId = ReadNextMultiXactId();
-	if (nextMxactId > FirstMultiXactId + effective_multixact_freeze_max_age)
-		safeMxactLimit = nextMxactId - effective_multixact_freeze_max_age;
-	else
+	safeMxactLimit =
+		ReadNextMultiXactId() - effective_multixact_freeze_max_age;
+	if (safeMxactLimit < FirstMultiXactId)
 		safeMxactLimit = FirstMultiXactId;
 
 	if (MultiXactIdPrecedes(mxactLimit, safeMxactLimit))
 	{
 		ereport(WARNING,
-				(errmsg("oldest multixact is far in the past: "
-					INT64_FORMAT " " INT64_FORMAT " "
-					INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT " "
-					INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT " ",
-					multixact_freeze_min_age, vacuum_multixact_freeze_min_age,
-					mxactLimit, mxid_freezemin, oldestMxact,
-					safeMxactLimit, effective_multixact_freeze_max_age, nextMxactId),
+				(errmsg("oldest multixact is far in the past"),
 				 errhint("Close open transactions with multixacts soon to avoid wraparound problems.")));
 		/* Use the safe limit, unless an older mxact is still running */
 		if (MultiXactIdPrecedes(oldestMxact, safeMxactLimit))
@@ -1103,10 +1087,8 @@ vacuum_set_xid_limits(Relation rel,
 		 * Compute XID limit causing a full-table vacuum, being careful not to
 		 * generate a "permanent" XID.
 		 */
-		limit = ReadNewTransactionId();
-		if (limit > FirstNormalTransactionId + freezetable)
-			limit -= freezetable;
-		else
+		limit = ReadNewTransactionId() - freezetable;
+		if (!TransactionIdIsNormal(limit))
 			limit = FirstNormalTransactionId;
 
 		*xidFullScanLimit = limit;
@@ -1130,10 +1112,8 @@ vacuum_set_xid_limits(Relation rel,
 		 * Compute MultiXact limit causing a full-table vacuum, being careful
 		 * to generate a valid MultiXact value.
 		 */
-		mxactLimit = ReadNextMultiXactId();
-		if (mxactLimit > FirstMultiXactId + freezetable)
-			mxactLimit -= freezetable;
-		else
+		mxactLimit = ReadNextMultiXactId() - freezetable;
+		if (mxactLimit < FirstMultiXactId)
 			mxactLimit = FirstMultiXactId;
 
 		*mxactFullScanLimit = mxactLimit;
@@ -1693,6 +1673,13 @@ vac_truncate_clog(TransactionId frozenXID,
 	 */
 	AdvanceOldestCommitTsXid(frozenXID);
 
+	/*
+	 * Truncate CLOG, multixact and CommitTs to the oldest computed value.
+	 */
+	TruncateCLOG(frozenXID, oldestxid_datoid);
+	TruncateCommitTs(frozenXID);
+	TruncateMultiXact(minMulti, minmulti_datoid);
+
 	/*
 	 * Update the wrap limit for GetNewTransactionId and creation of new
 	 * MultiXactIds.  Note: these functions will also signal the postmaster
@@ -1702,13 +1689,6 @@ vac_truncate_clog(TransactionId frozenXID,
 	SetTransactionIdLimit(frozenXID, oldestxid_datoid);
 	SetMultiXactIdLimit(minMulti, minmulti_datoid, false);
 
-	/*
-	 * Truncate CLOG, multixact and CommitTs to the oldest computed value.
-	 */
-	TruncateCLOG(frozenXID, oldestxid_datoid);
-	TruncateCommitTs(frozenXID);
-	TruncateMultiXact(minMulti, minmulti_datoid);
-	
 	LWLockRelease(WrapLimitsVacuumLock);
 }
 
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 8e2f29c06d..feaf99b1ed 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -1118,7 +1118,6 @@ GetAttributeByNum(HeapTupleHeader tuple,
 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
 	ItemPointerSetInvalid(&(tmptup.t_self));
 	tmptup.t_tableOid = InvalidOid;
-	HeapTupleSetZeroBase(&tmptup);
 	tmptup.t_data = tuple;
 
 	result = heap_getattr(&tmptup,
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 702c4de08d..daf1759623 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -235,7 +235,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 			 * src/backend/access/heap/README.HOT for discussion.
 			 */
 			if (index->indcheckxmin &&
-				!TransactionIdPrecedes(HeapTupleGetXmin(indexRelation->rd_indextuple),
+				!TransactionIdPrecedes(HeapTupleHeaderGetXmin(indexRelation->rd_indextuple->t_data),
 									   TransactionXmin))
 			{
 				root->glob->transientPlan = true;
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index ba84d134e7..ed127a1032 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -121,8 +121,8 @@ int			autovacuum_vac_ins_thresh;
 double		autovacuum_vac_ins_scale;
 int			autovacuum_anl_thresh;
 double		autovacuum_anl_scale;
-int64			autovacuum_freeze_max_age;
-int64			autovacuum_multixact_freeze_max_age;
+int			autovacuum_freeze_max_age;
+int			autovacuum_multixact_freeze_max_age;
 
 double		autovacuum_vac_cost_delay;
 int			autovacuum_vac_cost_limit;
@@ -148,10 +148,10 @@ static TransactionId recentXid;
 static MultiXactId recentMulti;
 
 /* Default freeze ages to use for autovacuum (varies by database) */
-static int64	default_freeze_min_age;
-static int64	default_freeze_table_age;
-static int64	default_multixact_freeze_min_age;
-static int64	default_multixact_freeze_table_age;
+static int	default_freeze_min_age;
+static int	default_freeze_table_age;
+static int	default_multixact_freeze_min_age;
+static int	default_multixact_freeze_table_age;
 
 /* Memory context for long-lived data */
 static MemoryContext AutovacMemCxt;
@@ -1152,7 +1152,6 @@ do_start_worker(void)
 	ListCell   *cell;
 	TransactionId xidForceLimit;
 	MultiXactId multiForceLimit;
-	int64		multiMembersThreshold;
 	bool		for_xid_wrap;
 	bool		for_multi_wrap;
 	avw_dbase  *avdb;
@@ -1192,17 +1191,17 @@ do_start_worker(void)
 	 * particular tables, but not loosened.)
 	 */
 	recentXid = ReadNewTransactionId();
-	if (recentXid > FirstNormalTransactionId + autovacuum_freeze_max_age)
-		xidForceLimit = recentXid - autovacuum_freeze_max_age;
-	else
-		xidForceLimit = FirstNormalTransactionId;
+	xidForceLimit = recentXid - autovacuum_freeze_max_age;
+	/* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
+	/* this can cause the limit to go backwards by 3, but that's OK */
+	if (xidForceLimit < FirstNormalTransactionId)
+		xidForceLimit -= FirstNormalTransactionId;
 
 	/* Also determine the oldest datminmxid we will consider. */
-	multiMembersThreshold = autovacuum_multixact_freeze_max_age;
-	if (recentMulti > FirstMultiXactId + multiMembersThreshold)
-		multiForceLimit = recentMulti - multiMembersThreshold;
-	else
-		multiForceLimit = FirstMultiXactId;
+	recentMulti = ReadNextMultiXactId();
+	multiForceLimit = recentMulti - MultiXactMemberFreezeThreshold();
+	if (multiForceLimit < FirstMultiXactId)
+		multiForceLimit -= FirstMultiXactId;
 
 	/*
 	 * Choose a database to connect to.  We pick the database that was least
@@ -1967,7 +1966,7 @@ do_autovacuum(void)
 	BufferAccessStrategy bstrategy;
 	ScanKeyData key;
 	TupleDesc	pg_class_desc;
-	int64		effective_multixact_freeze_max_age;
+	int			effective_multixact_freeze_max_age;
 	bool		did_vacuum = false;
 	bool		found_concurrent_worker = false;
 	int			i;
@@ -2003,7 +2002,7 @@ do_autovacuum(void)
 	 * normally autovacuum_multixact_freeze_max_age, but may be less if we are
 	 * short of multixact member space.
 	 */
-	effective_multixact_freeze_max_age = autovacuum_multixact_freeze_max_age;
+	effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
 
 	/*
 	 * Find the pg_database entry and select the default freeze ages. We use
@@ -2794,7 +2793,7 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
 static autovac_table *
 table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 					  TupleDesc pg_class_desc,
-					  int64 effective_multixact_freeze_max_age)
+					  int effective_multixact_freeze_max_age)
 {
 	Form_pg_class classForm;
 	HeapTuple	classTup;
@@ -2863,10 +2862,10 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 	/* OK, it needs something done */
 	if (doanalyze || dovacuum)
 	{
-		int64		freeze_min_age;
-		int64		freeze_table_age;
-		int64		multixact_freeze_min_age;
-		int64		multixact_freeze_table_age;
+		int			freeze_min_age;
+		int			freeze_table_age;
+		int			multixact_freeze_min_age;
+		int			multixact_freeze_table_age;
 		int			vac_cost_limit;
 		double		vac_cost_delay;
 		int			log_min_duration;
@@ -3048,7 +3047,7 @@ relation_needs_vacanalyze(Oid relid,
 						  AutoVacOpts *relopts,
 						  Form_pg_class classForm,
 						  PgStat_StatTabEntry *tabentry,
-						  int64 effective_multixact_freeze_max_age,
+						  int effective_multixact_freeze_max_age,
  /* output params below */
 						  bool *dovacuum,
 						  bool *doanalyze,
@@ -3077,8 +3076,8 @@ relation_needs_vacanalyze(Oid relid,
 				anltuples;
 
 	/* freeze parameters */
-	int64			freeze_max_age;
-	int64			multixact_freeze_max_age;
+	int			freeze_max_age;
+	int			multixact_freeze_max_age;
 	TransactionId xidForceLimit;
 	MultiXactId multiForceLimit;
 
@@ -3129,19 +3128,16 @@ relation_needs_vacanalyze(Oid relid,
 
 	/* Force vacuum if table is at risk of wraparound */
 	xidForceLimit = recentXid - freeze_max_age;
-	if (recentXid > FirstNormalTransactionId + freeze_max_age)
-		xidForceLimit = recentXid - freeze_max_age;
-	else
-		xidForceLimit = FirstNormalTransactionId;
+	if (xidForceLimit < FirstNormalTransactionId)
+		xidForceLimit -= FirstNormalTransactionId;
 	force_vacuum = (TransactionIdIsNormal(classForm->relfrozenxid) &&
 					TransactionIdPrecedes(classForm->relfrozenxid,
 										  xidForceLimit));
 	if (!force_vacuum)
 	{
-		if (recentMulti > FirstMultiXactId + multixact_freeze_max_age)
-			multiForceLimit = recentMulti - multixact_freeze_max_age;
-		else
-			multiForceLimit = FirstMultiXactId;
+		multiForceLimit = recentMulti - multixact_freeze_max_age;
+		if (multiForceLimit < FirstMultiXactId)
+			multiForceLimit -= FirstMultiXactId;
 		force_vacuum = MultiXactIdIsValid(classForm->relminmxid) &&
 			MultiXactIdPrecedes(classForm->relminmxid, multiForceLimit);
 	}
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 62eedfdec4..3613ae5f44 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -1837,8 +1837,6 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 		ct->tuple.t_len = dtp->t_len;
 		ct->tuple.t_self = dtp->t_self;
 		ct->tuple.t_tableOid = dtp->t_tableOid;
-		ct->tuple.t_xid_base = dtp->t_xid_base;
-		ct->tuple.t_multi_base = dtp->t_multi_base;
 		ct->tuple.t_data = (HeapTupleHeader)
 			MAXALIGN(((char *) ct) + sizeof(CatCTup));
 		/* copy tuple contents */
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 64b74d30c7..3bd5e18042 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -2250,9 +2250,8 @@ RelationReloadIndexInfo(Relation relation)
 		relation->rd_index->indislive = index->indislive;
 
 		/* Copy xmin too, as that is needed to make sense of indcheckxmin */
-		relation->rd_indextuple->t_xid_base = tuple->t_xid_base;
-		HeapTupleSetXmin(relation->rd_indextuple,
-						 HeapTupleGetXmin(tuple));
+		HeapTupleHeaderSetXmin(relation->rd_indextuple->t_data,
+							   HeapTupleHeaderGetXmin(tuple->t_data));
 
 		ReleaseSysCache(tuple);
 	}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 31731a9aa3..fa5f7ac615 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -543,7 +543,7 @@ lookup_C_func(HeapTuple procedureTuple)
 					NULL);
 	if (entry == NULL)
 		return NULL;			/* no such entry */
-	if (entry->fn_xmin == HeapTupleGetRawXmin(procedureTuple) &&
+	if (entry->fn_xmin == HeapTupleHeaderGetRawXmin(procedureTuple->t_data) &&
 		ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
 		return entry;			/* OK */
 	return NULL;				/* entry is out of date */
@@ -579,7 +579,7 @@ record_C_func(HeapTuple procedureTuple,
 					HASH_ENTER,
 					&found);
 	/* OID is already filled in */
-	entry->fn_xmin = HeapTupleGetRawXmin(procedureTuple);
+	entry->fn_xmin = HeapTupleHeaderGetRawXmin(procedureTuple->t_data);
 	entry->fn_tid = procedureTuple->t_self;
 	entry->user_fn = user_fn;
 	entry->inforec = inforec;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 073726aa67..45a79d6ec3 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -3149,6 +3149,27 @@ static struct config_int ConfigureNamesInt[] =
 		50, 0, INT_MAX,
 		NULL, NULL, NULL
 	},
+	{
+		/* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
+		{"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
+			gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."),
+			NULL
+		},
+		&autovacuum_freeze_max_age,
+		/* see pg_resetwal if you change the upperlimit value */
+		200000000, 100000, 2000000000,
+		NULL, NULL, NULL
+	},
+	{
+		/* see multixact.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
+		{"autovacuum_multixact_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
+			gettext_noop("Multixact age at which to autovacuum a table to prevent multixact wraparound."),
+			NULL
+		},
+		&autovacuum_multixact_freeze_max_age,
+		400000000, 10000, 2000000000,
+		NULL, NULL, NULL
+	},
 	{
 		/* see max_connections */
 		{"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM,
@@ -3660,77 +3681,6 @@ static struct config_real ConfigureNamesReal[] =
 
 static struct config_int64 ConfigureNamesInt64[] =
 {
-	{
-		{"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
-			gettext_noop("Minimum age at which VACUUM should freeze a table row."),
-			NULL
-		},
-		&vacuum_freeze_min_age,
-		INT64CONST(50000000), INT64CONST(0), INT64CONST(0x7FFFFFFFFFFFFFFF),
-		NULL, NULL, NULL
-	},
-
-	{
-		{"vacuum_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
-			gettext_noop("Age at which VACUUM should scan whole table to freeze tuples."),
-			NULL
-		},
-		&vacuum_freeze_table_age,
-		INT64CONST(150000000), INT64CONST(0), INT64CONST(0x7FFFFFFFFFFFFFFF),
-		NULL, NULL, NULL
-	},
-
-	{
-		{"vacuum_multixact_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
-			gettext_noop("Minimum age at which VACUUM should freeze a MultiXactId in a table row."),
-			NULL
-		},
-		&vacuum_multixact_freeze_min_age,
-		INT64CONST(5000000), INT64CONST(0), INT64CONST(0x7FFFFFFFFFFFFFFF),
-		NULL, NULL, NULL
-	},
-
-	{
-		{"vacuum_multixact_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
-			gettext_noop("Multixact age at which VACUUM should scan whole table to freeze tuples."),
-			NULL
-		},
-		&vacuum_multixact_freeze_table_age,
-		INT64CONST(150000000), INT64CONST(0), INT64CONST(0x7FFFFFFFFFFFFFFF),
-		NULL, NULL, NULL
-	},
-
-	{
-		{"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_MASTER,
-			gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."),
-			NULL
-		},
-		&vacuum_defer_cleanup_age,
-		INT64CONST(0), INT64CONST(0), INT64CONST(1000000),
-		NULL, NULL, NULL
-	},
-
-	{
-		/* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
-		{"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
-			gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."),
-			NULL
-		},
-		&autovacuum_freeze_max_age,
-		/* see pg_resetxlog if you change the upper-limit value */
-		INT64CONST(10000000000), INT64CONST(100000), INT64CONST(0x7FFFFFFFFFFFFFFF),
-		NULL, NULL, NULL
-	},
-	{
-		/* see multixact.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
-		{"autovacuum_multixact_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
-			gettext_noop("Multixact age at which to autovacuum a table to prevent multixact wraparound."),
-			NULL
-		},
-		&autovacuum_multixact_freeze_max_age,
-		INT64CONST(20000000000), INT64CONST(10000), INT64CONST(0x7FFFFFFFFFFFFFFF),
-		NULL, NULL, NULL
-	},
 
 	/* End-of-list marker */
 	{
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c29956d33d..d0cc04a878 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -4119,17 +4119,13 @@ static void
 writetup_cluster(Tuplesortstate *state, int tapenum, SortTuple *stup)
 {
 	HeapTuple	tuple = (HeapTuple) stup->tuple;
-	unsigned int tuplen = tuple->t_len + sizeof(ItemPointerData) + 2 * sizeof(TransactionId) + sizeof(int);
+	unsigned int tuplen = tuple->t_len + sizeof(ItemPointerData) + sizeof(int);
 
 	/* We need to store t_self, but not other fields of HeapTupleData */
 	LogicalTapeWrite(state->tapeset, tapenum,
 					 &tuplen, sizeof(tuplen));
 	LogicalTapeWrite(state->tapeset, tapenum,
 					 &tuple->t_self, sizeof(ItemPointerData));
-	LogicalTapeWrite(state->tapeset, tapenum,
-					 &tuple->t_xid_base, sizeof(TransactionId));  // FIXME - 64-bit XIDs - should this be FullTransactionId instead?
-	LogicalTapeWrite(state->tapeset, tapenum,
-					 &tuple->t_multi_base, sizeof(TransactionId));  // FIXME - 64-bit XIDs - should this be FullTransactionId instead?
 	LogicalTapeWrite(state->tapeset, tapenum,
 					 tuple->t_data, tuple->t_len);
 	if (state->randomAccess)	/* need trailing length word? */
@@ -4147,7 +4143,7 @@ static void
 readtup_cluster(Tuplesortstate *state, SortTuple *stup,
 				int tapenum, unsigned int tuplen)
 {
-	unsigned int t_len = tuplen - sizeof(ItemPointerData) - 2 * sizeof(TransactionId) - sizeof(int);
+	unsigned int t_len = tuplen - sizeof(ItemPointerData) - sizeof(int);
 	HeapTuple	tuple = (HeapTuple) readtup_alloc(state,
 												  t_len + HEAPTUPLESIZE);
 
@@ -4156,10 +4152,6 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup,
 	tuple->t_len = t_len;
 	LogicalTapeReadExact(state->tapeset, tapenum,
 						 &tuple->t_self, sizeof(ItemPointerData));
-	LogicalTapeReadExact(state->tapeset, tapenum,
-						 &tuple->t_xid_base, sizeof(TransactionId));   // FIXME - FullTransactionId?
-	LogicalTapeReadExact(state->tapeset, tapenum,
-						 &tuple->t_multi_base, sizeof(TransactionId)); // FIXME - FullTransactionId?
 	/* We don't currently bother to reconstruct t_tableOid */
 	tuple->t_tableOid = InvalidOid;
 	/* Read in the tuple body */
diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c
index e14c15519e..9626f98100 100644
--- a/src/backend/utils/time/combocid.c
+++ b/src/backend/utils/time/combocid.c
@@ -128,7 +128,7 @@ HeapTupleHeaderGetCmax(HeapTupleHeader tup)
 	 * things too much.
 	 */
 	Assert(CritSectionCount > 0 ||
-	  TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tup)));
+		   TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tup)));
 
 	if (tup->t_infomask & HEAP_COMBOCID)
 		return GetRealCmax(cid);
@@ -150,7 +150,7 @@ HeapTupleHeaderGetCmax(HeapTupleHeader tup)
  * changes the tuple in shared buffers.
  */
 void
-HeapTupleHeaderAdjustCmax(HeapTuple tup,
+HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
 						  CommandId *cmax,
 						  bool *iscombo)
 {
@@ -160,10 +160,10 @@ HeapTupleHeaderAdjustCmax(HeapTuple tup,
 	 * Test for HeapTupleHeaderXminCommitted() first, because it's cheaper
 	 * than a TransactionIdIsCurrentTransactionId call.
 	 */
-	if (!HeapTupleHeaderXminCommitted(tup->t_data) &&
-		TransactionIdIsCurrentTransactionId(HeapTupleGetRawXmin(tup)))
+	if (!HeapTupleHeaderXminCommitted(tup) &&
+		TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tup)))
 	{
-		CommandId	cmin = HeapTupleHeaderGetCmin(tup->t_data);
+		CommandId	cmin = HeapTupleHeaderGetCmin(tup);
 
 		*cmax = GetComboCommandId(cmin, *cmax);
 		*iscombo = true;
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index e000e87c6d..54b2eb7378 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -154,10 +154,10 @@ extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,
 								 Buffer *buffer, struct TM_FailureData *tmfd);
 
 extern void heap_inplace_update(Relation relation, HeapTuple tuple);
-extern bool heap_freeze_tuple(HeapTuple tuple,
+extern bool heap_freeze_tuple(HeapTupleHeader tuple,
 							  TransactionId relfrozenxid, TransactionId relminmxid,
 							  TransactionId cutoff_xid, TransactionId cutoff_multi);
-extern bool heap_tuple_needs_freeze(HeapTuple tuple, TransactionId cutoff_xid,
+extern bool heap_tuple_needs_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid,
 									MultiXactId cutoff_multi, Buffer buf);
 extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple);
 
@@ -178,12 +178,11 @@ extern int	heap_page_prune(Relation relation, Buffer buffer,
 							TransactionId limited_oldest_xmin,
 							TimestampTz limited_oldest_ts,
 							bool report_stats, TransactionId *latestRemovedXid,
-							OffsetNumber *off_loc, bool repairFragmentation);
+							OffsetNumber *off_loc);
 extern void heap_page_prune_execute(Buffer buffer,
 									OffsetNumber *redirected, int nredirected,
 									OffsetNumber *nowdead, int ndead,
-									OffsetNumber *nowunused, int nunused,
-									bool repairFragmentation);
+									OffsetNumber *nowunused, int nunused);
 extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets);
 
 /* in heap/vacuumlazy.c */
@@ -203,7 +202,7 @@ extern HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple stup, Buffer buffer
 												   TransactionId *dead_after);
 extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
 								 uint16 infomask, TransactionId xid);
-extern bool HeapTupleHeaderIsOnlyLocked(HeapTuple tuple);
+extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple);
 extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
 extern bool HeapTupleIsSurelyDead(HeapTuple htup,
 								  struct GlobalVisState *vistest);
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 6b71be3219..791883c4a7 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -62,11 +62,9 @@ typedef MinimalTupleData *MinimalTuple;
 typedef struct HeapTupleData
 {
 	uint32		t_len;			/* length of *t_data */
+	ItemPointerData t_self;		/* SelfItemPointer */
 	Oid			t_tableOid;		/* table the tuple came from */
 #define FIELDNO_HEAPTUPLEDATA_DATA 3
-	FullTransactionId	t_xid_base;
-	FullTransactionId	t_multi_base;
-	ItemPointerData t_self;		/* SelfItemPointer */
 	HeapTupleHeader t_data;		/* -> tuple header and data */
 } HeapTupleData;
 
@@ -82,10 +80,10 @@ typedef HeapTupleData *HeapTuple;
 /* HeapTupleHeader functions implemented in utils/time/combocid.c */
 extern CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup);
 extern CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup);
-extern void HeapTupleHeaderAdjustCmax(HeapTuple tup,
+extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
 									  CommandId *cmax, bool *iscombo);
 
 /* Prototype for HeapTupleHeader accessors in heapam.c */
-extern TransactionId HeapTupleGetUpdateXid(HeapTuple tuple);
+extern TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple);
 
 #endif							/* HTUP_H */
diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
index db54cd16cf..aebb1082ca 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -297,24 +297,6 @@ struct HeapTupleHeaderData
  * macros evaluate their other argument only once.
  */
 
-#define HeapTupleCopyBaseFromPage(tup, page) \
-{ \
-	(tup)->t_xid_base = HeapPageGetSpecial(page)->pd_xid_base; \
-	(tup)->t_multi_base = HeapPageGetSpecial(page)->pd_multi_base; \
-}
-
-#define HeapTupleCopyBase(dest, src) \
-{ \
-	(dest)->t_xid_base = (src)->t_xid_base; \
-	(dest)->t_multi_base = (src)->t_multi_base; \
-}
-
-#define HeapTupleSetZeroBase(tup) \
-{ \
-	(tup)->t_xid_base = InvalidTransactionId; \
-	(tup)->t_multi_base = InvalidTransactionId; \
-}
-
 /*
  * HeapTupleHeaderGetRawXmin returns the "raw" xmin field, which is the xid
  * originally used to insert the tuple.  However, the tuple might actually
@@ -325,28 +307,18 @@ struct HeapTupleHeaderData
  */
 #define HeapTupleHeaderGetRawXmin(tup) \
 ( \
-	TransactionIdToFull((tup)->t_xid_base, (tup)->t_data->t_choice.t_heap.t_xmin) \
+	(tup)->t_choice.t_heap.t_xmin \
 )
 
 #define HeapTupleHeaderGetXmin(tup) \
 ( \
-	HeapTupleHeaderXminFrozen((tup)->t_data) ? \
-		FrozenTransactionId : HeapTupleGetRawXmin(tup) \
+	HeapTupleHeaderXminFrozen(tup) ? \
+		FrozenTransactionId : HeapTupleHeaderGetRawXmin(tup) \
 )
 
 #define HeapTupleHeaderSetXmin(tup, xid) \
 ( \
-	(tup)->t_data->t_choice.t_heap.t_xmin = FullTransactionIdToShort((tup)->t_xid_base, (xid)) /* TBD 64bit XID FIXME */  \
-)
-
-#define HeapTupleSetXmin(tup, xid) \
-( \
-	(tup)->t_data->t_choice.t_heap.t_xmin = FullTransactionIdToShort((tup)->t_xid_base, (xid)) \
-)
-
-#define HeapTupleHeaderSetXmin(page, tup, xid) \
-( \
-	(tup)->t_choice.t_heap.t_xmin = FullTransactionIdToShort(HeapPageGetSpecial(page)->pd_xid_base, (xid)) \
+	(tup)->t_choice.t_heap.t_xmin = (xid) \
 )
 
 #define HeapTupleHeaderXminCommitted(tup) \
@@ -390,44 +362,24 @@ struct HeapTupleHeaderData
  * to resolve the MultiXactId if necessary.  This might involve multixact I/O,
  * so it should only be used if absolutely necessary.
  */
-#define HeapTupleGetUpdateXidAny(tup) \
+#define HeapTupleHeaderGetUpdateXid(tup) \
 ( \
-	(!((tup)->t_data->t_infomask & HEAP_XMAX_INVALID) && \
-	 ((tup)->t_data->t_infomask & HEAP_XMAX_IS_MULTI) && \
-	 !((tup)->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY)) ? \
+	(!((tup)->t_infomask & HEAP_XMAX_INVALID) && \
+	 ((tup)->t_infomask & HEAP_XMAX_IS_MULTI) && \
+	 !((tup)->t_infomask & HEAP_XMAX_LOCK_ONLY)) ? \
 		HeapTupleGetUpdateXid(tup) \
 	: \
-		HeapTupleGetRawXmax(tup) \
-)
-
-#define HeapTupleGetRawXmax(tup) \
-( \
-	TransactionIdToFull( /* TBD 64bit XID FIXME */	\
-		((tup)->t_data->t_infomask & HEAP_XMAX_IS_MULTI) ? (tup)->t_multi_base : (tup)->t_xid_base, \
-		(tup)->t_data->t_choice.t_heap.t_xmax) \
-)
-
-#define HeapTupleHeaderGetRawXmax(page, tup) \
-( \
-	TransactionIdToFull(	/* TBD 64bit XID FIXME */					\
-		((tup)->t_infomask & HEAP_XMAX_IS_MULTI) ? HeapPageGetSpecial(page)->pd_multi_base : HeapPageGetSpecial(page)->pd_xid_base, \
-		(tup)->t_choice.t_heap.t_xmax) \
+		HeapTupleHeaderGetRawXmax(tup) \
 )
 
-#define HeapTupleSetXmax(tup, xid)				\
+#define HeapTupleHeaderGetRawXmax(tup) \
 ( \
-	(tup)->t_data->t_choice.t_heap.t_xmax = \
-		FullTransactionIdToShort( /* TBD 64bit XID FIXME */ \
-			((tup)->t_data->t_infomask & HEAP_XMAX_IS_MULTI) ? (tup)->t_multi_base : (tup)->t_xid_base, \
-			(xid)) \
+	(tup)->t_choice.t_heap.t_xmax \
 )
 
-#define HeapTupleHeaderSetXmax(page, tup, xid) \
+#define HeapTupleHeaderSetXmax(tup, xid) \
 ( \
-	(tup)->t_choice.t_heap.t_xmax = \
-		FullTransactionIdToShort( /* TBD 64bit XID FIXME */ \
-			((tup)->t_infomask & HEAP_XMAX_IS_MULTI) ? HeapPageGetSpecial(page)->pd_multi_base : HeapPageGetSpecial(page)->pd_xid_base, \
-			(xid)) \
+	(tup)->t_choice.t_heap.t_xmax = (xid) \
 )
 
 /*
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 9030415d0b..a4cd721400 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -208,11 +208,11 @@ typedef enum VacOptTernaryValue
 typedef struct VacuumParams
 {
 	int			options;		/* bitmask of VacuumOption */
-	int64		freeze_min_age; /* min freeze age, -1 to use default */
-	int64		freeze_table_age;	/* age at which to scan whole table */
-	int64		multixact_freeze_min_age;	/* min multixact freeze age, -1 to
+	int			freeze_min_age; /* min freeze age, -1 to use default */
+	int			freeze_table_age;	/* age at which to scan whole table */
+	int			multixact_freeze_min_age;	/* min multixact freeze age, -1 to
 											 * use default */
-	int64		multixact_freeze_table_age; /* multixact age at which to scan
+	int			multixact_freeze_table_age; /* multixact age at which to scan
 											 * whole table */
 	bool		is_wraparound;	/* force a for-wraparound vacuum */
 	int			log_min_duration;	/* minimum execution threshold in ms at
@@ -233,12 +233,10 @@ typedef struct VacuumParams
 
 /* GUC parameters */
 extern PGDLLIMPORT int default_statistics_target;	/* PGDLLIMPORT for PostGIS */
-extern int64	vacuum_freeze_min_age;
-extern int64	vacuum_freeze_table_age;
-extern int64	vacuum_multixact_freeze_min_age;
-extern int64	vacuum_multixact_freeze_table_age;
-extern bool	vacuum_disable_page_skipping;
-extern bool	vacuum_disable_truncate;
+extern int	vacuum_freeze_min_age;
+extern int	vacuum_freeze_table_age;
+extern int	vacuum_multixact_freeze_min_age;
+extern int	vacuum_multixact_freeze_table_age;
 
 /* Variables for cost-based parallel vacuum */
 extern pg_atomic_uint32 *VacuumSharedCostBalance;
@@ -266,9 +264,9 @@ extern void vac_update_relstats(Relation relation,
 								MultiXactId minmulti,
 								bool in_outer_xact);
 extern void vacuum_set_xid_limits(Relation rel,
-								  int64 freeze_min_age, int64 freeze_table_age,
-								  int64 multixact_freeze_min_age,
-								  int64 multixact_freeze_table_age,
+								  int freeze_min_age, int freeze_table_age,
+								  int multixact_freeze_min_age,
+								  int multixact_freeze_table_age,
 								  TransactionId *oldestXmin,
 								  TransactionId *freezeLimit,
 								  TransactionId *xidFullScanLimit,
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 9fcaed5bdd..7277effe03 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -37,8 +37,8 @@ extern int	autovacuum_vac_ins_thresh;
 extern double autovacuum_vac_ins_scale;
 extern int	autovacuum_anl_thresh;
 extern double autovacuum_anl_scale;
-extern int64 autovacuum_freeze_max_age;
-extern int64 autovacuum_multixact_freeze_max_age;
+extern int	autovacuum_freeze_max_age;
+extern int	autovacuum_multixact_freeze_max_age;
 extern double autovacuum_vac_cost_delay;
 extern int	autovacuum_vac_cost_limit;
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index bd98548abe..c5ffea40f2 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -282,12 +282,12 @@ typedef struct AutoVacOpts
 	int			vacuum_ins_threshold;
 	int			analyze_threshold;
 	int			vacuum_cost_limit;
-	int64		freeze_min_age;
-	int64		freeze_max_age;
-	int64		freeze_table_age;
-	int64		multixact_freeze_min_age;
-	int64		multixact_freeze_max_age;
-	int64		multixact_freeze_table_age;
+	int			freeze_min_age;
+	int			freeze_max_age;
+	int			freeze_table_age;
+	int			multixact_freeze_min_age;
+	int			multixact_freeze_max_age;
+	int			multixact_freeze_table_age;
 	int			log_min_duration;
 	float8		vacuum_cost_delay;
 	float8		vacuum_scale_factor;
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index c8f1e4f526..6299adf71a 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -2659,7 +2659,7 @@ validate_plperl_function(plperl_proc_ptr *proc_ptr, HeapTuple procTup)
 		 * This is needed because CREATE OR REPLACE FUNCTION can modify the
 		 * function's pg_proc entry without changing its OID.
 		 ************************************************************/
-		uptodate = (prodesc->fn_xmin == HeapTupleGetRawXmin(procTup) &&
+		uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
 					ItemPointerEquals(&prodesc->fn_tid, &procTup->t_self));
 
 		if (uptodate)
@@ -2783,7 +2783,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
 		MemoryContextSetIdentifier(proc_cxt, prodesc->proname);
 		prodesc->fn_cxt = proc_cxt;
 		prodesc->fn_refcount = 0;
-		prodesc->fn_xmin = HeapTupleGetRawXmin(procTup);
+		prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
 		prodesc->fn_tid = procTup->t_self;
 		prodesc->nargs = procStruct->pronargs;
 		prodesc->arg_out_func = (FmgrInfo *) palloc0(prodesc->nargs * sizeof(FmgrInfo));
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 5c6b28607f..042deb2a96 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -171,7 +171,7 @@ recheck:
 	if (function)
 	{
 		/* We have a compiled function, but is it still valid? */
-		if (function->fn_xmin == HeapTupleGetRawXmin(procTup) &&
+		if (function->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
 			ItemPointerEquals(&function->fn_tid, &procTup->t_self))
 			function_valid = true;
 		else
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index 9ceae43189..b7c0b5cebe 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -178,7 +178,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
 		proc->proname = pstrdup(NameStr(procStruct->proname));
 		MemoryContextSetIdentifier(cxt, proc->proname);
 		proc->pyname = pstrdup(procName);
-		proc->fn_xmin = HeapTupleGetRawXmin(procTup);
+		proc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
 		proc->fn_tid = procTup->t_self;
 		proc->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
 		proc->is_setof = procStruct->proretset;
@@ -419,7 +419,7 @@ PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup)
 		return false;
 
 	/* If the pg_proc tuple has changed, it's not valid */
-	if (!(proc->fn_xmin == HeapTupleGetRawXmin(procTup) &&
+	if (!(proc->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
 		  ItemPointerEquals(&proc->fn_tid, &procTup->t_self)))
 		return false;
 
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index cdbdce3044..e11837559d 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -1423,7 +1423,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
 	 * function's pg_proc entry without changing its OID.
 	 ************************************************************/
 	if (prodesc != NULL &&
-		prodesc->fn_xmin == HeapTupleGetRawXmin(procTup) &&
+		prodesc->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
 		ItemPointerEquals(&prodesc->fn_tid, &procTup->t_self))
 	{
 		/* It's still up-to-date, so we can use it */
@@ -1490,7 +1490,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid,
 		prodesc->internal_proname = pstrdup(internal_proname);
 		prodesc->fn_cxt = proc_cxt;
 		prodesc->fn_refcount = 0;
-		prodesc->fn_xmin = HeapTupleGetRawXmin(procTup);
+		prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
 		prodesc->fn_tid = procTup->t_self;
 		prodesc->nargs = procStruct->pronargs;
 		prodesc->arg_out_func = (FmgrInfo *) palloc0(prodesc->nargs * sizeof(FmgrInfo));
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index ce89845fe3..4cc55d8525 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -1673,7 +1673,7 @@ from pg_locks l join pg_class c on l.relation = c.oid
 where virtualtransaction = (
         select virtualtransaction
         from pg_locks
-        where transactionid = pg_current_xact_id()::xid) -- TBD for 64bit xids, this becomes xid8
+        where transactionid = pg_current_xact_id()::xid)
 and locktype = 'relation'
 and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
 and c.relname != 'my_locks'
@@ -1760,7 +1760,7 @@ from pg_locks l join pg_class c on l.relation = c.oid
 where virtualtransaction = (
         select virtualtransaction
         from pg_locks
-        where transactionid = pg_current_xact_id()::xid) -- TBD for 64bit xids, this becomes xid8
+        where transactionid = pg_current_xact_id()::xid)
 and locktype = 'relation'
 and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
 and c.relname = 'my_locks'
