From 0f2da7fb758f12bd64c6c7891d455a53e1ab1d89 Mon Sep 17 00:00:00 2001 From: Gregory Wlodarek Date: Thu, 14 Feb 2019 16:15:50 -0500 Subject: SERVER-37954 Thread commitQuorum through the createIndexes command into the Coordinator --- src/mongo/db/SConscript | 4 +- src/mongo/db/commands/SConscript | 2 +- src/mongo/db/commands/create_indexes.cpp | 39 ++++++++++++++-- src/mongo/db/index_builds_coordinator.cpp | 23 +++++---- src/mongo/db/index_builds_coordinator.h | 13 +++++- src/mongo/db/index_builds_coordinator_mongod.cpp | 7 +-- src/mongo/db/index_builds_coordinator_mongod.h | 3 +- .../db/index_builds_coordinator_mongod_test.cpp | 54 +++++++++++++++------- src/mongo/db/repl/oplog.cpp | 7 ++- src/mongo/db/repl/repl_set_config.cpp | 6 +++ src/mongo/db/repl/repl_set_config.h | 5 ++ src/mongo/db/repl_index_build_state.h | 14 +++--- src/mongo/db/system_index.cpp | 11 ++++- .../embedded/index_builds_coordinator_embedded.cpp | 7 +-- .../embedded/index_builds_coordinator_embedded.h | 3 +- 15 files changed, 146 insertions(+), 52 deletions(-) diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index f7377ba6e14..fa3b8ac8358 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -943,7 +943,6 @@ env.Library( ], LIBDEPS_PRIVATE=[ 'curop', - "$BUILD_DIR/mongo/db/catalog/commit_quorum_options", '$BUILD_DIR/mongo/db/catalog/uuid_catalog', ], ) @@ -958,6 +957,7 @@ env.Library( LIBDEPS=[ "$BUILD_DIR/mongo/base", '$BUILD_DIR/mongo/db/catalog_raii', + "$BUILD_DIR/mongo/db/catalog/commit_quorum_options", "$BUILD_DIR/mongo/db/catalog/index_builds_manager", ], LIBDEPS_PRIVATE=[ @@ -976,8 +976,8 @@ env.CppUnitTest( "index_builds_coordinator_mongod_test.cpp", ], LIBDEPS=[ - "$BUILD_DIR/mongo/db/catalog/catalog_test_fixture", "index_builds_coordinator_mongod", + "$BUILD_DIR/mongo/db/catalog/catalog_test_fixture", ] ) diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index b31517bfbc9..9ecd99bafd9 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -269,6 +269,7 @@ env.Library( '$BUILD_DIR/mongo/db/ops/write_ops_exec', '$BUILD_DIR/mongo/db/pipeline/mongo_process_interface', '$BUILD_DIR/mongo/db/query_exec', + '$BUILD_DIR/mongo/db/repl/replica_set_messages', '$BUILD_DIR/mongo/db/rw_concern_d', '$BUILD_DIR/mongo/db/stats/counters', '$BUILD_DIR/mongo/db/stats/server_read_concern_write_concern_metrics', @@ -357,7 +358,6 @@ env.Library( '$BUILD_DIR/mongo/db/background', '$BUILD_DIR/mongo/db/catalog/catalog_control', '$BUILD_DIR/mongo/db/catalog/catalog_helpers', - '$BUILD_DIR/mongo/db/catalog/commit_quorum_options', '$BUILD_DIR/mongo/db/catalog/index_key_validate', '$BUILD_DIR/mongo/db/cloner', '$BUILD_DIR/mongo/db/commands', diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index fd5a0e9f30a..775f4eec0c2 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -51,6 +51,7 @@ #include "mongo/db/index_builds_coordinator.h" #include "mongo/db/op_observer.h" #include "mongo/db/ops/insert.h" +#include "mongo/db/repl/repl_set_config.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/s/collection_metadata.h" #include "mongo/db/s/collection_sharding_state.h" @@ -68,6 +69,7 @@ namespace { constexpr auto kIndexesFieldName = "indexes"_sd; constexpr auto kCommandName = "createIndexes"_sd; +constexpr auto kCommitQuorumFieldName = "commitQuorum"_sd; constexpr auto kTwoPhaseCommandName = "twoPhaseCreateIndexes"_sd; constexpr auto kCreateCollectionAutomaticallyFieldName = "createdCollectionAutomatically"_sd; constexpr auto kNumIndexesBeforeFieldName = "numIndexesBefore"_sd; @@ -135,7 +137,8 @@ StatusWith> parseAndValidateIndexSpecs( } hasIndexesField = true; - } else if (kCommandName == cmdElemFieldName || kTwoPhaseCommandName == cmdElemFieldName || + } else if (kCommandName == cmdElemFieldName || kCommitQuorumFieldName == cmdElemFieldName || + kTwoPhaseCommandName == cmdElemFieldName || isGenericArgument(cmdElemFieldName)) { continue; } else { @@ -160,6 +163,25 @@ StatusWith> parseAndValidateIndexSpecs( return indexSpecs; } +/** + * Retrieves the commit quorum from 'cmdObj' if it is present. If it isn't, we provide a default + * commit quorum, which consists of all the data-bearing nodes. + */ +boost::optional parseAndGetCommitQuorum(OperationContext* opCtx, + const BSONObj& cmdObj) { + if (cmdObj.hasField(kCommitQuorumFieldName)) { + CommitQuorumOptions commitQuorum; + uassertStatusOK(commitQuorum.parse(cmdObj.getField(kCommitQuorumFieldName))); + return commitQuorum; + } else { + // Retrieve the default commit quorum if one wasn't passed in, which consists of all + // data-bearing nodes. + auto replCoord = repl::ReplicationCoordinator::get(opCtx); + int numDataBearingMembers = replCoord->getConfig().getNumDataBearingMembers(); + return CommitQuorumOptions(numDataBearingMembers); + } +} + /** * Returns a vector of index specs with the filled in collection default options and removes any * indexes that already exist on the collection. If the returned vector is empty after returning, no @@ -450,6 +472,7 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx, auto specs = uassertStatusOK( parseAndValidateIndexSpecs(opCtx, ns, cmdObj, serverGlobalParams.featureCompatibility)); + boost::optional commitQuorum = parseAndGetCommitQuorum(opCtx, cmdObj); // Preliminary checks before handing control over to IndexBuildsCoordinator: // 1) We are in a replication mode that allows for index creation. @@ -548,9 +571,11 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx, (runTwoPhaseBuild) ? IndexBuildProtocol::kTwoPhase : IndexBuildProtocol::kSinglePhase; log() << "Registering index build: " << buildUUID; ReplIndexBuildState::IndexCatalogStats stats; + IndexBuildsCoordinator::IndexBuildOptions indexBuildOptions = {commitQuorum}; + try { - auto buildIndexFuture = uassertStatusOK( - indexBuildsCoord->startIndexBuild(opCtx, *collectionUUID, specs, buildUUID, protocol)); + auto buildIndexFuture = uassertStatusOK(indexBuildsCoord->startIndexBuild( + opCtx, *collectionUUID, specs, buildUUID, protocol, indexBuildOptions)); auto deadline = opCtx->getDeadline(); // Date_t::max() means no deadline. @@ -613,7 +638,9 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx, } /** - * { createIndexes : "bar", indexes : [ { ns : "test.bar", key : { x : 1 }, name: "x_1" } ] } + * { createIndexes : "bar", + * indexes : [ { ns : "test.bar", key : { x : 1 }, name: "x_1" } ], + * commitQuorum: "majority" } */ class CmdCreateIndex : public ErrmsgCommandDeprecated { public: @@ -658,7 +685,9 @@ public: * Builds project would have to be turned on all at once because so much testing already exists that * would break with incremental changes. * - * {twoPhaseCreateIndexes : "bar", indexes : [ { ns : "test.bar", key : { x : 1 }, name: "x_1" } ]} + * {twoPhaseCreateIndexes : "bar", + * indexes : [ { ns : "test.bar", key : { x : 1 }, name: "x_1" } ], + * commitQuorum: "majority" } */ class CmdTwoPhaseCreateIndex : public ErrmsgCommandDeprecated { public: diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index 0efc21bbbbe..b37c8fd2e5d 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -218,8 +218,13 @@ StatusWith> IndexBuildsCoordinator::startIndexRe // We run the index build using the single phase protocol as we already hold the global // write lock. - auto replIndexBuildState = std::make_shared( - buildUUID, collectionUUID, dbName, specs, IndexBuildProtocol::kSinglePhase); + auto replIndexBuildState = + std::make_shared(buildUUID, + collectionUUID, + dbName, + specs, + IndexBuildProtocol::kSinglePhase, + /*commitQuorum=*/boost::none); Status status = [&]() { stdx::unique_lock lk(_mutex); @@ -495,11 +500,13 @@ void IndexBuildsCoordinator::_unregisterIndexBuild( } StatusWith>> -IndexBuildsCoordinator::_registerAndSetUpIndexBuild(OperationContext* opCtx, - CollectionUUID collectionUUID, - const std::vector& specs, - const UUID& buildUUID, - IndexBuildProtocol protocol) { +IndexBuildsCoordinator::_registerAndSetUpIndexBuild( + OperationContext* opCtx, + CollectionUUID collectionUUID, + const std::vector& specs, + const UUID& buildUUID, + IndexBuildProtocol protocol, + boost::optional commitQuorum) { auto nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(collectionUUID); if (nss.isEmpty()) { return Status(ErrorCodes::NamespaceNotFound, @@ -546,7 +553,7 @@ IndexBuildsCoordinator::_registerAndSetUpIndexBuild(OperationContext* opCtx, } auto replIndexBuildState = std::make_shared( - buildUUID, collectionUUID, dbName, filteredSpecs, protocol); + buildUUID, collectionUUID, dbName, filteredSpecs, protocol, commitQuorum); replIndexBuildState->stats.numIndexesBefore = _getNumIndexesTotal(opCtx, collection); Status status = _registerIndexBuild(lk, replIndexBuildState); diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h index 7aa563790c9..cb7117376e0 100644 --- a/src/mongo/db/index_builds_coordinator.h +++ b/src/mongo/db/index_builds_coordinator.h @@ -67,6 +67,13 @@ class ServiceContext; */ class IndexBuildsCoordinator { public: + /** + * Contains additional information required by 'startIndexBuild()'. + */ + struct IndexBuildOptions { + boost::optional commitQuorum; + }; + /** * Invariants that there are no index builds in-progress. */ @@ -104,7 +111,8 @@ public: CollectionUUID collectionUUID, const std::vector& specs, const UUID& buildUUID, - IndexBuildProtocol protocol) = 0; + IndexBuildProtocol protocol, + IndexBuildOptions indexBuildOptions) = 0; /** * Sets up the in-memory and persisted state of the index build. @@ -345,7 +353,8 @@ protected: CollectionUUID collectionUUID, const std::vector& specs, const UUID& buildUUID, - IndexBuildProtocol protocol); + IndexBuildProtocol protocol, + boost::optional commitQuorum); /** * Runs the index build on the caller thread. Handles unregistering the index build and setting diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp index 2bc4fcd1fc7..de5374e8c98 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod.cpp @@ -85,9 +85,10 @@ IndexBuildsCoordinatorMongod::startIndexBuild(OperationContext* opCtx, CollectionUUID collectionUUID, const std::vector& specs, const UUID& buildUUID, - IndexBuildProtocol protocol) { - auto statusWithOptionalResult = - _registerAndSetUpIndexBuild(opCtx, collectionUUID, specs, buildUUID, protocol); + IndexBuildProtocol protocol, + IndexBuildOptions indexBuildOptions) { + auto statusWithOptionalResult = _registerAndSetUpIndexBuild( + opCtx, collectionUUID, specs, buildUUID, protocol, indexBuildOptions.commitQuorum); if (!statusWithOptionalResult.isOK()) { return statusWithOptionalResult.getStatus(); } diff --git a/src/mongo/db/index_builds_coordinator_mongod.h b/src/mongo/db/index_builds_coordinator_mongod.h index aef08abda8e..a9ee94852db 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.h +++ b/src/mongo/db/index_builds_coordinator_mongod.h @@ -74,7 +74,8 @@ public: CollectionUUID collectionUUID, const std::vector& specs, const UUID& buildUUID, - IndexBuildProtocol protocol) override; + IndexBuildProtocol protocol, + IndexBuildOptions indexBuildOptions) override; /** * TODO: not yet implemented. diff --git a/src/mongo/db/index_builds_coordinator_mongod_test.cpp b/src/mongo/db/index_builds_coordinator_mongod_test.cpp index 05e75c5913e..566219732f7 100644 --- a/src/mongo/db/index_builds_coordinator_mongod_test.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod_test.cpp @@ -33,6 +33,7 @@ #include "mongo/db/catalog/catalog_test_fixture.h" #include "mongo/db/catalog/collection_options.h" +#include "mongo/db/catalog/commit_quorum_options.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" @@ -62,6 +63,8 @@ public: const NamespaceString _testBarNss = NamespaceString("test.bar"); const CollectionUUID _othertestFooUUID = UUID::gen(); const NamespaceString _othertestFooNss = NamespaceString("othertest.foo"); + const IndexBuildsCoordinator::IndexBuildOptions _indexBuildOptions = { + CommitQuorumOptions("majority")}; std::unique_ptr _indexBuildsCoord; }; @@ -108,7 +111,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, AttemptBuildSameIndexReturnsImmediateSu _testFooUUID, makeSpecs(_testFooNss, {"a", "b"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); // Attempt and fail to register an index build on _testFooNss with the same index name, while // the prior build is still running. @@ -116,7 +120,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, AttemptBuildSameIndexReturnsImmediateSu _testFooUUID, makeSpecs(_testFooNss, {"b"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); auto readyStats = assertGet(readyFuture.getNoThrow()); ASSERT_EQ(3, readyStats.numIndexesBefore); @@ -139,7 +144,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, Registration) { _testFooUUID, makeSpecs(_testFooNss, {"a", "b"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); ASSERT_EQ(_indexBuildsCoord->numInProgForDb(_testFooNss.db()), 1); ASSERT(_indexBuildsCoord->inProgForCollection(_testFooUUID)); @@ -157,7 +163,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, Registration) { _testFooUUID, makeSpecs(_testFooNss, {"c", "d"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); ASSERT_EQ(_indexBuildsCoord->numInProgForDb(_testFooNss.db()), 2); ASSERT(_indexBuildsCoord->inProgForCollection(_testFooUUID)); @@ -175,7 +182,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, Registration) { _testBarUUID, makeSpecs(_testBarNss, {"x", "y"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); ASSERT_EQ(_indexBuildsCoord->numInProgForDb(_testBarNss.db()), 3); ASSERT(_indexBuildsCoord->inProgForCollection(_testBarUUID)); @@ -193,7 +201,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, Registration) { _othertestFooUUID, makeSpecs(_othertestFooNss, {"r", "s"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); ASSERT_EQ(_indexBuildsCoord->numInProgForDb(_othertestFooNss.db()), 1); ASSERT(_indexBuildsCoord->inProgForCollection(_othertestFooUUID)); @@ -254,7 +263,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"a", "b"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase) + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions) .getStatus()); // Registering index builds on other collections and databases should still succeed. @@ -263,13 +273,15 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testBarUUID, makeSpecs(_testBarNss, {"c", "d"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); auto othertestFooFuture = assertGet(_indexBuildsCoord->startIndexBuild(operationContext(), _othertestFooUUID, makeSpecs(_othertestFooNss, {"e", "f"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); _indexBuildsCoord->sleepIndexBuilds_forTestOnly(false); @@ -288,7 +300,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"a", "b"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); auto indexCatalogStats = unittest::assertGet(testFooFuture.getNoThrow()); ASSERT_EQ(1, indexCatalogStats.numIndexesBefore); ASSERT_EQ(3, indexCatalogStats.numIndexesAfter); @@ -307,7 +320,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"c", "d"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase) + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions) .getStatus()); ASSERT_EQ(ErrorCodes::CannotCreateIndex, _indexBuildsCoord @@ -315,7 +329,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testBarUUID, makeSpecs(_testBarNss, {"a", "b"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase) + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions) .getStatus()); // Registering index builds on another database should still succeed. @@ -324,7 +339,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _othertestFooUUID, makeSpecs(_othertestFooNss, {"g", "h"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); _indexBuildsCoord->sleepIndexBuilds_forTestOnly(false); @@ -340,7 +356,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"c", "d"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); auto indexCatalogStats = unittest::assertGet(testFooFuture.getNoThrow()); ASSERT_EQ(3, indexCatalogStats.numIndexesBefore); ASSERT_EQ(5, indexCatalogStats.numIndexesAfter); @@ -359,7 +376,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"e", "f"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase) + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions) .getStatus()); } ASSERT_EQ(ErrorCodes::CannotCreateIndex, @@ -368,7 +386,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"e", "f"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase) + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions) .getStatus()); } @@ -379,7 +398,8 @@ TEST_F(IndexBuildsCoordinatorMongodTest, DisallowNewBuildsOnNamespace) { _testFooUUID, makeSpecs(_testFooNss, {"e", "f"}), UUID::gen(), - IndexBuildProtocol::kTwoPhase)); + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); auto indexCatalogStats = unittest::assertGet(testFooFuture.getNoThrow()); ASSERT_EQ(5, indexCatalogStats.numIndexesBefore); ASSERT_EQ(7, indexCatalogStats.numIndexesAfter); diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 509a47cbc36..60686355eec 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -287,13 +287,18 @@ Status startIndexBuild(OperationContext* opCtx, if (!statusWithIndexes.isOK()) { return statusWithIndexes.getStatus(); } + + IndexBuildsCoordinator::IndexBuildOptions indexBuildOptions = {/*commitQuorum=*/boost::none}; + + // We don't pass in a commit quorum here because secondary nodes don't have any knowledge of it. return IndexBuildsCoordinator::get(opCtx) ->startIndexBuild(opCtx, collUUID, statusWithIndexes.getValue(), indexBuildUUID, /* This oplog entry is only replicated for two-phase index builds */ - IndexBuildProtocol::kTwoPhase) + IndexBuildProtocol::kTwoPhase, + indexBuildOptions) .getStatus(); } diff --git a/src/mongo/db/repl/repl_set_config.cpp b/src/mongo/db/repl/repl_set_config.cpp index 0bada070ca7..2f5b4c5d5b8 100644 --- a/src/mongo/db/repl/repl_set_config.cpp +++ b/src/mongo/db/repl/repl_set_config.cpp @@ -646,6 +646,12 @@ Status ReplSetConfig::checkIfWriteConcernCanBeSatisfied( } } +int ReplSetConfig::getNumDataBearingMembers() const { + int numArbiters = + std::count_if(begin(_members), end(_members), [](const auto& x) { return x.isArbiter(); }); + return _members.size() - numArbiters; +} + const MemberConfig& ReplSetConfig::getMemberAt(size_t i) const { invariant(i < _members.size()); return _members[i]; diff --git a/src/mongo/db/repl/repl_set_config.h b/src/mongo/db/repl/repl_set_config.h index 3f45f0a5721..c3de46ea033 100644 --- a/src/mongo/db/repl/repl_set_config.h +++ b/src/mongo/db/repl/repl_set_config.h @@ -141,6 +141,11 @@ public: return _members.size(); } + /** + * Gets the number of data-bearing members in this configuration. + */ + int getNumDataBearingMembers() const; + /** * Gets a begin iterator over the MemberConfigs stored in this ReplSetConfig. */ diff --git a/src/mongo/db/repl_index_build_state.h b/src/mongo/db/repl_index_build_state.h index cd7af07a2bb..151f6ade81f 100644 --- a/src/mongo/db/repl_index_build_state.h +++ b/src/mongo/db/repl_index_build_state.h @@ -36,9 +36,9 @@ #include "mongo/bson/bsonobj.h" #include "mongo/db/catalog/collection_catalog_entry.h" +#include "mongo/db/catalog/commit_quorum_options.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/namespace_string.h" -#include "mongo/db/write_concern_options.h" #include "mongo/stdx/condition_variable.h" #include "mongo/util/future.h" #include "mongo/util/net/hostandport.h" @@ -76,13 +76,15 @@ struct ReplIndexBuildState { const UUID& collUUID, const std::string& dbName, const std::vector& specs, - IndexBuildProtocol protocol) + IndexBuildProtocol protocol, + boost::optional commitQuorum) : buildUUID(indexBuildUUID), collectionUUID(collUUID), dbName(dbName), indexNames(extractIndexNames(specs)), indexSpecs(specs), - protocol(protocol) {} + protocol(protocol), + commitQuorum(commitQuorum) {} // Uniquely identifies this index build across replica set members. const UUID buildUUID; @@ -109,9 +111,9 @@ struct ReplIndexBuildState { // Protects the state below. mutable stdx::mutex mutex; - // The quorum required of commit ready replica set members before the index build will be - // allowed to commit. - WriteConcernOptions commitQuorum; + // Secondaries do not set this information, so it is only set on primaries or on + // transition to primary. + boost::optional commitQuorum; // Tracks the members of the replica set that have finished building the index(es) and are ready // to commit the index(es). diff --git a/src/mongo/db/system_index.cpp b/src/mongo/db/system_index.cpp index 6f69fa6bd5c..d6f6ebca0d2 100644 --- a/src/mongo/db/system_index.cpp +++ b/src/mongo/db/system_index.cpp @@ -38,6 +38,7 @@ #include "mongo/client/index_spec.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/commit_quorum_options.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/catalog/multi_index_block.h" @@ -122,8 +123,14 @@ SharedSemiFuture generateSystemIndexForE UUID buildUUID = UUID::gen(); IndexBuildsCoordinator* indexBuildsCoord = IndexBuildsCoordinator::get(opCtx); - auto indexBuildFuture = uassertStatusOK(indexBuildsCoord->startIndexBuild( - opCtx, collectionUUID, {indexSpec}, buildUUID, IndexBuildProtocol::kSinglePhase)); + IndexBuildsCoordinator::IndexBuildOptions indexBuildOptions = {CommitQuorumOptions(1)}; + auto indexBuildFuture = + uassertStatusOK(indexBuildsCoord->startIndexBuild(opCtx, + collectionUUID, + {indexSpec}, + buildUUID, + IndexBuildProtocol::kSinglePhase, + indexBuildOptions)); return indexBuildFuture; } catch (const DBException& e) { severe() << "Failed to regenerate index for " << ns << ". Exception: " << e.what(); diff --git a/src/mongo/embedded/index_builds_coordinator_embedded.cpp b/src/mongo/embedded/index_builds_coordinator_embedded.cpp index 831fea1685a..206db80a5bd 100644 --- a/src/mongo/embedded/index_builds_coordinator_embedded.cpp +++ b/src/mongo/embedded/index_builds_coordinator_embedded.cpp @@ -48,11 +48,12 @@ IndexBuildsCoordinatorEmbedded::startIndexBuild(OperationContext* opCtx, CollectionUUID collectionUUID, const std::vector& specs, const UUID& buildUUID, - IndexBuildProtocol protocol) { + IndexBuildProtocol protocol, + IndexBuildOptions indexBuildOptions) { invariant(!opCtx->lockState()->isLocked()); - auto statusWithOptionalResult = - _registerAndSetUpIndexBuild(opCtx, collectionUUID, specs, buildUUID, protocol); + auto statusWithOptionalResult = _registerAndSetUpIndexBuild( + opCtx, collectionUUID, specs, buildUUID, protocol, indexBuildOptions.commitQuorum); if (!statusWithOptionalResult.isOK()) { return statusWithOptionalResult.getStatus(); } diff --git a/src/mongo/embedded/index_builds_coordinator_embedded.h b/src/mongo/embedded/index_builds_coordinator_embedded.h index f33a529da3a..718276e8df1 100644 --- a/src/mongo/embedded/index_builds_coordinator_embedded.h +++ b/src/mongo/embedded/index_builds_coordinator_embedded.h @@ -61,7 +61,8 @@ public: CollectionUUID collectionUUID, const std::vector& specs, const UUID& buildUUID, - IndexBuildProtocol protocol) override; + IndexBuildProtocol protocol, + IndexBuildOptions indexBuildOptions) override; /** * None of the following functions should ever be called on an embedded server node. -- cgit v1.2.1