@@ -52,12 +52,25 @@ namespace SnapshotWindowUtil {
52
52
// Adds concurrency control to increaseTargetSnapshotWindowSize() and
53
53
// decreaseTargetSnapshotWindowSize(). They should not run concurrently with themselves or one
54
54
// another, since they act on and modify the same storage parameters. Further guards the static
55
- // variable "_snapshotWindowLastIncreasedAt" used in increaseTargetSnapshotWindowSize().
55
+ // variables "_snapshotWindowLastDecreasedAt" and "_snapshotWindowLastIncreasedAt" used in
56
+ // increaseTargetSnapshotWindowSize() and decreaseSnapshowWindow().
56
57
stdx::mutex snapshotWindowMutex;
57
58
58
59
namespace {
59
60
60
- void _decreaseTargetSnapshotWindowSize (WithLock, OperationContext* opCtx) {
61
+ void _decreaseTargetSnapshotWindowSize (WithLock lock, OperationContext* opCtx) {
62
+ // Tracks the last time that the snapshot window was decreased so that it does not go down so
63
+ // fast that the system does not have time to react and reduce snapshot availability.
64
+ static Date_t _snapshotWindowLastDecreasedAt{Date_t::min ()};
65
+
66
+ if (_snapshotWindowLastDecreasedAt >
67
+ (Date_t::now () -
68
+ Milliseconds (snapshotWindowParams.minMillisBetweenSnapshotWindowDec .load ()))) {
69
+ // We have already decreased the window size in the last minMillisBetweenSnapshotWindowDec
70
+ // milliseconds.
71
+ return ;
72
+ }
73
+
61
74
snapshotWindowParams.targetSnapshotHistoryWindowInSeconds .store (
62
75
snapshotWindowParams.targetSnapshotHistoryWindowInSeconds .load () *
63
76
snapshotWindowParams.snapshotWindowMultiplicativeDecrease .load ());
@@ -67,6 +80,8 @@ void _decreaseTargetSnapshotWindowSize(WithLock, OperationContext* opCtx) {
67
80
StorageEngine* engine = opCtx->getServiceContext ()->getStorageEngine ();
68
81
invariant (engine);
69
82
engine->setOldestTimestampFromStable ();
83
+
84
+ _snapshotWindowLastDecreasedAt = Date_t::now ();
70
85
}
71
86
72
87
} // namespace
@@ -90,6 +105,23 @@ void increaseTargetSnapshotWindowSize(OperationContext* opCtx) {
90
105
return ;
91
106
}
92
107
108
+ // If the cache pressure is already too high, we will not put more pressure on it by increasing
109
+ // the window size.
110
+ StorageEngine* engine = opCtx->getServiceContext ()->getStorageEngine ();
111
+ if (engine && engine->isCacheUnderPressure (opCtx)) {
112
+ warning () << " Attempted to increase the time window of available snapshots for "
113
+ " point-in-time operations (readConcern level 'snapshot' or transactions), but "
114
+ " the storage engine cache pressure, per the cachePressureThreshold setting of "
115
+ " '"
116
+ << snapshotWindowParams.cachePressureThreshold .load ()
117
+ << " ', is too high to allow it to increase. If this happens frequently, consider "
118
+ " either increasing the cache pressure threshold or increasing the memory "
119
+ " available to the storage engine cache, in order to improve the success rate "
120
+ " or speed of point-in-time requests." ;
121
+ _decreaseTargetSnapshotWindowSize (lock, opCtx);
122
+ return ;
123
+ }
124
+
93
125
if (snapshotWindowParams.targetSnapshotHistoryWindowInSeconds .load () ==
94
126
snapshotWindowParams.maxTargetSnapshotHistoryWindowInSeconds .load ()) {
95
127
warning () << " Attempted to increase the time window of available snapshots for "
@@ -119,28 +151,10 @@ void decreaseTargetSnapshotWindowSize(OperationContext* opCtx) {
119
151
stdx::unique_lock<stdx::mutex> lock (snapshotWindowMutex);
120
152
121
153
StorageEngine* engine = opCtx->getServiceContext ()->getStorageEngine ();
122
- if (engine) {
123
- static auto lastInsertsCount = 0 ;
124
- static auto lastSnapshotErrorCount = 0 ;
125
-
126
- auto currentInsertsCount = engine->getCacheOverflowTableInsertCount (opCtx);
127
- auto currentSnapshotErrorCount = snapshotWindowParams.snapshotTooOldErrorCount .load ();
128
-
129
- // Only decrease the snapshot window size if there were writes to the cache overflow table
130
- // and there has been no new SnapshotTooOld errors in the same time period.
131
- if (currentInsertsCount > lastInsertsCount &&
132
- currentSnapshotErrorCount == lastSnapshotErrorCount) {
133
- _decreaseTargetSnapshotWindowSize (lock, opCtx);
134
- }
135
-
136
- lastInsertsCount = currentInsertsCount;
137
- lastSnapshotErrorCount = currentSnapshotErrorCount;
154
+ if (engine && engine->isCacheUnderPressure (opCtx)) {
155
+ _decreaseTargetSnapshotWindowSize (lock, opCtx);
138
156
}
139
157
}
140
158
141
- void incrementSnapshotTooOldErrorCount () {
142
- snapshotWindowParams.snapshotTooOldErrorCount .addAndFetch (1 );
143
- }
144
-
145
159
} // namespace SnapshotWindowUtil
146
160
} // namespace mongo
0 commit comments