diff options
author | Eric Milkie <milkie@10gen.com> | 2019-08-19 10:23:17 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2019-09-12 13:32:07 -0400 |
commit | 08e81689618d7bf906377913e4f2958ce216e275 (patch) | |
tree | b7430cad42b07239d3effdc0f0b2305442aaed7c /src/mongo | |
parent | 823cdda984f11c1b4fbdd2ea571c05856a8e16eb (diff) | |
download | mongo-08e81689618d7bf906377913e4f2958ce216e275.tar.gz |
SERVER-42864 change index build initial write timestamp logic
(cherry picked from commit 99593e1255dde3320ac330599311e3481a1ac0e0)
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/catalog/multi_index_block.cpp | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/src/mongo/db/catalog/multi_index_block.cpp b/src/mongo/db/catalog/multi_index_block.cpp index 1e7c8795349..76dad0efcc2 100644 --- a/src/mongo/db/catalog/multi_index_block.cpp +++ b/src/mongo/db/catalog/multi_index_block.cpp @@ -233,17 +233,29 @@ MultiIndexBlock::OnInitFn MultiIndexBlock::kNoopOnInitFn = MultiIndexBlock::OnInitFn MultiIndexBlock::makeTimestampedIndexOnInitFn(OperationContext* opCtx, const Collection* coll) { return [opCtx, ns = coll->ns()](std::vector<BSONObj>& specs) -> Status { - auto replCoord = repl::ReplicationCoordinator::get(opCtx); - if (opCtx->recoveryUnit()->getCommitTimestamp().isNull() && - replCoord->canAcceptWritesForDatabase(opCtx, "admin")) { - // Only primaries must timestamp this write. Secondaries run this from within a - // `TimestampBlock`. Primaries performing an index build via `applyOps` may have a - // wrapping commit timestamp that will be used instead. - opCtx->getServiceContext()->getOpObserver()->onOpMessage( - opCtx, - BSON("msg" << std::string(str::stream() << "Creating indexes. Coll: " << ns))); - } + // This function sets a timestamp for the initial catalog write when beginning an index + // build, if necessary. There are four scenarios: + // 1. A timestamp is already set -- replication application sets a timestamp ahead of time. + // This could include the phase of initial sync where it applies oplog entries. Also, + // primaries performing an index build via `applyOps` may have a wrapping commit timestamp. + if (!opCtx->recoveryUnit()->getCommitTimestamp().isNull()) + return Status::OK(); + + // 2. If the node is initial syncing, we do not set a timestamp. + auto replCoord = repl::ReplicationCoordinator::get(opCtx); + if (replCoord->isReplEnabled() && replCoord->getMemberState().startup2()) + return Status::OK(); + + // 3. If the index build is on the local database, do not timestamp. + if (ns.isLocal()) + return Status::OK(); + + // 4. All other cases, we generate a timestamp by writing a no-op oplog entry. This is + // better than using a ghost timestamp. Writing an oplog entry ensures this node is + // primary. + opCtx->getServiceContext()->getOpObserver()->onOpMessage( + opCtx, BSON("msg" << std::string(str::stream() << "Creating indexes. Coll: " << ns))); return Status::OK(); }; } |