diff options
author | Huayu Ouyang <huayu.ouyang@mongodb.com> | 2021-04-22 22:57:03 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-04-28 17:47:34 +0000 |
commit | 75a84d831d04c13ee6d0578f2b22b01e234c9737 (patch) | |
tree | 1d345e323aab969240138cbcf04029298275e16f /src/mongo/db | |
parent | ddd0a40a0d53de5b4269db46ef7bf8ffdd765cc2 (diff) | |
download | mongo-75a84d831d04c13ee6d0578f2b22b01e234c9737.tar.gz |
SERVER-55697 Don't allow removing CWWC once it is set
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/SConscript | 4 | ||||
-rw-r--r-- | src/mongo/db/read_write_concern_defaults.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/read_write_concern_defaults_test.cpp | 63 |
3 files changed, 77 insertions, 6 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 2556198a1c1..b44f18ffb60 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -432,8 +432,11 @@ env.Library( 'write_concern_options', ], LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/idl/feature_flag', '$BUILD_DIR/mongo/util/caching', '$BUILD_DIR/mongo/util/concurrency/thread_pool', + 'repl/repl_server_parameters', + 'server_options_core', 'vector_clock', ], ) @@ -2421,6 +2424,7 @@ if wiredtiger: 'repl/mock_repl_coord_server_fixture', 'repl/oplog_interface_local', 'repl/repl_coordinator_interface', + 'repl/repl_server_parameters', 'repl/replica_set_aware_service', 'repl/replmocks', 'repl/storage_interface_impl', diff --git a/src/mongo/db/read_write_concern_defaults.cpp b/src/mongo/db/read_write_concern_defaults.cpp index 536d3a2471d..a046927eb3b 100644 --- a/src/mongo/db/read_write_concern_defaults.cpp +++ b/src/mongo/db/read_write_concern_defaults.cpp @@ -32,7 +32,8 @@ #include "mongo/platform/basic.h" #include "mongo/db/read_write_concern_defaults.h" - +#include "mongo/db/repl/repl_server_parameters_gen.h" +#include "mongo/db/server_options.h" #include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" @@ -130,6 +131,19 @@ RWConcernDefault ReadWriteConcernDefaults::generateNewConcerns( if (!wc && current) { rwc.setDefaultWriteConcern(current->getDefaultWriteConcern()); } + // If the setDefaultRWConcern command tries to unset the global default write concern when it + // has already been set, throw an error. + // wc->usedDefault indicates that the defaultWriteConcern given in the setDefaultRWConcern + // command was empty (i.e. {defaultWriteConcern: {}}) + // If current->getDefaultWriteConcern exists, that means the global default write concern has + // already been set. + if (repl::feature_flags::gDefaultWCMajority.isEnabled( + serverGlobalParams.featureCompatibility) && + wc && wc->usedDefault && current) { + uassert(ErrorCodes::IllegalOperation, + str::stream() << "The global default write concern cannot be unset once it is set.", + !current->getDefaultWriteConcern()); + } return rwc; } diff --git a/src/mongo/db/read_write_concern_defaults_test.cpp b/src/mongo/db/read_write_concern_defaults_test.cpp index c07de0e93f0..e902efbbc52 100644 --- a/src/mongo/db/read_write_concern_defaults_test.cpp +++ b/src/mongo/db/read_write_concern_defaults_test.cpp @@ -32,6 +32,8 @@ #include "mongo/db/read_write_concern_defaults.h" #include "mongo/db/read_write_concern_defaults_cache_lookup_mock.h" #include "mongo/db/repl/optime.h" +#include "mongo/db/repl/repl_server_parameters_gen.h" +#include "mongo/db/server_options.h" #include "mongo/db/service_context_test_fixture.h" #include "mongo/db/vector_clock_mutable.h" #include "mongo/db/vector_clock_test_fixture.h" @@ -403,13 +405,14 @@ TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, ASSERT_LT(oldDefaults.localUpdateWallClockTime(), newDefaults.localUpdateWallClockTime()); } -TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, - TestGenerateNewConcernsValidUnsetReadConcernAndWriteConcern) { +TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, TestGenerateNewConcernsValidUnsetReadConcern) { auto oldDefaults = setupOldDefaults(); - auto defaults = _rwcd.generateNewConcerns( - operationContext(), repl::ReadConcernArgs(), WriteConcernOptions()); + auto defaults = + _rwcd.generateNewConcerns(operationContext(), repl::ReadConcernArgs(), boost::none); ASSERT(!defaults.getDefaultReadConcern()); - ASSERT(!defaults.getDefaultWriteConcern()); + ASSERT(defaults.getDefaultWriteConcern()); + ASSERT_EQ(oldDefaults.getDefaultWriteConcern()->wNumNodes, + defaults.getDefaultWriteConcern()->wNumNodes); ASSERT_LT(*oldDefaults.getUpdateOpTime(), *defaults.getUpdateOpTime()); ASSERT_LT(*oldDefaults.getUpdateWallClockTime(), *defaults.getUpdateWallClockTime()); @@ -420,6 +423,56 @@ TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, } TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, + TestGenerateNewConcernsInvalidUnsetWriteConcern) { + auto oldDefaults = setupOldDefaults(); + if (repl::feature_flags::gDefaultWCMajority.isEnabled( + serverGlobalParams.featureCompatibility)) { + ASSERT_THROWS_CODE( + _rwcd.generateNewConcerns(operationContext(), boost::none, WriteConcernOptions()), + AssertionException, + ErrorCodes::IllegalOperation); + } else { + auto defaults = + _rwcd.generateNewConcerns(operationContext(), boost::none, WriteConcernOptions()); + ASSERT(defaults.getDefaultReadConcern()); + ASSERT(oldDefaults.getDefaultReadConcern()->getLevel() == + defaults.getDefaultReadConcern()->getLevel()); + ASSERT(!defaults.getDefaultWriteConcern()); + ASSERT_LT(*oldDefaults.getUpdateOpTime(), *defaults.getUpdateOpTime()); + ASSERT_LT(*oldDefaults.getUpdateWallClockTime(), *defaults.getUpdateWallClockTime()); + + _lookupMock.setLookupCallReturnValue(std::move(defaults)); + _rwcd.refreshIfNecessary(operationContext()); + auto newDefaults = _rwcd.getDefault(operationContext()); + ASSERT_LT(oldDefaults.localUpdateWallClockTime(), newDefaults.localUpdateWallClockTime()); + } +} + +TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, + TestGenerateNewConcernsInvalidUnsetReadWriteConcern) { + auto oldDefaults = setupOldDefaults(); + if (repl::feature_flags::gDefaultWCMajority.isEnabled( + serverGlobalParams.featureCompatibility)) { + ASSERT_THROWS_CODE(_rwcd.generateNewConcerns( + operationContext(), repl::ReadConcernArgs(), WriteConcernOptions()), + AssertionException, + ErrorCodes::IllegalOperation); + } else { + auto defaults = _rwcd.generateNewConcerns( + operationContext(), repl::ReadConcernArgs(), WriteConcernOptions()); + ASSERT(!defaults.getDefaultReadConcern()); + ASSERT(!defaults.getDefaultWriteConcern()); + ASSERT_LT(*oldDefaults.getUpdateOpTime(), *defaults.getUpdateOpTime()); + ASSERT_LT(*oldDefaults.getUpdateWallClockTime(), *defaults.getUpdateWallClockTime()); + + _lookupMock.setLookupCallReturnValue(std::move(defaults)); + _rwcd.refreshIfNecessary(operationContext()); + auto newDefaults = _rwcd.getDefault(operationContext()); + ASSERT_LT(oldDefaults.localUpdateWallClockTime(), newDefaults.localUpdateWallClockTime()); + } +} + +TEST_F(ReadWriteConcernDefaultsTestWithClusterTime, TestGenerateNewConcernsValidSetWriteConcernWithOnlyJ) { auto oldDefaults = setupOldDefaults(); auto defaults = |