v6-0003-Fix-bugs-in-MaintainOldSnapshotTimeMapping.patch
text/x-patch
Filename: v6-0003-Fix-bugs-in-MaintainOldSnapshotTimeMapping.patch
Type: text/x-patch
Part: 2
Patch
Format: format-patch
Series: patch v6-0003
Subject: Fix bugs in MaintainOldSnapshotTimeMapping.
| File | + | − |
|---|---|---|
| src/backend/utils/time/snapmgr.c | 27 | 3 |
From 62357a4cccfa0dbc7be7ae9e8f505e4c432f89f8 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Thu, 16 Apr 2020 12:15:57 -0400
Subject: [PATCH v6 3/6] Fix bugs in MaintainOldSnapshotTimeMapping.
---
src/backend/utils/time/snapmgr.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 9dc19b2f58..b41eadf905 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -1944,10 +1944,32 @@ MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, TransactionId xmin)
else
{
/* We need a new bucket, but it might not be the very next one. */
- int advance = ((ts - oldSnapshotControl->head_timestamp)
- / USECS_PER_MINUTE);
+ int distance_to_new_tail;
+ int distance_to_current_tail;
+ int advance;
- oldSnapshotControl->head_timestamp = ts;
+ /*
+ * Our goal is for the new "tail" of the mapping, that is, the entry
+ * which is newest and thus furthest from the "head" entry, to
+ * correspond to "ts". Since there's one entry per minute, the
+ * distance between the current head and the new tail is just the
+ * number of minutes of difference between ts and the current
+ * head_timestamp.
+ *
+ * The distance from the current head to the current tail is one
+ * less than the number of entries in the mapping, because the
+ * entry at the head_offset is for 0 minutes after head_timestamp.
+ *
+ * The difference between these two values is the number of minutes
+ * by which we need to advance the mapping, either adding new entries
+ * or rotating old ones out.
+ */
+ distance_to_new_tail =
+ (ts - oldSnapshotControl->head_timestamp) / USECS_PER_MINUTE;
+ distance_to_current_tail =
+ oldSnapshotControl->count_used - 1;
+ advance = distance_to_new_tail - distance_to_current_tail;
+ Assert(advance > 0);
if (advance >= OLD_SNAPSHOT_TIME_MAP_ENTRIES)
{
@@ -1955,6 +1977,7 @@ MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, TransactionId xmin)
oldSnapshotControl->head_offset = 0;
oldSnapshotControl->count_used = 1;
oldSnapshotControl->xid_by_minute[0] = xmin;
+ oldSnapshotControl->head_timestamp = ts;
}
else
{
@@ -1973,6 +1996,7 @@ MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, TransactionId xmin)
else
oldSnapshotControl->head_offset = old_head + 1;
oldSnapshotControl->xid_by_minute[old_head] = xmin;
+ oldSnapshotControl->head_timestamp += USECS_PER_MINUTE;
}
else
{
--
2.20.1