summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorNikita Lapkov <nikita.lapkov@mongodb.com>2020-08-25 16:53:30 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-09-03 21:09:55 +0000
commitcce8380c750dc9d45d88665e0e451013177fcd7a (patch)
tree8ee6af4721fa8a0b06680c0ef635a321efc35154 /src/mongo
parent39ce43a37c0e9bcdbaf04bbe76e9a75fefec7dd3 (diff)
downloadmongo-cce8380c750dc9d45d88665e0e451013177fcd7a.tar.gz
SERVER-34118 Log number of upserts performed
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/curop.cpp21
-rw-r--r--src/mongo/db/curop.h7
-rw-r--r--src/mongo/db/curop_test.cpp10
-rw-r--r--src/mongo/db/exec/plan_stats.h6
-rw-r--r--src/mongo/db/exec/upsert_stage.cpp6
-rw-r--r--src/mongo/db/ops/write_ops_exec.cpp2
-rw-r--r--src/mongo/db/query/explain.cpp2
-rw-r--r--src/mongo/s/commands/cluster_write_cmd.cpp11
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);