diff options
author | Kevin Pulo <kevin.pulo@mongodb.com> | 2020-02-16 04:51:35 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2020-02-16 04:51:35 +0000 |
commit | 95c8fc6a4a98f70b07f32565e3ef3e48172efa1e (patch) | |
tree | 5a4288ed6451cee86fdd319dcb52a592ec387c0e /src/mongo/db/write_concern.cpp | |
parent | 1d21e89fa5c9d838b2f40045c26fe41f306a8873 (diff) | |
download | mongo-95c8fc6a4a98f70b07f32565e3ef3e48172efa1e.tar.gz |
SERVER-45623 read/write concern provenance
Diffstat (limited to 'src/mongo/db/write_concern.cpp')
-rw-r--r-- | src/mongo/db/write_concern.cpp | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp index 3f55e87de40..e1fa1b4540f 100644 --- a/src/mongo/db/write_concern.cpp +++ b/src/mongo/db/write_concern.cpp @@ -82,10 +82,14 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx, WriteConcernOptions writeConcern = wcResult.getValue(); - // If no write concern is specified in the command (so usedDefault is true), then use the - // cluster-wide default WC (if there is one), or else the default WC from the ReplSetConfig - // (which takes the ReplicationCoordinator mutex). - if (writeConcern.usedDefault) { + bool clientSuppliedWriteConcern = !writeConcern.usedDefault; + bool customDefaultWasApplied = false; + bool getLastErrorDefaultsWasApplied = false; + + // If no write concern is specified in the command, then use the cluster-wide default WC (if + // there is one), or else the default WC from the ReplSetConfig (which takes the + // ReplicationCoordinator mutex). + if (!clientSuppliedWriteConcern) { writeConcern = ([&]() { // WriteConcern defaults can only be applied on regular replica set members. Operations // received by shard and config servers should always have WC explicitly specified. @@ -95,9 +99,11 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx, (!opCtx->inMultiDocumentTransaction() || isTransactionCommand(cmdObj.firstElementFieldName())) && !opCtx->getClient()->isInDirectClient()) { + auto wcDefault = ReadWriteConcernDefaults::get(opCtx->getServiceContext()) .getDefaultWriteConcern(opCtx); if (wcDefault) { + customDefaultWasApplied = true; LOGV2_DEBUG(22548, 2, "Applying default writeConcern on {cmdObj_firstElementFieldName} " @@ -128,6 +134,8 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx, if (getLastErrorDefault.wNumNodes == 1 && getLastErrorDefault.wTimeout == 0) { getLastErrorDefault.usedDefault = true; getLastErrorDefault.usedDefaultW = true; + } else { + getLastErrorDefaultsWasApplied = true; } return getLastErrorDefault; })(); @@ -137,6 +145,21 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx, writeConcern.usedDefaultW = true; } + // It's fine for clients to provide any provenance value to mongod. But if they haven't, then an + // appropriate provenance needs to be determined. + auto& provenance = writeConcern.getProvenance(); + if (!provenance.hasSource()) { + if (clientSuppliedWriteConcern) { + provenance.setSource(ReadWriteConcernProvenance::Source::clientSupplied); + } else if (customDefaultWasApplied) { + provenance.setSource(ReadWriteConcernProvenance::Source::customDefault); + } else if (getLastErrorDefaultsWasApplied) { + provenance.setSource(ReadWriteConcernProvenance::Source::getLastErrorDefaults); + } else { + provenance.setSource(ReadWriteConcernProvenance::Source::implicitDefault); + } + } + if (writeConcern.usedDefault && serverGlobalParams.clusterRole == ClusterRole::ConfigServer && !opCtx->getClient()->isInDirectClient() && (opCtx->getClient()->session() && @@ -146,6 +169,7 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx, // does not specify writeConcern when writing to the config server. writeConcern = { WriteConcernOptions::kMajority, WriteConcernOptions::SyncMode::UNSET, Seconds(30)}; + writeConcern.getProvenance().setSource(ReadWriteConcernProvenance::Source::implicitDefault); } else { Status wcStatus = validateWriteConcern(opCtx, writeConcern); if (!wcStatus.isOK()) { |