aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorKevin Grittner <kgrittn@postgresql.org>2016-04-29 16:46:08 -0500
committerKevin Grittner <kgrittn@postgresql.org>2016-04-29 16:46:08 -0500
commit7c3e8039f450eb99b3a73272d0a1661195747d1b (patch)
tree584cbac86a2eddbcf78d5c2617cc6179d44d3290 /src/backend
parentd34e7b2812467279b95060a4db8d9f4fc4be0e40 (diff)
downloadpostgresql-7c3e8039f450eb99b3a73272d0a1661195747d1b.tar.gz
postgresql-7c3e8039f450eb99b3a73272d0a1661195747d1b.zip
Add a few entries to the tail of time mapping, to see old values.
Without a few entries beyond old_snapshot_threshold, the lookup would often fail, resulting in the more aggressive pruning or vacuum being skipped often enough to matter. This was very clearly shown by a python test script posted by Ants Aasma, and was likely a factor in an earlier but somewhat less clear-cut test case posted by Jeff Janes. This patch makes no change to the logic, per se -- it just makes the array of mapping entries big enough to make lookup misses based on timing much less likely. An occasional miss is still possible if a thread stalls for more than 10 minutes, but that does not create any problem with correctness of behavior. Besides, if things are so busy that a thread is stalling for more than 10 minutes, it is probably OK to skip the more aggressive cleanup at that particular point in time.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/time/snapmgr.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 35f338133aa..0a9a231f597 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -92,10 +92,10 @@ typedef struct OldSnapshotControlData
* Use a circular buffer with a head offset, a count of entries currently
* used, and a timestamp corresponding to the xid at the head offset. A
* count_used value of zero means that there are no times stored; a
- * count_used value of old_snapshot_threshold means that the buffer is
- * full and the head must be advanced to add new entries. Use timestamps
- * aligned to minute boundaries, since that seems less surprising than
- * aligning based on the first usage timestamp.
+ * count_used value of OLD_SNAPSHOT_TIME_MAP_ENTRIES means that the buffer
+ * is full and the head must be advanced to add new entries. Use
+ * timestamps aligned to minute boundaries, since that seems less
+ * surprising than aligning based on the first usage timestamp.
*
* It is OK if the xid for a given time slot is from earlier than
* calculated by adding the number of minutes corresponding to the
@@ -243,7 +243,7 @@ SnapMgrShmemSize(void)
size = offsetof(OldSnapshotControlData, xid_by_minute);
if (old_snapshot_threshold > 0)
size = add_size(size, mul_size(sizeof(TransactionId),
- old_snapshot_threshold));
+ OLD_SNAPSHOT_TIME_MAP_ENTRIES));
return size;
}
@@ -1643,7 +1643,7 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin,
if (offset > oldSnapshotControl->count_used - 1)
offset = oldSnapshotControl->count_used - 1;
offset = (oldSnapshotControl->head_offset + offset)
- % old_snapshot_threshold;
+ % OLD_SNAPSHOT_TIME_MAP_ENTRIES;
xlimit = oldSnapshotControl->xid_by_minute[offset];
if (NormalTransactionIdFollows(xlimit, recentXmin))
@@ -1720,10 +1720,10 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
LWLockAcquire(OldSnapshotTimeMapLock, LW_EXCLUSIVE);
Assert(oldSnapshotControl->head_offset >= 0);
- Assert(oldSnapshotControl->head_offset < old_snapshot_threshold);
+ Assert(oldSnapshotControl->head_offset < OLD_SNAPSHOT_TIME_MAP_ENTRIES);
Assert((oldSnapshotControl->head_timestamp % USECS_PER_MINUTE) == 0);
Assert(oldSnapshotControl->count_used >= 0);
- Assert(oldSnapshotControl->count_used <= old_snapshot_threshold);
+ Assert(oldSnapshotControl->count_used <= OLD_SNAPSHOT_TIME_MAP_ENTRIES);
if (oldSnapshotControl->count_used == 0)
{
@@ -1750,7 +1750,7 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
int bucket = (oldSnapshotControl->head_offset
+ ((ts - oldSnapshotControl->head_timestamp)
/ USECS_PER_MINUTE))
- % old_snapshot_threshold;
+ % OLD_SNAPSHOT_TIME_MAP_ENTRIES;
if (TransactionIdPrecedes(oldSnapshotControl->xid_by_minute[bucket], xmin))
oldSnapshotControl->xid_by_minute[bucket] = xmin;
@@ -1763,7 +1763,7 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
oldSnapshotControl->head_timestamp = ts;
- if (advance >= old_snapshot_threshold)
+ if (advance >= OLD_SNAPSHOT_TIME_MAP_ENTRIES)
{
/* Advance is so far that all old data is junk; start over. */
oldSnapshotControl->head_offset = 0;
@@ -1777,12 +1777,12 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
for (i = 0; i < advance; i++)
{
- if (oldSnapshotControl->count_used == old_snapshot_threshold)
+ if (oldSnapshotControl->count_used == OLD_SNAPSHOT_TIME_MAP_ENTRIES)
{
/* Map full and new value replaces old head. */
int old_head = oldSnapshotControl->head_offset;
- if (old_head == (old_snapshot_threshold - 1))
+ if (old_head == (OLD_SNAPSHOT_TIME_MAP_ENTRIES - 1))
oldSnapshotControl->head_offset = 0;
else
oldSnapshotControl->head_offset = old_head + 1;
@@ -1793,7 +1793,7 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
/* Extend map to unused entry. */
int new_tail = (oldSnapshotControl->head_offset
+ oldSnapshotControl->count_used)
- % old_snapshot_threshold;
+ % OLD_SNAPSHOT_TIME_MAP_ENTRIES;
oldSnapshotControl->count_used++;
oldSnapshotControl->xid_by_minute[new_tail] = xmin;