summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2015-09-30 17:41:56 -0400
committerJames Wahlin <james.wahlin@10gen.com>2015-10-07 15:42:22 -0400
commitec97a61067e2dc3f9c4e58a9d66b5e1f2600f978 (patch)
tree40c67ec652a87b17b794a8ba5fc5aa3b4fc3e99e
parent33167b814bb9d8962205a85fed34c9d88942db83 (diff)
downloadmongo-ec97a61067e2dc3f9c4e58a9d66b5e1f2600f978.tar.gz
SERVER-20520 Include index key in $indexStats return documents
-rw-r--r--jstests/core/index_stats.js14
-rw-r--r--src/mongo/db/catalog/collection_info_cache.cpp8
-rw-r--r--src/mongo/db/catalog/collection_info_cache.h3
-rw-r--r--src/mongo/db/catalog/index_catalog.cpp4
-rw-r--r--src/mongo/db/collection_index_usage_tracker.cpp4
-rw-r--r--src/mongo/db/collection_index_usage_tracker.h14
-rw-r--r--src/mongo/db/collection_index_usage_tracker_test.cpp28
-rw-r--r--src/mongo/db/pipeline/document_source_index_stats.cpp1
8 files changed, 55 insertions, 21 deletions
diff --git a/jstests/core/index_stats.js b/jstests/core/index_stats.js
index f2f913b3235..1fc028fca31 100644
--- a/jstests/core/index_stats.js
+++ b/jstests/core/index_stats.js
@@ -17,6 +17,19 @@
return undefined;
}
+ var getIndexKey = function (indexName) {
+ var cursor = col.aggregate([{$indexStats: {}}]);
+ while (cursor.hasNext()) {
+ var doc = cursor.next();
+
+ if (doc.name === indexName) {
+ return doc.key;
+ }
+ }
+
+ return undefined;
+ }
+
assert.writeOK(col.insert({a: 1, b: 1, c: 1}));
assert.writeOK(col.insert({a: 2, b: 2, c: 2}));
assert.writeOK(col.insert({a: 3, b: 3, c: 3}));
@@ -33,6 +46,7 @@
// Confirm a stats object exists post index creation (with 0 count).
assert.eq(countA, getUsageCount("a_1"));
+ assert.eq({a: 1}, getIndexKey("a_1"));
// Confirm index stats tick on find().
col.findOne({a: 1});
diff --git a/src/mongo/db/catalog/collection_info_cache.cpp b/src/mongo/db/catalog/collection_info_cache.cpp
index 9682ee40899..0f1e6409c4b 100644
--- a/src/mongo/db/catalog/collection_info_cache.cpp
+++ b/src/mongo/db/catalog/collection_info_cache.cpp
@@ -175,18 +175,20 @@ void CollectionInfoCache::init(OperationContext* txn) {
_collection->getIndexCatalog()->getIndexIterator(txn, includeUnfinishedIndexes);
while (ii.more()) {
const IndexDescriptor* desc = ii.next();
- _indexUsageTracker.registerIndex(desc->indexName());
+ _indexUsageTracker.registerIndex(desc->indexName(), desc->keyPattern());
}
rebuildIndexData(txn);
}
-void CollectionInfoCache::addedIndex(OperationContext* txn, StringData indexName) {
+void CollectionInfoCache::addedIndex(OperationContext* txn, const IndexDescriptor* desc) {
// Requires exclusive collection lock.
invariant(txn->lockState()->isCollectionLockedForMode(_collection->ns().ns(), MODE_X));
+ invariant(desc);
rebuildIndexData(txn);
- _indexUsageTracker.registerIndex(indexName);
+
+ _indexUsageTracker.registerIndex(desc->indexName(), desc->keyPattern());
}
void CollectionInfoCache::droppedIndex(OperationContext* txn, StringData indexName) {
diff --git a/src/mongo/db/catalog/collection_info_cache.h b/src/mongo/db/catalog/collection_info_cache.h
index 46d3a9e1784..4c5b67ed880 100644
--- a/src/mongo/db/catalog/collection_info_cache.h
+++ b/src/mongo/db/catalog/collection_info_cache.h
@@ -38,6 +38,7 @@
namespace mongo {
class Collection;
+class IndexDescriptor;
class OperationContext;
/**
@@ -83,7 +84,7 @@ public:
*
* Must be called under exclusive collection lock.
*/
- void addedIndex(OperationContext* txn, StringData indexName);
+ void addedIndex(OperationContext* txn, const IndexDescriptor* desc);
/**
* Deregister a newly-dropped index with the cache. Must be called whenever an index is
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp
index d0da634ac21..8662eb0f906 100644
--- a/src/mongo/db/catalog/index_catalog.cpp
+++ b/src/mongo/db/catalog/index_catalog.cpp
@@ -414,7 +414,7 @@ void IndexCatalog::IndexBuildBlock::success() {
entry->setIsReady(true);
- collection->infoCache()->addedIndex(_txn, _indexName);
+ collection->infoCache()->addedIndex(_txn, desc);
}
namespace {
@@ -792,7 +792,7 @@ public:
void rollback() final {
_entries->add(_entry);
- _collection->infoCache()->addedIndex(_txn, _entry->descriptor()->indexName());
+ _collection->infoCache()->addedIndex(_txn, _entry->descriptor());
}
private:
diff --git a/src/mongo/db/collection_index_usage_tracker.cpp b/src/mongo/db/collection_index_usage_tracker.cpp
index 10894bcfe6e..9b1d0e17b22 100644
--- a/src/mongo/db/collection_index_usage_tracker.cpp
+++ b/src/mongo/db/collection_index_usage_tracker.cpp
@@ -49,12 +49,12 @@ void CollectionIndexUsageTracker::recordIndexAccess(StringData indexName) {
_indexUsageMap[indexName].accesses.fetchAndAdd(1);
}
-void CollectionIndexUsageTracker::registerIndex(StringData indexName) {
+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());
+ _indexUsageMap[indexName] = IndexUsageStats(_clockSource->now(), indexKey);
}
void CollectionIndexUsageTracker::unregisterIndex(StringData indexName) {
diff --git a/src/mongo/db/collection_index_usage_tracker.h b/src/mongo/db/collection_index_usage_tracker.h
index def45712aad..ad55c229972 100644
--- a/src/mongo/db/collection_index_usage_tracker.h
+++ b/src/mongo/db/collection_index_usage_tracker.h
@@ -30,6 +30,7 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h"
+#include "mongo/bson/bsonobj.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/util/string_map.h"
#include "mongo/util/time_support.h"
@@ -51,14 +52,18 @@ class CollectionIndexUsageTracker {
public:
struct IndexUsageStats {
IndexUsageStats() = default;
- explicit IndexUsageStats(Date_t now) : trackerStartTime(now) {}
+ explicit IndexUsageStats(Date_t now, const BSONObj& key)
+ : trackerStartTime(now), indexKey(key.getOwned()) {}
IndexUsageStats(const IndexUsageStats& other)
- : accesses(other.accesses.load()), trackerStartTime(other.trackerStartTime) {}
+ : accesses(other.accesses.load()),
+ trackerStartTime(other.trackerStartTime),
+ indexKey(other.indexKey) {}
IndexUsageStats& operator=(const IndexUsageStats& other) {
accesses.store(other.accesses.load());
trackerStartTime = other.trackerStartTime;
+ indexKey = other.indexKey;
return *this;
}
@@ -67,6 +72,9 @@ public:
// Date/Time that we started tracking index usage.
Date_t trackerStartTime;
+
+ // An owned copy of the associated IndexDescriptor's index key.
+ BSONObj indexKey;
};
/**
@@ -87,7 +95,7 @@ public:
* Add map entry for 'indexName' stats collection. Must be called under exclusive collection
* lock.
*/
- void registerIndex(StringData indexName);
+ void registerIndex(StringData indexName, const BSONObj& indexKey);
/**
* Erase statistics for index 'indexName'. Must be called under exclusive collection lock.
diff --git a/src/mongo/db/collection_index_usage_tracker_test.cpp b/src/mongo/db/collection_index_usage_tracker_test.cpp
index 39a31120903..5ce0988452c 100644
--- a/src/mongo/db/collection_index_usage_tracker_test.cpp
+++ b/src/mongo/db/collection_index_usage_tracker_test.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
#include "mongo/db/collection_index_usage_tracker.h"
+#include "mongo/db/jsobj.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/clock_source_mock.h"
@@ -65,7 +66,7 @@ TEST_F(CollectionIndexUsageTrackerTest, Empty) {
// Test that recording of a single index hit is reflected in returned stats map.
TEST_F(CollectionIndexUsageTrackerTest, SingleHit) {
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
getTracker()->recordIndexAccess("foo");
CollectionIndexUsageMap statsMap = getTracker()->getUsageStats();
ASSERT(statsMap.find("foo") != statsMap.end());
@@ -74,7 +75,7 @@ TEST_F(CollectionIndexUsageTrackerTest, SingleHit) {
// Test that recording of multiple index hits are reflected in stats map.
TEST_F(CollectionIndexUsageTrackerTest, MultipleHit) {
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
getTracker()->recordIndexAccess("foo");
getTracker()->recordIndexAccess("foo");
CollectionIndexUsageMap statsMap = getTracker()->getUsageStats();
@@ -82,18 +83,25 @@ TEST_F(CollectionIndexUsageTrackerTest, MultipleHit) {
ASSERT_EQUALS(2, statsMap["foo"].accesses.loadRelaxed());
}
+TEST_F(CollectionIndexUsageTrackerTest, IndexKey) {
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
+ CollectionIndexUsageMap statsMap = getTracker()->getUsageStats();
+ ASSERT(statsMap.find("foo") != statsMap.end());
+ ASSERT_EQUALS(BSON("foo" << 1), statsMap["foo"].indexKey);
+}
+
// Test that index registration generates an entry in the stats map.
TEST_F(CollectionIndexUsageTrackerTest, Register) {
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
ASSERT_EQUALS(1U, getTracker()->getUsageStats().size());
- getTracker()->registerIndex("bar");
+ getTracker()->registerIndex("bar", BSON("bar" << 1));
ASSERT_EQUALS(2U, getTracker()->getUsageStats().size());
}
// Test that index deregistration results in removal of an entry from the stats map.
TEST_F(CollectionIndexUsageTrackerTest, Deregister) {
- getTracker()->registerIndex("foo");
- getTracker()->registerIndex("bar");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
+ getTracker()->registerIndex("bar", BSON("bar" << 1));
ASSERT_EQUALS(2U, getTracker()->getUsageStats().size());
getTracker()->unregisterIndex("foo");
ASSERT_EQUALS(1U, getTracker()->getUsageStats().size());
@@ -103,7 +111,7 @@ TEST_F(CollectionIndexUsageTrackerTest, Deregister) {
// Test that index deregistration results in reset of the usage counter.
TEST_F(CollectionIndexUsageTrackerTest, HitAfterDeregister) {
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
getTracker()->recordIndexAccess("foo");
getTracker()->recordIndexAccess("foo");
CollectionIndexUsageMap statsMap = getTracker()->getUsageStats();
@@ -114,7 +122,7 @@ TEST_F(CollectionIndexUsageTrackerTest, HitAfterDeregister) {
statsMap = getTracker()->getUsageStats();
ASSERT(statsMap.find("foo") == statsMap.end());
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
getTracker()->recordIndexAccess("foo");
statsMap = getTracker()->getUsageStats();
ASSERT(statsMap.find("foo") != statsMap.end());
@@ -123,7 +131,7 @@ TEST_F(CollectionIndexUsageTrackerTest, HitAfterDeregister) {
// Test that index tracker start date/time is reset on index deregistration/registration.
TEST_F(CollectionIndexUsageTrackerTest, DateTimeAfterDeregister) {
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
CollectionIndexUsageMap statsMap = getTracker()->getUsageStats();
ASSERT(statsMap.find("foo") != statsMap.end());
ASSERT_EQUALS(statsMap["foo"].trackerStartTime, getClockSource()->now());
@@ -135,7 +143,7 @@ TEST_F(CollectionIndexUsageTrackerTest, DateTimeAfterDeregister) {
// Increment clock source so that a new index registration has different start time.
getClockSource()->advance(stdx::chrono::milliseconds(1));
- getTracker()->registerIndex("foo");
+ getTracker()->registerIndex("foo", BSON("foo" << 1));
statsMap = getTracker()->getUsageStats();
ASSERT(statsMap.find("foo") != statsMap.end());
ASSERT_EQUALS(statsMap["foo"].trackerStartTime, getClockSource()->now());
diff --git a/src/mongo/db/pipeline/document_source_index_stats.cpp b/src/mongo/db/pipeline/document_source_index_stats.cpp
index 65edfaea37d..517a781a71b 100644
--- a/src/mongo/db/pipeline/document_source_index_stats.cpp
+++ b/src/mongo/db/pipeline/document_source_index_stats.cpp
@@ -52,6 +52,7 @@ boost::optional<Document> DocumentSourceIndexStats::getNext() {
const auto& stats = _indexStatsIter->second;
MutableDocument doc;
doc["name"] = Value(_indexStatsIter->first);
+ doc["key"] = Value(stats.indexKey);
doc["host"] = Value(_processName);
doc["accesses"]["ops"] = Value(stats.accesses.loadRelaxed());
doc["accesses"]["since"] = Value(stats.trackerStartTime);