Heikki pointed out to me that the btree delete record processing does
not respect vacuum_defer_cleanup_age. It should.

Attached patch to implement that.

Looking to commit in next few hours barring objections/suggestions, to
both HEAD and 9_0_STABLE, in time for next minor release.

-- 
 Simon Riggs           http://www.2ndQuadrant.com/books/
 PostgreSQL Development, 24x7 Support, Training and Services
 
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index 0822f5c..5b2d58a 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -683,6 +683,12 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record)
 	UnlockReleaseBuffer(ibuffer);
 
 	/*
+	 * Apply vacuum_defer_cleanup_age, if we have a valid xid.
+	 */
+	if (TransactionIdIsValid(latestRemovedXid))
+		TransactionIdRetreatMany(latestRemovedXid, vacuum_defer_cleanup_age);
+
+	/*
 	 * Note that if all heap tuples were LP_DEAD then we will be returning
 	 * InvalidTransactionId here. That can happen if we are re-replaying this
 	 * record type, though that will be before the consistency point and will
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 6e7a6db..c16a287 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -1129,8 +1129,7 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
 	LWLockRelease(ProcArrayLock);
 
 	/*
-	 * Compute the cutoff XID, being careful not to generate a "permanent"
-	 * XID.
+	 * Compute the cutoff XID, being careful not to generate a reserved XID.
 	 *
 	 * vacuum_defer_cleanup_age provides some additional "slop" for the
 	 * benefit of hot standby queries on slave servers.  This is quick and
@@ -1140,9 +1139,7 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
 	 * wraparound --- so guc.c should limit it to no more than the
 	 * xidStopLimit threshold in varsup.c.
 	 */
-	result -= vacuum_defer_cleanup_age;
-	if (!TransactionIdIsNormal(result))
-		result = FirstNormalTransactionId;
+	TransactionIdRetreatMany(result, vacuum_defer_cleanup_age);
 
 	return result;
 }
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index a7ae752..2f7070e 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -58,6 +58,19 @@
 		(dest)--; \
 	} while ((dest) < FirstNormalTransactionId)
 
+#define TransactionIdRetreatMany(dest, many)	\
+{ \
+	if ((dest) >= (many)) \
+	{ \
+		(dest) -= (many); \
+		while ((dest) < FirstNormalTransactionId) \
+		{ \
+			(dest)--; \
+		} \
+	} \
+	else \
+		(dest) = MaxTransactionId - (many) + (dest); \
+}
 
 /* ----------
  *		Object ID (OID) zero is InvalidOid.
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to