summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-02-14 16:15:50 -0500
committerGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-02-22 21:12:50 -0500
commit0f2da7fb758f12bd64c6c7891d455a53e1ab1d89 (patch)
treed21c7a099c802971bea6059041da5b3b15365079
parent4253bddd476f19fb6af295323acc9d5af15da598 (diff)
downloadmongo-0f2da7fb758f12bd64c6c7891d455a53e1ab1d89.tar.gz
SERVER-37954 Thread commitQuorum through the createIndexes command into the Coordinator
-rw-r--r--src/mongo/db/SConscript4
-rw-r--r--src/mongo/db/commands/SConscript2
-rw-r--r--src/mongo/db/commands/create_indexes.cpp39
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp23
-rw-r--r--src/mongo/db/index_builds_coordinator.h13
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod.cpp7
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod.h3
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod_test.cpp54
-rw-r--r--src/mongo/db/repl/oplog.cpp7
-rw-r--r--src/mongo/db/repl/repl_set_config.cpp6
-rw-r--r--src/mongo/db/repl/repl_set_config.h5
-rw-r--r--src/mongo/db/repl_index_build_state.h14
-rw-r--r--src/mongo/db/system_index.cpp11
-rw-r--r--src/mongo/embedded/index_builds_coordinator_embedded.cpp7
-rw-r--r--src/mongo/embedded/index_builds_coordinator_embedded.h3
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<std::vector<BSONObj>> parseAndValidateIndexSpecs(
}
hasIndexesField = true;
- } else if (kCommandName == cmdElemFieldName || kTwoPhaseCommandName == cmdElemFieldName ||
+ } else if (kCommandName == cmdElemFieldName || kCommitQuorumFieldName == cmdElemFieldName ||
+ kTwoPhaseCommandName == cmdElemFieldName ||
isGenericArgument(cmdElemFieldName)) {
continue;
} else {
@@ -161,6 +164,25 @@ StatusWith<std::vector<BSONObj>> parseAndValidateIndexSpecs(
}
/**
+ * 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<CommitQuorumOptions> 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
* new indexes need to be built. Throws on error.
@@ -450,6 +472,7 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx,
auto specs = uassertStatusOK(
parseAndValidateIndexSpecs(opCtx, ns, cmdObj, serverGlobalParams.featureCompatibility));
+ boost::optional<CommitQuorumOptions> 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<std::pair<long long, long long>> 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<ReplIndexBuildState>(
- buildUUID, collectionUUID, dbName, specs, IndexBuildProtocol::kSinglePhase);
+ auto replIndexBuildState =
+ std::make_shared<ReplIndexBuildState>(buildUUID,
+ collectionUUID,
+ dbName,
+ specs,
+ IndexBuildProtocol::kSinglePhase,
+ /*commitQuorum=*/boost::none);
Status status = [&]() {
stdx::unique_lock<stdx::mutex> lk(_mutex);
@@ -495,11 +500,13 @@ void IndexBuildsCoordinator::_unregisterIndexBuild(
}
StatusWith<boost::optional<SharedSemiFuture<ReplIndexBuildState::IndexCatalogStats>>>
-IndexBuildsCoordinator::_registerAndSetUpIndexBuild(OperationContext* opCtx,
- CollectionUUID collectionUUID,
- const std::vector<BSONObj>& specs,
- const UUID& buildUUID,
- IndexBuildProtocol protocol) {
+IndexBuildsCoordinator::_registerAndSetUpIndexBuild(
+ OperationContext* opCtx,
+ CollectionUUID collectionUUID,
+ const std::vector<BSONObj>& specs,
+ const UUID& buildUUID,
+ IndexBuildProtocol protocol,
+ boost::optional<CommitQuorumOptions> 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<ReplIndexBuildState>(
- 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
@@ -68,6 +68,13 @@ class ServiceContext;
class IndexBuildsCoordinator {
public:
/**
+ * Contains additional information required by 'startIndexBuild()'.
+ */
+ struct IndexBuildOptions {
+ boost::optional<CommitQuorumOptions> commitQuorum;
+ };
+
+ /**
* Invariants that there are no index builds in-progress.
*/
virtual ~IndexBuildsCoordinator();
@@ -104,7 +111,8 @@ public:
CollectionUUID collectionUUID,
const std::vector<BSONObj>& 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<BSONObj>& specs,
const UUID& buildUUID,
- IndexBuildProtocol protocol);
+ IndexBuildProtocol protocol,
+ boost::optional<CommitQuorumOptions> 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<BSONObj>& 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<BSONObj>& 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<IndexBuildsCoordinator> _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
@@ -142,6 +142,11 @@ public:
}
/**
+ * Gets the number of data-bearing members in this configuration.
+ */
+ int getNumDataBearingMembers() const;
+
+ /**
* Gets a begin iterator over the MemberConfigs stored in this ReplSetConfig.
*/
MemberIterator membersBegin() const {
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<BSONObj>& specs,
- IndexBuildProtocol protocol)
+ IndexBuildProtocol protocol,
+ boost::optional<CommitQuorumOptions> 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<CommitQuorumOptions> 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<ReplIndexBuildState::IndexCatalogStats> 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<BSONObj>& 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<BSONObj>& 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.