summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2019-08-19 10:23:17 -0400
committerEric Milkie <milkie@10gen.com>2019-09-12 13:32:07 -0400
commit08e81689618d7bf906377913e4f2958ce216e275 (patch)
treeb7430cad42b07239d3effdc0f0b2305442aaed7c /src/mongo
parent823cdda984f11c1b4fbdd2ea571c05856a8e16eb (diff)
downloadmongo-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.cpp32
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();
};
}