summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorHuayu Ouyang <huayu.ouyang@mongodb.com>2021-04-22 22:57:03 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-04-28 17:47:34 +0000
commit75a84d831d04c13ee6d0578f2b22b01e234c9737 (patch)
tree1d345e323aab969240138cbcf04029298275e16f /src/mongo/db
parentddd0a40a0d53de5b4269db46ef7bf8ffdd765cc2 (diff)
downloadmongo-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/SConscript4
-rw-r--r--src/mongo/db/read_write_concern_defaults.cpp16
-rw-r--r--src/mongo/db/read_write_concern_defaults_test.cpp63
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 =