Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7c3e803

Browse files
committed
Add a few entries to the tail of time mapping, to see old values.
Without a few entries beyond old_snapshot_threshold, the lookupwould often fail, resulting in the more aggressive pruning orvacuum being skipped often enough to matter. This was very clearlyshown by a python test script posted by Ants Aasma, and was likelya factor in an earlier but somewhat less clear-cut test case postedby Jeff Janes.This patch makes no change to the logic, per se -- it just makesthe array of mapping entries big enough to make lookup misses basedon timing much less likely. An occasional miss is still possibleif a thread stalls for more than 10 minutes, but that does notcreate any problem with correctness of behavior. Besides, ifthings are so busy that a thread is stalling for more than 10minutes, it is probably OK to skip the more aggressive cleanup atthat particular point in time.
1 parentd34e7b2 commit7c3e803

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

‎src/backend/utils/time/snapmgr.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ typedef struct OldSnapshotControlData
9292
* Use a circular buffer with a head offset, a count of entries currently
9393
* used, and a timestamp corresponding to the xid at the head offset. A
9494
* count_used value of zero means that there are no times stored; a
95-
* count_used value ofold_snapshot_threshold means that the buffer is
96-
* full and the head must be advanced to add new entries. Use timestamps
97-
* aligned to minute boundaries, since that seems less surprising than
98-
* aligning based on the first usage timestamp.
95+
* count_used value ofOLD_SNAPSHOT_TIME_MAP_ENTRIES means that the buffer
96+
*isfull and the head must be advanced to add new entries. Use
97+
*timestampsaligned to minute boundaries, since that seems less
98+
*surprising thanaligning based on the first usage timestamp.
9999
*
100100
* It is OK if the xid for a given time slot is from earlier than
101101
* calculated by adding the number of minutes corresponding to the
@@ -243,7 +243,7 @@ SnapMgrShmemSize(void)
243243
size= offsetof(OldSnapshotControlData,xid_by_minute);
244244
if (old_snapshot_threshold>0)
245245
size=add_size(size,mul_size(sizeof(TransactionId),
246-
old_snapshot_threshold));
246+
OLD_SNAPSHOT_TIME_MAP_ENTRIES));
247247

248248
returnsize;
249249
}
@@ -1643,7 +1643,7 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin,
16431643
if (offset>oldSnapshotControl->count_used-1)
16441644
offset=oldSnapshotControl->count_used-1;
16451645
offset= (oldSnapshotControl->head_offset+offset)
1646-
%old_snapshot_threshold;
1646+
%OLD_SNAPSHOT_TIME_MAP_ENTRIES;
16471647
xlimit=oldSnapshotControl->xid_by_minute[offset];
16481648

16491649
if (NormalTransactionIdFollows(xlimit,recentXmin))
@@ -1720,10 +1720,10 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
17201720
LWLockAcquire(OldSnapshotTimeMapLock,LW_EXCLUSIVE);
17211721

17221722
Assert(oldSnapshotControl->head_offset >=0);
1723-
Assert(oldSnapshotControl->head_offset<old_snapshot_threshold);
1723+
Assert(oldSnapshotControl->head_offset<OLD_SNAPSHOT_TIME_MAP_ENTRIES);
17241724
Assert((oldSnapshotControl->head_timestamp %USECS_PER_MINUTE)==0);
17251725
Assert(oldSnapshotControl->count_used >=0);
1726-
Assert(oldSnapshotControl->count_used <=old_snapshot_threshold);
1726+
Assert(oldSnapshotControl->count_used <=OLD_SNAPSHOT_TIME_MAP_ENTRIES);
17271727

17281728
if (oldSnapshotControl->count_used==0)
17291729
{
@@ -1750,7 +1750,7 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
17501750
intbucket= (oldSnapshotControl->head_offset
17511751
+ ((ts-oldSnapshotControl->head_timestamp)
17521752
/USECS_PER_MINUTE))
1753-
%old_snapshot_threshold;
1753+
%OLD_SNAPSHOT_TIME_MAP_ENTRIES;
17541754

17551755
if (TransactionIdPrecedes(oldSnapshotControl->xid_by_minute[bucket],xmin))
17561756
oldSnapshotControl->xid_by_minute[bucket]=xmin;
@@ -1763,7 +1763,7 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
17631763

17641764
oldSnapshotControl->head_timestamp=ts;
17651765

1766-
if (advance >=old_snapshot_threshold)
1766+
if (advance >=OLD_SNAPSHOT_TIME_MAP_ENTRIES)
17671767
{
17681768
/* Advance is so far that all old data is junk; start over. */
17691769
oldSnapshotControl->head_offset=0;
@@ -1777,12 +1777,12 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
17771777

17781778
for (i=0;i<advance;i++)
17791779
{
1780-
if (oldSnapshotControl->count_used==old_snapshot_threshold)
1780+
if (oldSnapshotControl->count_used==OLD_SNAPSHOT_TIME_MAP_ENTRIES)
17811781
{
17821782
/* Map full and new value replaces old head. */
17831783
intold_head=oldSnapshotControl->head_offset;
17841784

1785-
if (old_head== (old_snapshot_threshold-1))
1785+
if (old_head== (OLD_SNAPSHOT_TIME_MAP_ENTRIES-1))
17861786
oldSnapshotControl->head_offset=0;
17871787
else
17881788
oldSnapshotControl->head_offset=old_head+1;
@@ -1793,7 +1793,7 @@ MaintainOldSnapshotTimeMapping(int64 whenTaken, TransactionId xmin)
17931793
/* Extend map to unused entry. */
17941794
intnew_tail= (oldSnapshotControl->head_offset
17951795
+oldSnapshotControl->count_used)
1796-
%old_snapshot_threshold;
1796+
%OLD_SNAPSHOT_TIME_MAP_ENTRIES;
17971797

17981798
oldSnapshotControl->count_used++;
17991799
oldSnapshotControl->xid_by_minute[new_tail]=xmin;

‎src/include/utils/snapmgr.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@
1919
#include"utils/snapshot.h"
2020

2121

22+
/*
23+
* The structure used to map times to TransactionId values for the "snapshot
24+
* too old" feature must have a few entries at the tail to hold old values;
25+
* otherwise the lookup will often fail and the expected early pruning or
26+
* vacuum will not usually occur. It is best if this padding is for a number
27+
* of minutes greater than a thread would normally be stalled, but it's OK if
28+
* early vacuum opportunities are occasionally missed, so there's no need to
29+
* use an extreme value or get too fancy. 10 minutes seems plenty.
30+
*/
31+
#defineOLD_SNAPSHOT_PADDING_ENTRIES 10
32+
#defineOLD_SNAPSHOT_TIME_MAP_ENTRIES (old_snapshot_threshold + OLD_SNAPSHOT_PADDING_ENTRIES)
33+
34+
2235
/* GUC variables */
2336
externPGDLLIMPORTintold_snapshot_threshold;
2437

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp