0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-55702 Update 'defaultRWConcern' section of serverStatus

This commit is contained in:
Huayu Ouyang 2021-05-11 19:30:03 +00:00 committed by Evergreen Agent
parent 065762a395
commit 28206ffd75
4 changed files with 250 additions and 61 deletions

View File

@ -12,12 +12,9 @@ load("jstests/libs/write_concern_util.js"); // For isDefaultWriteConcernMajorit
// Verifies the transaction server status response has the fields that we expect.
function verifyServerStatus(conn,
{expectedRC, expectedWC, expectNoDefaultsDocument, expectNothing}) {
{expectedRC, expectedWC, expectNoDefaultsDocument, expectNothing},
isImplicitDefaultWCMajority) {
const res = assert.commandWorked(conn.adminCommand({serverStatus: 1}));
if (isDefaultWriteConcernMajorityFlagEnabled(conn) && !expectedWC) {
expectedWC = {w: "majority", wtimeout: 0};
}
if (expectNothing) {
assert.eq(undefined, res.defaultRWConcern, tojson(res.defaultRWConcern));
return;
@ -26,6 +23,20 @@ function verifyServerStatus(conn,
assert.hasFields(res, ["defaultRWConcern"]);
const defaultsRes = res.defaultRWConcern;
if (isDefaultWriteConcernMajorityFlagEnabled(conn)) {
assert.hasFields(defaultsRes, ["defaultWriteConcernSource"]);
if (!expectedWC) {
assert.eq("implicit", defaultsRes.defaultWriteConcernSource, tojson(defaultsRes));
if (isImplicitDefaultWCMajority) {
expectedWC = {w: "majority", wtimeout: 0};
}
} else {
assert.eq("global", defaultsRes.defaultWriteConcernSource, tojson(defaultsRes));
}
} else {
assert.eq(undefined, defaultsRes.defaultWriteConcernSource);
}
if (expectedRC) {
assert.eq(expectedRC, defaultsRes.defaultReadConcern, tojson(defaultsRes));
} else {
@ -52,24 +63,25 @@ function verifyServerStatus(conn,
}
}
function testServerStatus(conn) {
function testServerStatus(conn, isImplicitDefaultWCMajority) {
// When no defaults have been set.
verifyServerStatus(conn, {expectNoDefaultsDocument: true});
verifyServerStatus(conn, {expectNoDefaultsDocument: true}, isImplicitDefaultWCMajority);
// When only read concern is set.
assert.commandWorked(
conn.adminCommand({setDefaultRWConcern: 1, defaultReadConcern: {level: "majority"}}));
verifyServerStatus(conn, {expectedRC: {level: "majority"}});
verifyServerStatus(conn, {expectedRC: {level: "majority"}}, isImplicitDefaultWCMajority);
// When read concern is explicitly unset and write concern is unset.
assert.commandWorked(conn.adminCommand(
{setDefaultRWConcern: 1, defaultReadConcern: {}, defaultWriteConcern: {}}));
verifyServerStatus(conn, {});
verifyServerStatus(conn, {}, isImplicitDefaultWCMajority);
// When only write concern is set.
assert.commandWorked(conn.adminCommand(
{setDefaultRWConcern: 1, defaultReadConcern: {}, defaultWriteConcern: {w: "majority"}}));
verifyServerStatus(conn, {expectedWC: {w: "majority", wtimeout: 0}});
verifyServerStatus(
conn, {expectedWC: {w: "majority", wtimeout: 0}}, isImplicitDefaultWCMajority);
// When both read and write concern are set.
assert.commandWorked(conn.adminCommand({
@ -78,7 +90,8 @@ function testServerStatus(conn) {
defaultWriteConcern: {w: "majority"}
}));
verifyServerStatus(conn,
{expectedRC: {level: "majority"}, expectedWC: {w: "majority", wtimeout: 0}});
{expectedRC: {level: "majority"}, expectedWC: {w: "majority", wtimeout: 0}},
isImplicitDefaultWCMajority);
// When the defaults document has been deleted.
assert.commandWorked(conn.getDB("config").settings.remove({_id: "ReadWriteConcernDefaults"}));
@ -88,7 +101,7 @@ function testServerStatus(conn) {
const res = conn.adminCommand({getDefaultRWConcern: 1, inMemory: true});
return !res.hasOwnProperty("updateOpTime");
}, "mongos failed to pick up deleted default rwc", undefined, 1000, {runHangAnalyzer: false});
verifyServerStatus(conn, {expectNoDefaultsDocument: true});
verifyServerStatus(conn, {expectNoDefaultsDocument: true}, isImplicitDefaultWCMajority);
}
function testFTDC(conn, ftdcDirPath, expectNothingOnRotation = false) {
@ -140,16 +153,17 @@ jsTestLog("Testing sharded cluster...");
configOptions: {setParameter: {diagnosticDataCollectionDirectoryPath: testPathConfig}}
});
testServerStatus(st.s);
testServerStatus(st.s, true /* isImplicitDefaultWCMajority */);
testFTDC(st.s, testPathMongos);
testServerStatus(st.configRS.getPrimary());
testServerStatus(st.configRS.getPrimary(), true /* isImplicitDefaultWCMajority */);
testFTDC(st.configRS.getPrimary(), testPathConfig);
// Set a default before verifying it isn't included by shards.
assert.commandWorked(
st.s.adminCommand({setDefaultRWConcern: 1, defaultWriteConcern: {w: "majority"}}));
verifyServerStatus(st.rs0.getPrimary(), {expectNothing: true});
verifyServerStatus(
st.rs0.getPrimary(), {expectNothing: true}, true /* isImplicitDefaultWCMajority */);
testFTDC(st.rs0.getPrimary(), testPathShard, true /* expectNothingOnRotation */);
st.stop();
@ -163,19 +177,29 @@ jsTestLog("Testing plain replica set...");
rst.startSet();
rst.initiate();
testServerStatus(rst.getPrimary());
testServerStatus(rst.getPrimary(), true /* isImplicitDefaultWCMajority */);
testFTDC(rst.getPrimary(), testPath);
rst.stopSet();
}
jsTestLog("Testing server status for plain replica set with implicit default WC {w:1}");
{
const rst = new ReplSetTest({nodes: [{}, {}, {arbiter: true}]});
rst.startSet();
rst.initiate();
testServerStatus(rst.getPrimary(), false /* isImplicitDefaultWCMajority */);
rst.stopSet();
}
jsTestLog("Testing standalone server...");
{
const testPath = MongoRunner.toRealPath("ftdc_dir_standalone");
const standalone =
MongoRunner.runMongod({setParameter: {diagnosticDataCollectionDirectoryPath: testPath}});
verifyServerStatus(standalone, {expectNothing: true});
verifyServerStatus(standalone, {expectNothing: true}, true /* isImplicitDefaultWCMajority */);
testFTDC(standalone, testPath, true /* expectNothingOnRotation */);
MongoRunner.stopMongod(standalone);

View File

@ -9,7 +9,10 @@ load("jstests/libs/write_concern_util.js"); // For isDefaultWriteConcernMajorit
// Asserts a set/get default RWC command response or persisted document contains the expected
// fields. Assumes a default read or write concern has been set previously and the response was not
// generated by a getDefaultRWConcern command with inMemory=true.
function verifyFields(res, {expectRC, expectWC, isPersistedDocument}) {
function verifyFields(res,
{expectRC, expectWC, isPersistedDocument},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority) {
// These fields are always set once a read or write concern has been set at least once.
let expectedFields = ["updateOpTime", "updateWallClockTime", "localUpdateWallClockTime"];
let unexpectedFields = ["inMemory"];
@ -20,12 +23,18 @@ function verifyFields(res, {expectRC, expectWC, isPersistedDocument}) {
unexpectedFields.push("defaultReadConcern");
}
if (expectWC) {
if (expectWC || (isImplicitDefaultWCMajority && !isPersistedDocument)) {
expectedFields.push("defaultWriteConcern");
} else {
unexpectedFields.push("defaultWriteConcern");
}
if (isDefaultWCMajorityFlagEnabled) {
expectedFields.push("defaultWriteConcernSource");
} else {
unexpectedFields.push("defaultWriteConcernSource");
}
// localUpdateWallClockTime is generated by the in-memory cache and is not stored in the
// persisted document.
if (isPersistedDocument) {
@ -38,6 +47,13 @@ function verifyFields(res, {expectRC, expectWC, isPersistedDocument}) {
assert(!res.hasOwnProperty(field),
`response unexpectedly had field '${field}', res: ${tojson(res)}`);
});
if (isDefaultWCMajorityFlagEnabled) {
if (expectWC) {
assert.eq(res.defaultWriteConcernSource, "global", tojson(res));
} else {
assert.eq(res.defaultWriteConcernSource, "implicit", tojson(res));
}
}
}
function verifyDefaultRWCommandsInvalidInput(conn) {
@ -115,13 +131,20 @@ function verifyDefaultRWCommandsInvalidInput(conn) {
}
// Verifies the default responses for the default RWC commands and the default persisted state.
function verifyDefaultState(conn) {
function verifyDefaultState(conn, isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority) {
const res = assert.commandWorked(conn.adminCommand({getDefaultRWConcern: 1}));
const inMemoryRes =
assert.commandWorked(conn.adminCommand({getDefaultRWConcern: 1, inMemory: true}));
// localUpdateWallClockTime is set when a node refreshes its defaults, even if none are found.
const expectedFields = ["localUpdateWallClockTime"];
if (isImplicitDefaultWCMajority) {
expectedFields.push("defaultWriteConcern");
}
if (isDefaultWCMajorityFlagEnabled) {
expectedFields.push("defaultWriteConcernSource");
}
expectedFields.forEach(field => {
assert(res.hasOwnProperty(field),
`response did not have field '${field}', res: ${tojson(res)}`);
@ -130,9 +153,19 @@ function verifyDefaultState(conn) {
});
assert.eq(inMemoryRes.inMemory, true, tojson(inMemoryRes));
if (isDefaultWCMajorityFlagEnabled) {
assert.eq(res.defaultWriteConcernSource, "implicit", tojson(res));
assert.eq(inMemoryRes.defaultWriteConcernSource, "implicit", tojson(inMemoryRes));
}
// No other fields should be returned if neither a default read nor write concern has been set.
const unexpectedFields =
["defaultReadConcern", "defaultWriteConcern", "updateOpTime", "updateWallClockTime"];
const unexpectedFields = ["defaultReadConcern", "updateOpTime", "updateWallClockTime"];
if (!isImplicitDefaultWCMajority) {
unexpectedFields.push("defaultWriteConcern");
}
if (!isDefaultWCMajorityFlagEnabled) {
unexpectedFields.push("defaultWriteConcernSource");
}
unexpectedFields.forEach(field => {
assert(!res.hasOwnProperty(field),
`response unexpectedly had field '${field}', res: ${tojson(res)}`);
@ -146,7 +179,8 @@ function verifyDefaultState(conn) {
assert.eq(null, getPersistedRWCDocument(conn));
}
function verifyDefaultRWCommandsValidInputOnSuccess(conn) {
function verifyDefaultRWCommandsValidInputOnSuccess(
conn, isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority) {
//
// Test getDefaultRWConcern when neither read nor write concern are set.
//
@ -170,22 +204,34 @@ function verifyDefaultRWCommandsValidInputOnSuccess(conn) {
// Test setDefaultRWConcern when only read concern is set.
verifyFields(assert.commandWorked(conn.adminCommand(
{setDefaultRWConcern: 1, defaultReadConcern: {level: "local"}})),
{expectRC: true, expectWC: false});
{expectRC: true, expectWC: false},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
verifyFields(getPersistedRWCDocument(conn),
{expectRC: true, expectWC: false, isPersistedDocument: true});
{expectRC: true, expectWC: false, isPersistedDocument: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
// Test getDefaultRWConcern when only read concern is set.
verifyFields(assert.commandWorked(conn.adminCommand({getDefaultRWConcern: 1})),
{expectRC: true, expectWC: false});
{expectRC: true, expectWC: false},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
// Test unsetting read concern.
verifyFields(
assert.commandWorked(conn.adminCommand({setDefaultRWConcern: 1, defaultReadConcern: {}})),
{expectRC: false, expectWC: false});
{expectRC: false, expectWC: false},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
verifyFields(getPersistedRWCDocument(conn),
{expectRC: false, expectWC: false, isPersistedDocument: true});
{expectRC: false, expectWC: false, isPersistedDocument: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
verifyFields(assert.commandWorked(conn.adminCommand({getDefaultRWConcern: 1})),
{expectRC: false, expectWC: false});
{expectRC: false, expectWC: false},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
//
// Test getting and setting write concern.
@ -194,9 +240,13 @@ function verifyDefaultRWCommandsValidInputOnSuccess(conn) {
// Empty write concern is allowed if write concern has not already been set.
verifyFields(
assert.commandWorked(conn.adminCommand({setDefaultRWConcern: 1, defaultWriteConcern: {}})),
{expectRC: false, expectWC: false});
{expectRC: false, expectWC: false},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
verifyFields(getPersistedRWCDocument(conn),
{expectRC: false, expectWC: false, isPersistedDocument: true});
{expectRC: false, expectWC: false, isPersistedDocument: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
// Test setRWConcern when only write concern is set.
assert.commandWorked(conn.adminCommand({setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}}));
@ -207,13 +257,19 @@ function verifyDefaultRWCommandsValidInputOnSuccess(conn) {
verifyFields(assert.commandWorked(
conn.adminCommand({setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}})),
{expectRC: false, expectWC: true});
{expectRC: false, expectWC: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
verifyFields(getPersistedRWCDocument(conn),
{expectRC: false, expectWC: true, isPersistedDocument: true});
{expectRC: false, expectWC: true, isPersistedDocument: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
// Test getRWConcern when only write concern is set.
verifyFields(assert.commandWorked(conn.adminCommand({getDefaultRWConcern: 1})),
{expectRC: false, expectWC: true});
{expectRC: false, expectWC: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
//
// Test getting and setting both read and write concern.
@ -223,13 +279,19 @@ function verifyDefaultRWCommandsValidInputOnSuccess(conn) {
defaultReadConcern: {level: "local"},
defaultWriteConcern: {w: 1}
})),
{expectRC: true, expectWC: true});
{expectRC: true, expectWC: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
verifyFields(getPersistedRWCDocument(conn),
{expectRC: true, expectWC: true, isPersistedDocument: true});
{expectRC: true, expectWC: true, isPersistedDocument: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
// Test getRWConcern when both read and write concern are set.
verifyFields(assert.commandWorked(conn.adminCommand({getDefaultRWConcern: 1})),
{expectRC: true, expectWC: true});
{expectRC: true, expectWC: true},
isDefaultWCMajorityFlagEnabled,
isImplicitDefaultWCMajority);
}
function getPersistedRWCDocument(conn) {
@ -255,22 +317,20 @@ jsTestLog("Testing standalone mongod...");
MongoRunner.stopMongod(standalone);
}
jsTestLog("Testing standalone replica set...");
jsTestLog("Testing standalone replica set with implicit default write concern majority...");
{
const rst = new ReplSetTest({nodes: 2});
rst.startSet();
rst.initiate();
// TODO (SERVER-56643): Fix the test to work with the new default write concern.
if (isDefaultWriteConcernMajorityFlagEnabled(rst.getPrimary())) {
jsTestLog("Skipping test because the default WC majority feature flag is enabled.");
rst.stopSet();
return;
}
// Primary succeeds.
verifyDefaultState(rst.getPrimary());
verifyDefaultRWCommandsValidInputOnSuccess(rst.getPrimary());
const isDefaultWCMajorityFlagEnabled =
isDefaultWriteConcernMajorityFlagEnabled(rst.getPrimary());
const isImplicitDefaultWCMajority = isDefaultWCMajorityFlagEnabled;
verifyDefaultState(
rst.getPrimary(), isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsValidInputOnSuccess(
rst.getPrimary(), isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsInvalidInput(rst.getPrimary());
// Secondary can run getDefaultRWConcern, but not setDefaultRWConcern.
@ -283,18 +343,41 @@ jsTestLog("Testing standalone replica set...");
rst.stopSet();
}
jsTestLog("Testing sharded cluster...");
jsTestLog("Testing standalone replica set with implicit default write concern {w:1}...");
{
const rst = new ReplSetTest({nodes: [{}, {}, {arbiter: true}]});
rst.startSet();
rst.initiate();
// Primary succeeds.
const isDefaultWCMajorityFlagEnabled =
isDefaultWriteConcernMajorityFlagEnabled(rst.getPrimary());
verifyDefaultState(
rst.getPrimary(), isDefaultWCMajorityFlagEnabled, false /* isImplicitDefaultWCMajority */);
verifyDefaultRWCommandsValidInputOnSuccess(
rst.getPrimary(), isDefaultWCMajorityFlagEnabled, false /* isImplicitDefaultWCMajority */);
verifyDefaultRWCommandsInvalidInput(rst.getPrimary());
// Secondary can run getDefaultRWConcern, but not setDefaultRWConcern.
assert.commandWorked(rst.getSecondary().adminCommand({getDefaultRWConcern: 1}));
assert.commandFailedWithCode(
rst.getSecondary().adminCommand(
{setDefaultRWConcern: 1, defaultReadConcern: {level: "local"}}),
ErrorCodes.NotWritablePrimary);
rst.stopSet();
}
jsTestLog("Testing sharded cluster with implicit default write concern majority...");
{
let st = new ShardingTest({shards: 1, rs: {nodes: 2}});
if (isDefaultWriteConcernMajorityFlagEnabled(st.s)) {
jsTestLog("Skipping test because the default WC majority feature flag is enabled.");
st.stop();
return;
}
// Mongos succeeds.
verifyDefaultState(st.s);
verifyDefaultRWCommandsValidInputOnSuccess(st.s);
let isDefaultWCMajorityFlagEnabled = isDefaultWriteConcernMajorityFlagEnabled(st.s);
let isImplicitDefaultWCMajority = isDefaultWCMajorityFlagEnabled;
verifyDefaultState(st.s, isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsValidInputOnSuccess(
st.s, isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsInvalidInput(st.s);
// Shard node fails.
@ -310,8 +393,57 @@ jsTestLog("Testing sharded cluster...");
st.stop();
st = new ShardingTest({shards: 1, rs: {nodes: 2}});
// Config server primary succeeds.
verifyDefaultState(st.configRS.getPrimary());
verifyDefaultRWCommandsValidInputOnSuccess(st.configRS.getPrimary());
isDefaultWCMajorityFlagEnabled =
isDefaultWriteConcernMajorityFlagEnabled(st.configRS.getPrimary());
isImplicitDefaultWCMajority = isDefaultWCMajorityFlagEnabled;
verifyDefaultState(
st.configRS.getPrimary(), isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsValidInputOnSuccess(
st.configRS.getPrimary(), isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsInvalidInput(st.configRS.getPrimary());
// Config server secondary can run getDefaultRWConcern, but not setDefaultRWConcern.
assert.commandWorked(st.configRS.getSecondary().adminCommand({getDefaultRWConcern: 1}));
assert.commandFailedWithCode(
st.configRS.getSecondary().adminCommand(
{setDefaultRWConcern: 1, defaultReadConcern: {level: "local"}}),
ErrorCodes.NotWritablePrimary);
st.stop();
}
jsTestLog("Testing sharded cluster with a PSA replica set...");
{
let st = new ShardingTest({shards: 1, rs: {nodes: [{}, {}, {arbiter: true}]}});
// Mongos succeeds.
let isDefaultWCMajorityFlagEnabled = isDefaultWriteConcernMajorityFlagEnabled(st.s);
let isImplicitDefaultWCMajority = isDefaultWCMajorityFlagEnabled;
verifyDefaultState(st.s, isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsValidInputOnSuccess(
st.s, isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsInvalidInput(st.s);
// Shard node fails.
verifyDefaultRWCommandsFailWithCode(st.rs0.getPrimary(), {failureCode: 51301});
assert.commandFailedWithCode(st.rs0.getSecondary().adminCommand({getDefaultRWConcern: 1}),
51301);
// Secondaries fail setDefaultRWConcern before executing the command.
assert.commandFailedWithCode(
st.rs0.getSecondary().adminCommand(
{setDefaultRWConcern: 1, defaultReadConcern: {level: "local"}}),
ErrorCodes.NotWritablePrimary);
st.stop();
st = new ShardingTest({shards: 1, rs: {nodes: 2}});
// Config server primary succeeds.
isDefaultWCMajorityFlagEnabled =
isDefaultWriteConcernMajorityFlagEnabled(st.configRS.getPrimary());
isImplicitDefaultWCMajority = isDefaultWCMajorityFlagEnabled;
verifyDefaultState(
st.configRS.getPrimary(), isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsValidInputOnSuccess(
st.configRS.getPrimary(), isDefaultWCMajorityFlagEnabled, isImplicitDefaultWCMajority);
verifyDefaultRWCommandsInvalidInput(st.configRS.getPrimary());
// Config server secondary can run getDefaultRWConcern, but not setDefaultRWConcern.

View File

@ -110,6 +110,12 @@ RWConcernDefault ReadWriteConcernDefaults::generateNewCWRWCToBeSavedOnDisk(
rc || wc);
RWConcernDefault rwc;
const bool isDefaultWCMajorityFeatureFlagEnabled =
repl::feature_flags::gDefaultWCMajority.isEnabled(serverGlobalParams.featureCompatibility);
if (isDefaultWCMajorityFeatureFlagEnabled) {
rwc.setDefaultWriteConcernSource(DefaultWriteConcernSourceEnum::kImplicit);
}
if (rc && !rc->isEmpty()) {
checkSuitabilityAsDefault(*rc);
rwc.setDefaultReadConcern(rc);
@ -117,6 +123,9 @@ RWConcernDefault ReadWriteConcernDefaults::generateNewCWRWCToBeSavedOnDisk(
if (wc && !wc->usedDefault) {
checkSuitabilityAsDefault(*wc);
rwc.setDefaultWriteConcern(wc);
if (isDefaultWCMajorityFeatureFlagEnabled) {
rwc.setDefaultWriteConcernSource(DefaultWriteConcernSourceEnum::kGlobal);
}
}
auto* const serviceContext = opCtx->getServiceContext();
@ -130,6 +139,10 @@ RWConcernDefault ReadWriteConcernDefaults::generateNewCWRWCToBeSavedOnDisk(
}
if (!wc && current) {
rwc.setDefaultWriteConcern(current->getDefaultWriteConcern());
if (isDefaultWCMajorityFeatureFlagEnabled && current->getDefaultWriteConcern() &&
!current->getDefaultWriteConcern().get().usedDefault) {
rwc.setDefaultWriteConcernSource(DefaultWriteConcernSourceEnum::kGlobal);
}
}
// If the setDefaultRWConcern command tries to unset the global default write concern when it
// has already been set, throw an error.
@ -213,6 +226,12 @@ ReadWriteConcernDefaults::_getDefaultCWRWCFromDisk(OperationContext* opCtx) {
ReadWriteConcernDefaults::RWConcernDefaultAndTime ReadWriteConcernDefaults::getDefault(
OperationContext* opCtx) {
auto cached = _getDefaultCWRWCFromDisk(opCtx).value_or(RWConcernDefaultAndTime());
const bool isDefaultWCMajorityFeatureFlagEnabled =
serverGlobalParams.featureCompatibility.isVersionInitialized() &&
repl::feature_flags::gDefaultWCMajority.isEnabled(serverGlobalParams.featureCompatibility);
if (isDefaultWCMajorityFeatureFlagEnabled && !cached.getDefaultWriteConcernSource()) {
cached.setDefaultWriteConcernSource(DefaultWriteConcernSourceEnum::kImplicit);
}
// The implicit default write concern will be w:1 if the feature compatibility version is not
// yet initialized. Similarly, if the config hasn't yet been loaded on the node, the default
@ -220,10 +239,7 @@ ReadWriteConcernDefaults::RWConcernDefaultAndTime ReadWriteConcernDefaults::getD
// we have loaded our config, nodes could change their implicit write concern default. This is
// safe since we shouldn't be accepting writes that need a write concern before we have loaded
// our config.
if (!serverGlobalParams.featureCompatibility.isVersionInitialized() ||
!repl::feature_flags::gDefaultWCMajority.isEnabled(
serverGlobalParams.featureCompatibility) ||
!_implicitDefaultWriteConcernMajority) {
if (!isDefaultWCMajorityFeatureFlagEnabled || !_implicitDefaultWriteConcernMajority) {
return cached;
}
@ -232,6 +248,9 @@ ReadWriteConcernDefaults::RWConcernDefaultAndTime ReadWriteConcernDefaults::getD
cached.setDefaultWriteConcern(WriteConcernOptions(WriteConcernOptions::kMajority,
WriteConcernOptions::SyncMode::UNSET,
WriteConcernOptions::kNoTimeout));
if (isDefaultWCMajorityFeatureFlagEnabled) {
cached.setDefaultWriteConcernSource(DefaultWriteConcernSourceEnum::kImplicit);
}
}
return cached;

View File

@ -33,6 +33,16 @@ imports:
- "mongo/db/repl/read_concern_args.idl"
- "mongo/db/write_concern_options.idl"
enums:
DefaultWriteConcernSource:
description: "The source of the default write concern"
type: string
values:
# The default write concern was set implicitly by the server
kImplicit: "implicit"
# The default write concern was set globally through setDefaultRWConcern
kGlobal: "global"
structs:
RWConcernDefault:
description: "Represents a set of read/write concern defaults, and associated metadata"
@ -58,3 +68,7 @@ structs:
used for any recency comparisons."
type: date
optional: true
defaultWriteConcernSource:
description: "The source of the default write concern."
type: DefaultWriteConcernSource
optional: true