summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/collection_scan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/exec/collection_scan.cpp')
-rw-r--r--src/mongo/db/exec/collection_scan.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/mongo/db/exec/collection_scan.cpp b/src/mongo/db/exec/collection_scan.cpp
index f8550dbe81d..877603a0965 100644
--- a/src/mongo/db/exec/collection_scan.cpp
+++ b/src/mongo/db/exec/collection_scan.cpp
@@ -275,19 +275,36 @@ void CollectionScan::setLatestOplogEntryTimestamp(const Record& record) {
}
void CollectionScan::assertTsHasNotFallenOffOplog(const Record& record) {
- // If the first entry we see in the oplog is the replset initialization, then it doesn't matter
- // if its timestamp is later than the timestamp that should not have fallen off the oplog; no
- // events earlier can have fallen off this oplog. Otherwise, verify that the timestamp of the
- // first observed oplog entry is earlier than or equal to timestamp that should not have fallen
- // off the oplog.
- auto oplogEntry = uassertStatusOK(repl::OplogEntry::parse(record.data.toBson()));
+ const auto oplogEntry = record.data.toBson();
+ const repl::OplogEntryParserNonStrict oplogEntryParser{oplogEntry};
invariant(_specificStats.docsTested == 0);
- const bool isNewRS =
- oplogEntry.getObject().binaryEqual(BSON("msg" << repl::kInitiatingSetMsg)) &&
- oplogEntry.getOpType() == repl::OpTypeEnum::kNoop;
+
+ // Indicates that 'oplogEntry' means initialization of a replica set.
+ bool isNewRS{false};
+
+ // Indicates that the timestamp of the observed oplog entry 'oplogEntry' is earlier than or
+ // equal to timestamp that should not have fallen off the oplog.
+ bool tsHasNotFallenOff{false};
+ try {
+ tsHasNotFallenOff =
+ oplogEntryParser.getOpTime().getTimestamp() <= *_params.assertTsHasNotFallenOffOplog;
+
+ // If the first entry we see in the oplog is the replset initialization, then it doesn't
+ // matter if its timestamp is later than the timestamp that should not have fallen off the
+ // oplog; no events earlier can have fallen off this oplog.
+ // NOTE: A change collection can be created at any moment as such it might not have replset
+ // initialization message, as such this case is not fully applicable for the change
+ // collection.
+ isNewRS = oplogEntryParser.getOpType() == repl::OpTypeEnum::kNoop &&
+ oplogEntryParser.getObject().binaryEqual(BSON("msg" << repl::kInitiatingSetMsg));
+ } catch (const AssertionException& exception) {
+ uasserted(8881102,
+ str::stream() << "Failed to parse the oldest oplog entry" << causedBy(exception));
+ }
uassert(ErrorCodes::OplogQueryMinTsMissing,
"Specified timestamp has already fallen off the oplog",
- isNewRS || oplogEntry.getTimestamp() <= *_params.assertTsHasNotFallenOffOplog);
+ isNewRS || tsHasNotFallenOff);
+
// We don't need to check this assertion again after we've confirmed the first oplog event.
_params.assertTsHasNotFallenOffOplog = boost::none;
}
@@ -431,9 +448,7 @@ void CollectionScan::doReattachToOperationContext() {
unique_ptr<PlanStageStats> CollectionScan::getStats() {
// Add a BSON representation of the filter to the stats tree, if there is one.
if (nullptr != _filter) {
- BSONObjBuilder bob;
- _filter->serialize(&bob);
- _commonStats.filter = bob.obj();
+ _commonStats.filter = _filter->serialize();
}
unique_ptr<PlanStageStats> ret = std::make_unique<PlanStageStats>(_commonStats, STAGE_COLLSCAN);