summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas2015-05-11 01:34:26 +0000
committerRobert Haas2015-05-11 01:34:26 +0000
commit312747c224be4c0a880b5172a010e980f8b654ca (patch)
tree33cb5acbab8934d2b79524cd744e1a9b5b2bb3dc /src
parent1a8a4e5cde2b7755e11bde2ea7897bd650622d3e (diff)
Fix DetermineSafeOldestOffset for the case where there are no mxacts.
Commit b69bf30b9bfacafc733a9ba77c9587cf54d06c0c failed to take into account the possibility that there might be no multixacts in existence at all. Report by Thomas Munro; patch by me.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/multixact.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 68b0e101473..5e0bda7e700 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -2492,13 +2492,24 @@ DetermineSafeOldestOffset(MultiXactId oldestMXact)
return;
/*
- * We determine the safe upper bound for offsets of new xacts by reading
- * the offset of the oldest multixact, and going back one segment. This
- * way, the sequence of multixact member segments will always have a
- * one-segment hole at a minimum. We start spewing warnings a few
- * complete segments before that.
+ * Determine the offset of the oldest multixact. Normally, we can read
+ * the offset from the multixact itself, but there's an important special
+ * case: if there are no multixacts in existence at all, oldestMXact
+ * obviously can't point to one. It will instead point to the multixact
+ * ID that will be assigned the next time one is needed.
*/
- oldestOffset = find_multixact_start(oldestMXact);
+ LWLockAcquire(MultiXactGenLock, LW_SHARED);
+ if (MultiXactState->nextMXact == oldestMXact)
+ {
+ oldestOffset = MultiXactState->nextOffset;
+ LWLockRelease(MultiXactGenLock);
+ }
+ else
+ {
+ LWLockRelease(MultiXactGenLock);
+ oldestOffset = find_multixact_start(oldestMXact);
+ }
+
/* move back to start of the corresponding segment */
oldestOffset -= oldestOffset %
(MULTIXACT_MEMBERS_PER_PAGE * SLRU_PAGES_PER_SEGMENT);