diff options
author | Suganthi Mani <suganthi.mani@mongodb.com> | 2020-04-15 09:23:45 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-16 18:30:57 +0000 |
commit | 4ab404081f02d52285371c5a3b8520429a74e047 (patch) | |
tree | f7f27810f32447bbb7d50bb7a347e18ae82ecdce /src | |
parent | 44af4b2915cef5afcfe63104fb902e4519ffa889 (diff) | |
download | mongo-4ab404081f02d52285371c5a3b8520429a74e047.tar.gz |
SERVER-47464 Prevent SetIndexCommitQuorum cmd from changing commit quorum on to off & vice versa.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/index_builds_coordinator_mongod.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator_mongod_test.cpp | 57 |
2 files changed, 68 insertions, 1 deletions
diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp index 189e0397f29..517cf95d2c2 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod.cpp @@ -802,7 +802,17 @@ Status IndexBuildsCoordinatorMongod::setCommitQuorum(OperationContext* opCtx, << nss << "'."); } - invariantStatusOK(swOnDiskCommitQuorum); + auto currentCommitQuorum = invariantStatusOK(swOnDiskCommitQuorum); + if (currentCommitQuorum.numNodes == CommitQuorumOptions::kDisabled || + newCommitQuorum.numNodes == CommitQuorumOptions::kDisabled) { + return Status(ErrorCodes::BadValue, + str::stream() << "Commit quorum value can be changed only for index builds " + << "with commit quorum enabled, nss: '" << nss + << "' first index name: '" << indexNames.front() + << "' currentCommitQuorum: " << currentCommitQuorum.toBSON() + << " providedCommitQuorum: " << newCommitQuorum.toBSON()); + } + invariant(opCtx->lockState()->isRSTLLocked()); // About to update the commit quorum value on-disk. So, take the lock in exclusive mode to // prevent readers from reading the commit quorum value and making decision on commit quorum diff --git a/src/mongo/db/index_builds_coordinator_mongod_test.cpp b/src/mongo/db/index_builds_coordinator_mongod_test.cpp index d4fba054cae..59ecfba58b6 100644 --- a/src/mongo/db/index_builds_coordinator_mongod_test.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod_test.cpp @@ -313,6 +313,63 @@ TEST_F(IndexBuildsCoordinatorMongodTest, SetCommitQuorumWithBadArguments) { unittest::assertGet(testFoo1Future.getNoThrow()); } +TEST_F(IndexBuildsCoordinatorMongodTest, SetCommitQuorumFailsToTurnCommitQuorumFromOffToOn) { + _indexBuildsCoord->sleepIndexBuilds_forTestOnly(true); + + // Start an index build on _testFooNss with commit quorum disabled. + auto testFoo1Future = + assertGet(_indexBuildsCoord->startIndexBuild(operationContext(), + _testFooNss.db().toString(), + _testFooUUID, + makeSpecs(_testFooNss, {"a"}), + UUID::gen(), + IndexBuildProtocol::kTwoPhase, + _indexBuildOptions)); + + // Update the commit quorum value such that it enables commit quorum for the index + // build 'a_1'. + auto status = _indexBuildsCoord->setCommitQuorum( + operationContext(), _testFooNss, {"a_1"}, CommitQuorumOptions(1)); + ASSERT_EQUALS(ErrorCodes::BadValue, status); + + _indexBuildsCoord->sleepIndexBuilds_forTestOnly(false); + assertGet(testFoo1Future.getNoThrow()); +} + +TEST_F(IndexBuildsCoordinatorMongodTest, SetCommitQuorumFailsToTurnCommitQuorumFromOnToOff) { + _indexBuildsCoord->sleepIndexBuilds_forTestOnly(true); + + const IndexBuildsCoordinator::IndexBuildOptions indexBuildOptionsWithCQOn = { + CommitQuorumOptions(1)}; + const auto buildUUID = UUID::gen(); + + // Start an index build on _testFooNss with commit quorum enabled. + auto testFoo1Future = + assertGet(_indexBuildsCoord->startIndexBuild(operationContext(), + _testFooNss.db().toString(), + _testFooUUID, + makeSpecs(_testFooNss, {"a"}), + buildUUID, + IndexBuildProtocol::kTwoPhase, + indexBuildOptionsWithCQOn)); + + // Update the commit quorum value such that it disables commit quorum for the index + // build 'a_1'. + auto status = + _indexBuildsCoord->setCommitQuorum(operationContext(), + _testFooNss, + {"a_1"}, + CommitQuorumOptions(CommitQuorumOptions::kDisabled)); + ASSERT_EQUALS(ErrorCodes::BadValue, status); + + _indexBuildsCoord->sleepIndexBuilds_forTestOnly(false); + + ASSERT_OK(_indexBuildsCoord->voteCommitIndexBuild( + operationContext(), buildUUID, HostAndPort("test1", 1234))); + + assertGet(testFoo1Future.getNoThrow()); +} + } // namespace } // namespace mongo |