diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/curop.cpp | 21 | ||||
-rw-r--r-- | src/mongo/db/curop.h | 7 | ||||
-rw-r--r-- | src/mongo/db/curop_test.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/exec/plan_stats.h | 6 | ||||
-rw-r--r-- | src/mongo/db/exec/upsert_stage.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/query/explain.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_write_cmd.cpp | 11 |
8 files changed, 49 insertions, 16 deletions
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index 6905e8ce469..670449fce89 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -835,7 +835,7 @@ string OpDebug::report(OperationContext* opCtx, const SingleThreadedLockStats* l OPDEBUG_TOSTRING_HELP_OPTIONAL("nModified", additiveMetrics.nModified); OPDEBUG_TOSTRING_HELP_OPTIONAL("ninserted", additiveMetrics.ninserted); OPDEBUG_TOSTRING_HELP_OPTIONAL("ndeleted", additiveMetrics.ndeleted); - OPDEBUG_TOSTRING_HELP_BOOL(upsert); + OPDEBUG_TOSTRING_HELP_OPTIONAL("nUpserted", additiveMetrics.nUpserted); OPDEBUG_TOSTRING_HELP_BOOL(cursorExhausted); OPDEBUG_TOSTRING_HELP_OPTIONAL("keysInserted", additiveMetrics.keysInserted); @@ -1004,7 +1004,7 @@ void OpDebug::report(OperationContext* opCtx, OPDEBUG_TOATTR_HELP_OPTIONAL("nModified", additiveMetrics.nModified); OPDEBUG_TOATTR_HELP_OPTIONAL("ninserted", additiveMetrics.ninserted); OPDEBUG_TOATTR_HELP_OPTIONAL("ndeleted", additiveMetrics.ndeleted); - OPDEBUG_TOATTR_HELP_BOOL(upsert); + OPDEBUG_TOATTR_HELP_OPTIONAL("nUpserted", additiveMetrics.nUpserted); OPDEBUG_TOATTR_HELP_BOOL(cursorExhausted); OPDEBUG_TOATTR_HELP_OPTIONAL("keysInserted", additiveMetrics.keysInserted); @@ -1126,7 +1126,7 @@ void OpDebug::append(OperationContext* opCtx, OPDEBUG_APPEND_OPTIONAL("nModified", additiveMetrics.nModified); OPDEBUG_APPEND_OPTIONAL("ninserted", additiveMetrics.ninserted); OPDEBUG_APPEND_OPTIONAL("ndeleted", additiveMetrics.ndeleted); - OPDEBUG_APPEND_BOOL(upsert); + OPDEBUG_APPEND_OPTIONAL("nUpserted", additiveMetrics.nUpserted); OPDEBUG_APPEND_BOOL(cursorExhausted); OPDEBUG_APPEND_OPTIONAL("keysInserted", additiveMetrics.keysInserted); @@ -1261,6 +1261,7 @@ void OpDebug::AdditiveMetrics::add(const AdditiveMetrics& otherMetrics) { nModified = addOptionalLongs(nModified, otherMetrics.nModified); ninserted = addOptionalLongs(ninserted, otherMetrics.ninserted); ndeleted = addOptionalLongs(ndeleted, otherMetrics.ndeleted); + nUpserted = addOptionalLongs(nUpserted, otherMetrics.nUpserted); keysInserted = addOptionalLongs(keysInserted, otherMetrics.keysInserted); keysDeleted = addOptionalLongs(keysDeleted, otherMetrics.keysDeleted); prepareReadConflicts.fetchAndAdd(otherMetrics.prepareReadConflicts.load()); @@ -1274,6 +1275,7 @@ void OpDebug::AdditiveMetrics::reset() { nModified = boost::none; ninserted = boost::none; ndeleted = boost::none; + nUpserted = boost::none; keysInserted = boost::none; keysDeleted = boost::none; prepareReadConflicts.store(0); @@ -1284,7 +1286,8 @@ bool OpDebug::AdditiveMetrics::equals(const AdditiveMetrics& otherMetrics) const return keysExamined == otherMetrics.keysExamined && docsExamined == otherMetrics.docsExamined && nMatched == otherMetrics.nMatched && nModified == otherMetrics.nModified && ninserted == otherMetrics.ninserted && ndeleted == otherMetrics.ndeleted && - keysInserted == otherMetrics.keysInserted && keysDeleted == otherMetrics.keysDeleted && + nUpserted == otherMetrics.nUpserted && keysInserted == otherMetrics.keysInserted && + keysDeleted == otherMetrics.keysDeleted && prepareReadConflicts.load() == otherMetrics.prepareReadConflicts.load() && writeConflicts.load() == otherMetrics.writeConflicts.load(); } @@ -1314,6 +1317,13 @@ void OpDebug::AdditiveMetrics::incrementNinserted(long long n) { *ninserted += n; } +void OpDebug::AdditiveMetrics::incrementNUpserted(long long n) { + if (!nUpserted) { + nUpserted = 0; + } + *nUpserted += n; +} + void OpDebug::AdditiveMetrics::incrementPrepareReadConflicts(long long n) { prepareReadConflicts.fetchAndAdd(n); } @@ -1327,6 +1337,7 @@ string OpDebug::AdditiveMetrics::report() const { OPDEBUG_TOSTRING_HELP_OPTIONAL("nModified", nModified); OPDEBUG_TOSTRING_HELP_OPTIONAL("ninserted", ninserted); OPDEBUG_TOSTRING_HELP_OPTIONAL("ndeleted", ndeleted); + OPDEBUG_TOSTRING_HELP_OPTIONAL("nUpserted", nUpserted); OPDEBUG_TOSTRING_HELP_OPTIONAL("keysInserted", keysInserted); OPDEBUG_TOSTRING_HELP_OPTIONAL("keysDeleted", keysDeleted); OPDEBUG_TOSTRING_HELP_ATOMIC("prepareReadConflicts", prepareReadConflicts); @@ -1342,6 +1353,7 @@ void OpDebug::AdditiveMetrics::report(logv2::DynamicAttributes* pAttrs) const { OPDEBUG_TOATTR_HELP_OPTIONAL("nModified", nModified); OPDEBUG_TOATTR_HELP_OPTIONAL("ninserted", ninserted); OPDEBUG_TOATTR_HELP_OPTIONAL("ndeleted", ndeleted); + OPDEBUG_TOATTR_HELP_OPTIONAL("nUpserted", nUpserted); OPDEBUG_TOATTR_HELP_OPTIONAL("keysInserted", keysInserted); OPDEBUG_TOATTR_HELP_OPTIONAL("keysDeleted", keysDeleted); OPDEBUG_TOATTR_HELP_ATOMIC("prepareReadConflicts", prepareReadConflicts); @@ -1356,6 +1368,7 @@ BSONObj OpDebug::AdditiveMetrics::reportBSON() const { OPDEBUG_APPEND_OPTIONAL("nModified", nModified); OPDEBUG_APPEND_OPTIONAL("ninserted", ninserted); OPDEBUG_APPEND_OPTIONAL("ndeleted", ndeleted); + OPDEBUG_APPEND_OPTIONAL("nUpserted", nUpserted); OPDEBUG_APPEND_OPTIONAL("keysInserted", keysInserted); OPDEBUG_APPEND_OPTIONAL("keysDeleted", keysDeleted); OPDEBUG_APPEND_ATOMIC("prepareReadConflicts", prepareReadConflicts); diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index 8702daae43c..7fe4794b984 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -112,6 +112,11 @@ public: void incrementNinserted(long long n); /** + * Increments nUpserted by n. + */ + void incrementNUpserted(long long n); + + /** * Increments prepareReadConflicts by n. */ void incrementPrepareReadConflicts(long long n); @@ -135,6 +140,7 @@ public: boost::optional<long long> nModified; boost::optional<long long> ninserted; boost::optional<long long> ndeleted; + boost::optional<long long> nUpserted; // Number of index keys inserted. boost::optional<long long> keysInserted; @@ -217,7 +223,6 @@ public: // True if a replan was triggered during the execution of this operation. std::optional<std::string> replanReason; - bool upsert{false}; // true if the update actually did an insert bool cursorExhausted{ false}; // true if the cursor has been closed at end a find/getMore operation diff --git a/src/mongo/db/curop_test.cpp b/src/mongo/db/curop_test.cpp index ecc3fb5f70a..de3fda03ab3 100644 --- a/src/mongo/db/curop_test.cpp +++ b/src/mongo/db/curop_test.cpp @@ -73,6 +73,8 @@ TEST(CurOpTest, AddingAdditiveMetricsObjectsTogetherShouldAddFieldsTogether) { additiveMetricsToAdd.ninserted = 0; currentAdditiveMetrics.ndeleted = 3; additiveMetricsToAdd.ndeleted = 2; + currentAdditiveMetrics.nUpserted = 7; + additiveMetricsToAdd.nUpserted = 8; currentAdditiveMetrics.keysInserted = 6; additiveMetricsToAdd.keysInserted = 5; currentAdditiveMetrics.keysDeleted = 4; @@ -100,6 +102,8 @@ TEST(CurOpTest, AddingAdditiveMetricsObjectsTogetherShouldAddFieldsTogether) { *additiveMetricsBeforeAdd.ninserted + *additiveMetricsToAdd.ninserted); ASSERT_EQ(*currentAdditiveMetrics.ndeleted, *additiveMetricsBeforeAdd.ndeleted + *additiveMetricsToAdd.ndeleted); + ASSERT_EQ(*currentAdditiveMetrics.nUpserted, + *additiveMetricsBeforeAdd.nUpserted + *additiveMetricsToAdd.nUpserted); ASSERT_EQ(*currentAdditiveMetrics.keysInserted, *additiveMetricsBeforeAdd.keysInserted + *additiveMetricsToAdd.keysInserted); ASSERT_EQ(*currentAdditiveMetrics.keysDeleted, @@ -147,6 +151,10 @@ TEST(CurOpTest, AddingUninitializedAdditiveMetricsFieldsShouldBeTreatedAsZero) { // object to add were not initialized, so nMatched should still be uninitialized after the add. ASSERT_EQ(currentAdditiveMetrics.nMatched, boost::none); + // The 'nUpserted' field for both the current AdditiveMetrics object and the AdditiveMetrics + // object to add were not initialized, so nUpserted should still be uninitialized after the add. + ASSERT_EQ(currentAdditiveMetrics.nUpserted, boost::none); + // The following field values should have changed after adding. ASSERT_EQ(*currentAdditiveMetrics.keysInserted, *additiveMetricsBeforeAdd.keysInserted + *additiveMetricsToAdd.keysInserted); @@ -173,12 +181,14 @@ TEST(CurOpTest, AdditiveMetricsFieldsShouldIncrementByN) { additiveMetrics.incrementKeysInserted(5); additiveMetrics.incrementKeysDeleted(0); additiveMetrics.incrementNinserted(3); + additiveMetrics.incrementNUpserted(6); additiveMetrics.incrementPrepareReadConflicts(2); ASSERT_EQ(additiveMetrics.writeConflicts.load(), 2); ASSERT_EQ(*additiveMetrics.keysInserted, 7); ASSERT_EQ(*additiveMetrics.keysDeleted, 0); ASSERT_EQ(*additiveMetrics.ninserted, 3); + ASSERT_EQ(*additiveMetrics.nUpserted, 6); ASSERT_EQ(additiveMetrics.prepareReadConflicts.load(), 8); } diff --git a/src/mongo/db/exec/plan_stats.h b/src/mongo/db/exec/plan_stats.h index 3d3137029c8..a67b2b6f452 100644 --- a/src/mongo/db/exec/plan_stats.h +++ b/src/mongo/db/exec/plan_stats.h @@ -722,7 +722,7 @@ struct NearStats : public SpecificStats { }; struct UpdateStats : public SpecificStats { - UpdateStats() : nMatched(0), nModified(0), isModUpdate(false), inserted(false) {} + UpdateStats() : nMatched(0), nModified(0), isModUpdate(false), nUpserted(0) {} SpecificStats* clone() const final { return new UpdateStats(*this); @@ -741,8 +741,8 @@ struct UpdateStats : public SpecificStats { // True iff this is a $mod update. bool isModUpdate; - // Is this an {upsert: true} update that did an insert? - bool inserted; + // Will be 1 if this is an {upsert: true} update that did an insert, 0 otherwise. + size_t nUpserted; // The object that was inserted. This is an empty document if no insert was performed. BSONObj objInserted; diff --git a/src/mongo/db/exec/upsert_stage.cpp b/src/mongo/db/exec/upsert_stage.cpp index 906b99e679a..4bf02125604 100644 --- a/src/mongo/db/exec/upsert_stage.cpp +++ b/src/mongo/db/exec/upsert_stage.cpp @@ -61,7 +61,7 @@ UpsertStage::UpsertStage(ExpressionContext* expCtx, // We're done when updating is finished and we have either matched or inserted. bool UpsertStage::isEOF() { - return UpdateStage::isEOF() && (_specificStats.nMatched > 0 || _specificStats.inserted); + return UpdateStage::isEOF() && (_specificStats.nMatched > 0 || _specificStats.nUpserted > 0); } PlanStage::StageState UpsertStage::doWork(WorkingSetID* out) { @@ -83,9 +83,9 @@ PlanStage::StageState UpsertStage::doWork(WorkingSetID* out) { invariant(updateState == PlanStage::IS_EOF && !isEOF()); // Since this is an insert, we will be logging it as such in the oplog. We don't need the - // driver's help to build the oplog record. We also set the 'inserted' stats flag here. + // driver's help to build the oplog record. We also set the 'nUpserted' stats counter here. _params.driver->setLogOp(false); - _specificStats.inserted = true; + _specificStats.nUpserted = 1; // Generate the new document to be inserted. _specificStats.objInserted = _produceNewDocumentForInsert(); diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index e6b5209488a..2bd2bfc3865 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -1016,7 +1016,7 @@ void recordUpdateResultInOpDebug(const UpdateResult& updateResult, OpDebug* opDe invariant(opDebug); opDebug->additiveMetrics.nMatched = updateResult.numMatched; opDebug->additiveMetrics.nModified = updateResult.numDocsModified; - opDebug->upsert = !updateResult.upsertedId.isEmpty(); + opDebug->additiveMetrics.nUpserted = static_cast<long long>(!updateResult.upsertedId.isEmpty()); } namespace { diff --git a/src/mongo/db/query/explain.cpp b/src/mongo/db/query/explain.cpp index 55a0af03740..d0deb055438 100644 --- a/src/mongo/db/query/explain.cpp +++ b/src/mongo/db/query/explain.cpp @@ -542,7 +542,7 @@ void Explain::statsToBSON(const PlanStageStats& stats, if (verbosity >= ExplainOptions::Verbosity::kExecStats) { bob->appendNumber("nMatched", spec->nMatched); bob->appendNumber("nWouldModify", spec->nModified); - bob->appendBool("wouldInsert", spec->inserted); + bob->appendNumber("nWouldUpsert", spec->nUpserted); } } diff --git a/src/mongo/s/commands/cluster_write_cmd.cpp b/src/mongo/s/commands/cluster_write_cmd.cpp index 17d1d415679..fbaced5e4b7 100644 --- a/src/mongo/s/commands/cluster_write_cmd.cpp +++ b/src/mongo/s/commands/cluster_write_cmd.cpp @@ -509,9 +509,14 @@ private: } catalogCache->checkAndRecordOperationBlockedByRefresh(opCtx, mongo::LogicalOp::opUpdate); - debug.upsert = response.isUpsertDetailsSet(); - debug.additiveMetrics.nMatched = - response.getN() - (debug.upsert ? response.sizeUpsertDetails() : 0); + + // The response.getN() count is the sum of documents matched and upserted. + if (response.isUpsertDetailsSet()) { + debug.additiveMetrics.nMatched = response.getN() - response.sizeUpsertDetails(); + debug.additiveMetrics.nUpserted = response.sizeUpsertDetails(); + } else { + debug.additiveMetrics.nMatched = response.getN(); + } debug.additiveMetrics.nModified = response.getNModified(); invariant(_updateMetrics); |