summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/noPassthroughWithMongod/top_rename.js52
-rw-r--r--src/mongo/db/catalog/create_collection.cpp4
-rw-r--r--src/mongo/db/catalog/database_holder_impl.cpp2
-rw-r--r--src/mongo/db/catalog/drop_collection.cpp4
-rw-r--r--src/mongo/db/catalog/rename_collection.cpp6
-rw-r--r--src/mongo/db/commands/create_indexes.cpp4
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp4
-rw-r--r--src/mongo/db/commands/killcursors_cmd.cpp2
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp2
-rw-r--r--src/mongo/db/db_raii.cpp16
-rw-r--r--src/mongo/db/db_raii.h26
-rw-r--r--src/mongo/db/query/find.cpp4
-rw-r--r--src/mongo/db/run_op_kill_cursors.cpp2
-rw-r--r--src/mongo/db/stats/top.cpp14
-rw-r--r--src/mongo/db/stats/top.h3
15 files changed, 96 insertions, 49 deletions
diff --git a/jstests/noPassthroughWithMongod/top_rename.js b/jstests/noPassthroughWithMongod/top_rename.js
new file mode 100644
index 00000000000..566d3ee5e6d
--- /dev/null
+++ b/jstests/noPassthroughWithMongod/top_rename.js
@@ -0,0 +1,52 @@
+/**
+ * Ensures that the data managed by Top is removed for the source namespace when renaming the
+ * collection.
+ *
+ * @tags: [incompatible_with_embedded]
+ */
+(function() {
+
+load("jstests/libs/stats.js");
+
+const dbName = "top_rename";
+const sourceCollection = "source";
+const destCollection = "dest";
+const mapReduceCollection = "final";
+
+const testDB = db.getSiblingDB(dbName);
+testDB.getCollection(sourceCollection).drop();
+testDB.getCollection(destCollection).drop();
+testDB.getCollection(mapReduceCollection).drop();
+
+assert.commandWorked(testDB.createCollection(sourceCollection));
+assert.doesNotThrow(() => {
+ getTop(testDB.getCollection(sourceCollection));
+});
+
+assert.commandWorked(testDB.adminCommand(
+ {renameCollection: dbName + "." + sourceCollection, to: dbName + "." + destCollection}));
+assert.throws(() => {
+ getTop(testDB.getCollection(sourceCollection));
+});
+
+// Perform an operation on the renamed collection so that it is present in the "top" command's
+// output.
+assert.commandWorked(testDB.getCollection(destCollection).insert({}));
+assert.doesNotThrow(() => {
+ getTop(testDB.getCollection(destCollection));
+});
+
+// MapReduce creates temporary collections before renaming them in place. Test that these temporary
+// collections are not kept in Top's output after the command finishes.
+assert.commandWorked(
+ testDB.getCollection(destCollection)
+ .mapReduce(function() {}, function() {}, {out: {merge: mapReduceCollection}}));
+
+const top = testDB.adminCommand("top");
+assert.commandWorked(top);
+
+const mapReduceTmp = ".tmp.";
+for (const collection in top.totals) {
+ assert.eq(false, collection.includes(mapReduceTmp));
+}
+}());
diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
index 61464bb08da..b70f4cd675f 100644
--- a/src/mongo/db/catalog/create_collection.cpp
+++ b/src/mongo/db/catalog/create_collection.cpp
@@ -71,7 +71,7 @@ Status _createView(OperationContext* opCtx,
AutoStatsTracker statsTracker(opCtx,
nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
db->getProfilingLevel());
if (opCtx->writesAreReplicated() &&
@@ -123,7 +123,7 @@ Status _createCollection(OperationContext* opCtx,
AutoStatsTracker statsTracker(opCtx,
nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
autoDb.getDb()->getProfilingLevel());
if (opCtx->writesAreReplicated() &&
diff --git a/src/mongo/db/catalog/database_holder_impl.cpp b/src/mongo/db/catalog/database_holder_impl.cpp
index 6ee95d92a81..9f20c1f563a 100644
--- a/src/mongo/db/catalog/database_holder_impl.cpp
+++ b/src/mongo/db/catalog/database_holder_impl.cpp
@@ -201,7 +201,7 @@ void DatabaseHolderImpl::dropDb(OperationContext* opCtx, Database* db) {
break;
}
- Top::get(serviceContext).collectionDropped(coll->ns(), true);
+ Top::get(serviceContext).collectionDropped(coll->ns());
}
close(opCtx, name);
diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp
index 5c374c2d98c..f973c1257bd 100644
--- a/src/mongo/db/catalog/drop_collection.cpp
+++ b/src/mongo/db/catalog/drop_collection.cpp
@@ -82,7 +82,7 @@ Status _dropView(OperationContext* opCtx,
AutoStatsTracker statsTracker(opCtx,
collectionName,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateCurOp,
db->getProfilingLevel());
if (opCtx->writesAreReplicated() &&
@@ -124,7 +124,7 @@ Status _dropCollection(OperationContext* opCtx,
AutoStatsTracker statsTracker(opCtx,
collectionName,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateCurOp,
db->getProfilingLevel());
if (opCtx->writesAreReplicated() &&
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp
index 3a614bc8092..626ab1ba1f4 100644
--- a/src/mongo/db/catalog/rename_collection.cpp
+++ b/src/mongo/db/catalog/rename_collection.cpp
@@ -320,7 +320,7 @@ Status renameCollectionWithinDB(OperationContext* opCtx,
AutoStatsTracker statsTracker(opCtx,
source,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateCurOp,
db->getProfilingLevel());
if (!targetColl) {
@@ -360,7 +360,7 @@ Status renameCollectionWithinDBForApplyOps(OperationContext* opCtx,
AutoStatsTracker statsTracker(opCtx,
source,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateCurOp,
db->getProfilingLevel());
return writeConflictRetry(opCtx, "renameCollection", target.ns(), [&] {
@@ -478,7 +478,7 @@ Status renameBetweenDBs(OperationContext* opCtx,
opCtx,
source,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateCurOp,
sourceDB->getProfilingLevel());
Collection* const sourceColl =
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 6c69b9ddc3b..24162252130 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -575,7 +575,7 @@ bool runCreateIndexesForMobile(OperationContext* opCtx,
statsTracker.emplace(opCtx,
ns,
Top::LockType::WriteLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
dbProfilingLevel);
MultiIndexBlock indexer;
@@ -840,7 +840,7 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx,
statsTracker.emplace(opCtx,
ns,
Top::LockType::WriteLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
dbProfilingLevel);
auto indexBuildsCoord = IndexBuildsCoordinator::get(opCtx);
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index 55a1fad1498..1795337753d 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -405,7 +405,7 @@ public:
statsTracker.emplace(opCtx,
_request.nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
dbProfilingLevel);
}
} else {
@@ -434,7 +434,7 @@ public:
statsTracker.emplace(opCtx,
_request.nss,
Top::LockType::ReadLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
readLock->getDb() ? readLock->getDb()->getProfilingLevel()
: doNotChangeProfilingLevel);
diff --git a/src/mongo/db/commands/killcursors_cmd.cpp b/src/mongo/db/commands/killcursors_cmd.cpp
index 591a381106c..52fdf7a6803 100644
--- a/src/mongo/db/commands/killcursors_cmd.cpp
+++ b/src/mongo/db/commands/killcursors_cmd.cpp
@@ -70,7 +70,7 @@ private:
statsTracker.emplace(opCtx,
nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
dbProfilingLevel);
}
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index aceebd1a900..d37112a4d34 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -552,7 +552,7 @@ Status runAggregate(OperationContext* opCtx,
statsTracker.emplace(opCtx,
nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
0);
collatorToUse.emplace(
PipelineD::resolveCollator(opCtx, request.getCollation(), nullptr));
diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp
index dd98f9f5ee7..02df85a977b 100644
--- a/src/mongo/db/db_raii.cpp
+++ b/src/mongo/db/db_raii.cpp
@@ -60,8 +60,12 @@ AutoStatsTracker::AutoStatsTracker(OperationContext* opCtx,
LogMode logMode,
boost::optional<int> dbProfilingLevel,
Date_t deadline)
- : _opCtx(opCtx), _lockType(lockType), _nss(nss) {
- if (!dbProfilingLevel && logMode == LogMode::kUpdateTopAndCurop) {
+ : _opCtx(opCtx), _lockType(lockType), _nss(nss), _logMode(logMode) {
+ if (_logMode == LogMode::kUpdateTop) {
+ return;
+ }
+
+ if (!dbProfilingLevel) {
// No profiling level was determined, attempt to read the profiling level from the Database
// object. Since we are only reading the in-memory profiling level out of the database
// object (which is configured on a per-node basis and not replicated or persisted), we
@@ -74,12 +78,14 @@ AutoStatsTracker::AutoStatsTracker(OperationContext* opCtx,
}
stdx::lock_guard<Client> clientLock(*_opCtx->getClient());
- if (logMode == LogMode::kUpdateTopAndCurop) {
- CurOp::get(_opCtx)->enter_inlock(_nss.ns().c_str(), dbProfilingLevel);
- }
+ CurOp::get(_opCtx)->enter_inlock(_nss.ns().c_str(), dbProfilingLevel);
}
AutoStatsTracker::~AutoStatsTracker() {
+ if (_logMode == LogMode::kUpdateCurOp) {
+ return;
+ }
+
auto curOp = CurOp::get(_opCtx);
Top::get(_opCtx->getServiceContext())
.record(_opCtx,
diff --git a/src/mongo/db/db_raii.h b/src/mongo/db/db_raii.h
index 940e13c1f6f..edf32cd0010 100644
--- a/src/mongo/db/db_raii.h
+++ b/src/mongo/db/db_raii.h
@@ -48,21 +48,21 @@ class AutoStatsTracker {
public:
/**
- *Describes which diagnostics to update during the lifetime of this object.
+ * Describes which diagnostics to update during the lifetime of this object.
*/
enum class LogMode {
- kUpdateTop, // Increments the Top counter for this operation type and this namespace upon
- // destruction.
- kUpdateTopAndCurop, // In addition to incrementing the Top counter, adjusts state on the
- // CurOp object associated with the OperationContext. Updates the
- // namespace to be 'nss', starts a timer for the operation (if it
- // hasn't started already), and figures out and records the profiling
- // level of the operation.
+ kUpdateTop, // Increments the Top counter for this operation type and this namespace
+ // upon destruction.
+ kUpdateCurOp, // Adjusts the state on the CurOp object associated with the
+ // OperationContext. Updates the namespace to be 'nss', starts a timer
+ // for the operation (if it hasn't already started), and figures out and
+ // records the profiling level of the operation.
+ kUpdateTopAndCurOp, // Performs the operations of both the LogModes specified above.
};
/**
- * If 'logMode' is 'kUpdateTopAndCurop', sets up and records state on the CurOp object attached
- * to 'opCtx', as described above.
+ * If 'logMode' is 'kUpdateCurOp' or 'kUpdateTopAndCurOp', sets up and records state on the
+ * CurOp object attached to 'opCtx', as described above.
*/
AutoStatsTracker(OperationContext* opCtx,
const NamespaceString& nss,
@@ -72,7 +72,8 @@ public:
Date_t deadline = Date_t::max());
/**
- * Records stats about the current operation via Top.
+ * Records stats about the current operation via Top, if 'logMode' is 'kUpdateTop' or
+ * 'kUpdateTopAndCurOp'.
*/
~AutoStatsTracker();
@@ -80,6 +81,7 @@ private:
OperationContext* _opCtx;
Top::LockType _lockType;
const NamespaceString _nss;
+ const LogMode _logMode;
};
/**
@@ -160,7 +162,7 @@ public:
const NamespaceStringOrUUID& nsOrUUID,
AutoGetCollection::ViewMode viewMode = AutoGetCollection::ViewMode::kViewsForbidden,
Date_t deadline = Date_t::max(),
- AutoStatsTracker::LogMode logMode = AutoStatsTracker::LogMode::kUpdateTopAndCurop);
+ AutoStatsTracker::LogMode logMode = AutoStatsTracker::LogMode::kUpdateTopAndCurOp);
Database* getDb() const {
return _autoCollForRead.getDb();
diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp
index d118bcb7ed3..87725fca4d1 100644
--- a/src/mongo/db/query/find.cpp
+++ b/src/mongo/db/query/find.cpp
@@ -300,7 +300,7 @@ Message getMore(OperationContext* opCtx,
statsTracker.emplace(opCtx,
nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
profilingLevel);
auto view = autoDb.getDb() ? ViewCatalog::get(autoDb.getDb())->lookup(opCtx, nss.ns())
: nullptr;
@@ -318,7 +318,7 @@ Message getMore(OperationContext* opCtx,
statsTracker.emplace(opCtx,
nss,
Top::LockType::ReadLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
readLock->getDb() ? readLock->getDb()->getProfilingLevel()
: doNotChangeProfilingLevel);
diff --git a/src/mongo/db/run_op_kill_cursors.cpp b/src/mongo/db/run_op_kill_cursors.cpp
index cb7dbf6f3e0..4b0733ef9d6 100644
--- a/src/mongo/db/run_op_kill_cursors.cpp
+++ b/src/mongo/db/run_op_kill_cursors.cpp
@@ -63,7 +63,7 @@ bool killCursorIfAuthorized(OperationContext* opCtx, CursorId id) {
statsTracker.emplace(opCtx,
nss,
Top::LockType::NotLocked,
- AutoStatsTracker::LogMode::kUpdateTopAndCurop,
+ AutoStatsTracker::LogMode::kUpdateTopAndCurOp,
dbProfilingLevel);
}
diff --git a/src/mongo/db/stats/top.cpp b/src/mongo/db/stats/top.cpp
index e9fea54b0cc..1cba425396c 100644
--- a/src/mongo/db/stats/top.cpp
+++ b/src/mongo/db/stats/top.cpp
@@ -85,12 +85,6 @@ void Top::record(OperationContext* opCtx,
auto hashedNs = UsageMap::hasher().hashed_key(ns);
stdx::lock_guard<SimpleMutex> lk(_lock);
- if ((command || logicalOp == LogicalOp::opQuery) &&
- _collDropNs.find(ns.toString()) != _collDropNs.end()) {
- _collDropNs.erase(ns.toString());
- return;
- }
-
CollectionData& coll = _usage[hashedNs];
_record(opCtx, coll, logicalOp, lockType, micros, readWriteType);
}
@@ -140,15 +134,9 @@ void Top::_record(OperationContext* opCtx,
}
}
-void Top::collectionDropped(const NamespaceString& nss, bool databaseDropped) {
+void Top::collectionDropped(const NamespaceString& nss) {
stdx::lock_guard<SimpleMutex> lk(_lock);
_usage.erase(nss.ns());
-
- if (!databaseDropped) {
- // If a collection drop occurred, there will be a subsequent call to record for this
- // collection namespace which must be ignored. This does not apply to a database drop.
- _collDropNs.insert(nss.toString());
- }
}
void Top::cloneMap(Top::UsageMap& out) const {
diff --git a/src/mongo/db/stats/top.h b/src/mongo/db/stats/top.h
index 2fcbb620f6c..635fda68a1e 100644
--- a/src/mongo/db/stats/top.h
+++ b/src/mongo/db/stats/top.h
@@ -108,7 +108,7 @@ public:
void cloneMap(UsageMap& out) const;
- void collectionDropped(const NamespaceString& nss, bool databaseDropped = false);
+ void collectionDropped(const NamespaceString& nss);
/**
* Appends the collection-level latency statistics
@@ -154,7 +154,6 @@ private:
mutable SimpleMutex _lock;
OperationLatencyHistogram _globalHistogramStats;
UsageMap _usage;
- std::set<std::string> _collDropNs;
};
} // namespace mongo