diff options
author | Dianna Hohensee <dianna.hohensee@mongodb.com> | 2020-07-24 17:03:21 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-19 00:56:17 +0000 |
commit | 6ffbf7c475ee34575a632040b70a6a20aa13cb4a (patch) | |
tree | 8575e17e2509dcd5dd99ad23dd2fca2108c07bd3 /src/mongo/db/collection_index_usage_tracker.cpp | |
parent | c4e552d731362a49f9d4a7ed4e646cfc852958da (diff) | |
download | mongo-6ffbf7c475ee34575a632040b70a6a20aa13cb4a.tar.gz |
SERVER-48539 Add internal concurrency control to CollectionIndexUsageTracker
Diffstat (limited to 'src/mongo/db/collection_index_usage_tracker.cpp')
-rw-r--r-- | src/mongo/db/collection_index_usage_tracker.cpp | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/src/mongo/db/collection_index_usage_tracker.cpp b/src/mongo/db/collection_index_usage_tracker.cpp index 4a30940d3cb..8cab4bb51b7 100644 --- a/src/mongo/db/collection_index_usage_tracker.cpp +++ b/src/mongo/db/collection_index_usage_tracker.cpp @@ -31,8 +31,11 @@ #include "mongo/platform/basic.h" -#include "mongo/base/counter.h" #include "mongo/db/collection_index_usage_tracker.h" + +#include <atomic> + +#include "mongo/base/counter.h" #include "mongo/db/commands/server_status_metric.h" #include "mongo/util/assert_util.h" #include "mongo/util/clock_source.h" @@ -49,15 +52,21 @@ ServerStatusMetricField<Counter64> displayCollectionScansNonTailable( } // namespace CollectionIndexUsageTracker::CollectionIndexUsageTracker(ClockSource* clockSource) - : _clockSource(clockSource) { + : _indexUsageStatsMap(std::make_shared<CollectionIndexUsageMap>()), _clockSource(clockSource) { invariant(_clockSource); } void CollectionIndexUsageTracker::recordIndexAccess(StringData indexName) { invariant(!indexName.empty()); - dassert(_indexUsageMap.find(indexName) != _indexUsageMap.end()); - _indexUsageMap[indexName].accesses.fetchAndAdd(1); + // The following update after fetching the map can race with the removal of this index entry + // from the map. However, that race is inconsequential and remains memory safe. + auto mapSharedPtr = atomic_load(&_indexUsageStatsMap); + + dassert(mapSharedPtr->find(indexName) != mapSharedPtr->end()); + + // Increment the index usage atomic counter. + mapSharedPtr->at(indexName)->accesses.fetchAndAdd(1); } void CollectionIndexUsageTracker::recordCollectionScans(unsigned long long collectionScans) { @@ -73,20 +82,39 @@ void CollectionIndexUsageTracker::recordCollectionScansNonTailable( void CollectionIndexUsageTracker::registerIndex(StringData indexName, const BSONObj& indexKey) { invariant(!indexName.empty()); - dassert(_indexUsageMap.find(indexName) == _indexUsageMap.end()); - // Create map entry. - _indexUsageMap[indexName] = IndexUsageStats(_clockSource->now(), indexKey); + // Create a copy of the map to modify. + auto mapSharedPtr = atomic_load(&_indexUsageStatsMap); + auto mapCopy = std::make_shared<CollectionIndexUsageMap>(*mapSharedPtr); + + dassert(mapCopy->find(indexName) == mapCopy->end()); + + // Create the map entry. + auto inserted = mapCopy->try_emplace( + indexName, make_intrusive<IndexUsageStats>(_clockSource->now(), indexKey)); + invariant(inserted.second); + + // Swap the modified map into place atomically. + atomic_store(&_indexUsageStatsMap, std::move(mapCopy)); } void CollectionIndexUsageTracker::unregisterIndex(StringData indexName) { invariant(!indexName.empty()); - _indexUsageMap.erase(indexName); + // Create a copy of the map to modify. + auto mapSharedPtr = atomic_load(&_indexUsageStatsMap); + auto mapCopy = std::make_shared<CollectionIndexUsageMap>(*mapSharedPtr); + + // Remove the map entry. + mapCopy->erase(indexName); + + // Swap the modified map into place atomically. + atomic_store(&_indexUsageStatsMap, std::move(mapCopy)); } -CollectionIndexUsageMap CollectionIndexUsageTracker::getUsageStats() const { - return _indexUsageMap; +std::shared_ptr<CollectionIndexUsageTracker::CollectionIndexUsageMap> +CollectionIndexUsageTracker::getUsageStats() const { + return atomic_load(&_indexUsageStatsMap); } CollectionIndexUsageTracker::CollectionScanStats |