summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_check_resume_token.cpp
diff options
context:
space:
mode:
authorBernard Gorman <bernard.gorman@gmail.com>2019-07-15 11:15:19 +0100
committerBernard Gorman <bernard.gorman@gmail.com>2019-07-18 22:29:23 +0100
commitffdb59938db0dfc8ec48e8b74df7a54d07b3a128 (patch)
treece0bdfccfb33a8be7aa1a888d9c8199a8dbb6947 /src/mongo/db/pipeline/document_source_check_resume_token.cpp
parent51a218fb13e02e59afe203c5efd665c9399bfde2 (diff)
downloadmongo-ffdb59938db0dfc8ec48e8b74df7a54d07b3a128.tar.gz
SERVER-42232 Adding a new shard renders all preceding resume tokens invalid
Diffstat (limited to 'src/mongo/db/pipeline/document_source_check_resume_token.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_check_resume_token.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/mongo/db/pipeline/document_source_check_resume_token.cpp b/src/mongo/db/pipeline/document_source_check_resume_token.cpp
index 719be15ea2b..5b9eeabaf6c 100644
--- a/src/mongo/db/pipeline/document_source_check_resume_token.cpp
+++ b/src/mongo/db/pipeline/document_source_check_resume_token.cpp
@@ -331,10 +331,17 @@ void DocumentSourceShardCheckResumability::_assertOplogHasEnoughHistory(
auto pipeline = pExpCtx->mongoProcessInterface->makePipeline({matchSpec}, firstEntryExpCtx);
if (auto first = pipeline->getNext()) {
auto firstOplogEntry = Value(*first);
+ // If the first entry in the oplog is the replset initialization, then it doesn't matter
+ // if its timestamp is later than the resume token. No events earlier than the token can
+ // have fallen off this oplog, and it is therefore safe to resume. Otherwise, verify that
+ // the timestamp of the first oplog entry is earlier than that of the resume token.
+ const bool isNewRS =
+ Value::compare(firstOplogEntry["o"]["msg"], Value("initiating set"_sd), nullptr) == 0 &&
+ Value::compare(firstOplogEntry["op"], Value("n"_sd), nullptr) == 0;
uassert(40576,
- "Resume of change stream was not possible, as the resume point may no longer "
- "be in the oplog. ",
- firstOplogEntry["ts"].getTimestamp() < _tokenFromClient.clusterTime);
+ "Resume of change stream was not possible, as the resume point may no longer be in "
+ "the oplog. ",
+ isNewRS || firstOplogEntry["ts"].getTimestamp() < _tokenFromClient.clusterTime);
} else {
// Very unusual case: the oplog is empty. We can always resume. However, it should never be
// possible to have obtained a document that matched the filter if the oplog is empty.