-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
Storage Execution
-
Fully Compatible
-
ALL
-
Storage Execution 2026-08-03
-
200
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Context
Before truncating anything in _reclaimOplogByTime(), we check that there is a valid truncate point using newestExpiredRecord(). newestExpiredRecord() accepts a mayTruncateUpTo RecordId argument. mayTruncateUpTo is calculated as
min(validAsOf, pinned oplog timestamp)
here.
Bug
If mayTruncateUpTo is null, meaning RecordId(0), we ignore it and truncate all records older than the oplog expiration time:
// it's OK to round off expiry time to the nearest second.
RecordId seekTo(durationCount<Seconds>(expiryTime.toDurationSinceEpoch()), /* low */ 0);
if (!mayTruncateUpTo.isNull() && seekTo > mayTruncateUpTo) {
seekTo = mayTruncateUpTo;
}
record = cursor->seek(seekTo, SeekableRecordCursor::BoundInclusion::kInclude);
mayTruncateUpTo can be null when the pinned oplog timestamp has not been advanced or, after SERVER-131744, the validAsOf timestamp has not been persisted yet.
The result is we can truncate oplog before it has been persisted, which has caused AF-18740 and BF-44537.
Solution
Disallow any truncation in newestExpiredRecord() when mayTruncateUpTo is RecordId(0). This is the current behavior for size-based truncation.
- is depended on by
-
SERVER-131842 Assert _lastBufferedRid exists unconditionally
-
- Closed
-
- is related to
-
SERVER-131744 Impose correct timestamp guard for oplog truncation with an empty timestamp store
-
- Closed
-
- related to
-
SERVER-131842 Assert _lastBufferedRid exists unconditionally
-
- Closed
-