From 766dcfb16ca385274d510eaed01724bb3836efdd Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 23 Jul 2015 01:29:59 +0300 Subject: Fix off-by-one error in calculating subtrans/multixact truncation point. If there were no subtransactions (or multixacts) active, we would calculate the oldestxid == next xid. That's correct, but if next XID happens to be on the next pg_subtrans (pg_multixact) page, the page does not exist yet, and SimpleLruTruncate will produce an "apparent wraparound" warning. The warning is harmless in this case, but looks very alarming to users. Backpatch to all supported versions. Patch and analysis by Thomas Munro. --- src/backend/access/transam/multixact.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/backend/access/transam/multixact.c') diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 377d0842bdd..1933a87d656 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -173,6 +173,8 @@ #define MULTIXACT_MEMBER_DANGER_THRESHOLD \ (MaxMultiXactOffset - MaxMultiXactOffset / 4) +#define PreviousMultiXactId(xid) \ + ((xid) == FirstMultiXactId ? MaxMultiXactId : (xid) - 1) /* * Links to shared-memory data structures for MultiXact control @@ -3057,10 +3059,15 @@ TruncateMultiXact(void) SlruScanDirectory(MultiXactMemberCtl, SlruScanDirCbRemoveMembers, &range); - /* Now we can truncate MultiXactOffset */ + /* + * Now we can truncate MultiXactOffset. We step back one multixact to + * avoid passing a cutoff page that hasn't been created yet in the rare + * case that oldestMXact would be the first item on a page and oldestMXact + * == nextMXact. In that case, if we didn't subtract one, we'd trigger + * SimpleLruTruncate's wraparound detection. + */ SimpleLruTruncate(MultiXactOffsetCtl, - MultiXactIdToOffsetPage(oldestMXact)); - + MultiXactIdToOffsetPage(PreviousMultiXactId(oldestMXact))); /* * Now, and only now, we can advance the stop point for multixact members. -- cgit v1.2.3