summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas2015-06-19 15:28:30 +0000
committerRobert Haas2015-06-19 15:35:44 +0000
commit8507a5b37bd95717572c5fd1863758f478fe7b10 (patch)
tree7a388547ebdc651d9f289f24a3ad50341877d95e
parent2a781b5bb260209be0d856c6a43d15194d6848e0 (diff)
Fix corner case in autovacuum-forcing logic for multixact wraparound.
Since find_multixact_start() relies on SimpleLruDoesPhysicalPageExist(), and that function looks only at the on-disk state, it's possible for it to fail to find a page that exists in the in-memory SLRU that has not been written yet. If that happens, SetOffsetVacuumLimit() will erroneously decide to force emergency autovacuuming immediately. We should probably fix find_multixact_start() to consider the data cached in memory as well as on the on-disk state, but that's no excuse for SetOffsetVacuumLimit() to be stupid about the case where it can no longer read the value after having previously succeeded in doing so. Report by Andres Freund.
-rw-r--r--src/backend/access/transam/multixact.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index b3e60cb1dd2..19b2a734468 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -2681,6 +2681,18 @@ SetOffsetVacuumLimit(bool finish_setup)
}
/*
+ * If we failed to get the oldest offset this time, but we have a value
+ * from a previous pass through this function, assess the need for
+ * autovacuum based on that old value rather than automatically forcing
+ * it.
+ */
+ if (prevOldestOffsetKnown && !oldestOffsetKnown)
+ {
+ oldestOffset = prevOldestOffset;
+ oldestOffsetKnown = true;
+ }
+
+ /*
* Do we need an emergency autovacuum? If we're not sure, assume yes.
*/
return !oldestOffsetKnown ||