You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[3.1.9 backport] CBG-4016 Refresh sequence allocator before incr during nextSequenceGreaterThan (#6960)
* CBG-4015 Refresh sequence allocator before incr during nextSequenceGreaterThan
When nextSequenceGreaterThan requires a sequence larger than what’s already present in the allocator’s batch size, fetch the current _sync:seq before computing the require increment size, to account for variable allocation rates by other allocators.
* Logging fixes
* Test enhancements from PR review
// nextSequenceGreaterThan increments _sync:seq such that it's greater than existingSequence + s.sequenceBatchSize
186
198
// In the case where our local s.max < _sync:seq (another node has incremented _sync:seq), we may be releasing
187
199
// sequences greater than existingSequence, but we will only ever release sequences allocated by this node's incr operation
@@ -221,19 +233,45 @@ func (s *sequenceAllocator) nextSequenceGreaterThan(ctx context.Context, existin
221
233
222
234
}
223
235
224
-
// If the target sequence is greater than the highest in our batch (s.max), we want to:
225
-
// (a) Reserve n sequences past _sync:seq, where n = existingSequence - s.max. It's ok if the resulting sequence exceeds targetSequence (if other nodes have allocated sequences and
226
-
// updated _sync:seq since we last updated s.max.), then
236
+
// At this point we need to allocate a sequence that's larger than what's in our current batch, so we first need to release the current batch while holding the mutex.
237
+
varnumReleasedBatchuint64
238
+
numReleasedBatch, err=s._releaseCurrentBatch(ctx)
239
+
iferr!=nil {
240
+
base.InfofCtx(ctx, base.KeyCache, "Unable to release current batch during nextSequenceGreaterThan for existing sequence %d. Will be handled by skipped sequence handling. %v", existingSequence, err)
241
+
}
242
+
releasedSequenceCount+=numReleasedBatch
243
+
244
+
syncSeq, err:=s.getSequence()
245
+
iferr!=nil {
246
+
base.WarnfCtx(ctx, "Unable to fetch current sequence during nextSequenceGreaterThan for existing sequence %d. Error:%v", existingSequence, err)
247
+
s.mutex.Unlock()
248
+
return0, 0, err
249
+
}
250
+
251
+
// If the target sequence is less than the current _sync:seq, allocate as normal using _nextSequence
// If the target sequence is greater than the current _sync:seq, we want to:
266
+
// (a) Reserve n sequences past _sync:seq, where n = existingSequence - syncSeq. It's ok if the resulting sequence exceeds targetSequence (if other nodes have allocated sequences and
267
+
// updated _sync:seq since we last updated s.max.)
227
268
// (b) Allocate a standard batch of sequences, and assign a sequence from that batch in the usual way.
228
269
// (c) Release any previously allocated sequences (s.last to s.max)
229
270
// (d) Release the reserved sequences from part (a)
230
271
// We can perform (a) and (b) as a single increment operation, but (c) and (d) aren't necessarily contiguous blocks and must be released
base.WarnfCtx(ctx, "Error returned when releasing sequence range [%d-%d] for previously allocated sequences. Will be handled by skipped sequence handling. Error:%v", prevAllocReleaseFrom, prevAllocReleaseTo, err)
260
-
}
261
-
releasedSequenceCount+=released
262
294
// Release the newly allocated sequences that were used to catch up to existingSequence (d)
// multiNodeUpdate obtains an initial sequence from an import allocator (import node), then performs repeated updates to the doc using random pool of iterators (random SG node).
489
+
// Performs sequenceGreaterThan, then ensures that allocator doesn't release more than the sequence batch size
0 commit comments