diff options
author | Daniel Gómez Ferro <daniel.gomezferro@mongodb.com> | 2021-11-30 09:10:05 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-30 09:51:03 +0000 |
commit | d77aec3d56a3ec9be56fb71982729589588a131e (patch) | |
tree | 361d5ce22f117b7da38660dda3b84df28177471e /src/mongo/db | |
parent | fcd1982137ce70e65efd6a7f04b6360e0552fdc6 (diff) | |
download | mongo-d77aec3d56a3ec9be56fb71982729589588a131e.tar.gz |
SERVER-58476 Add `numericOnly' option to collStats, use it for FTDC
Diffstat (limited to 'src/mongo/db')
10 files changed, 94 insertions, 29 deletions
diff --git a/src/mongo/db/ftdc/ftdc_mongod.cpp b/src/mongo/db/ftdc/ftdc_mongod.cpp index abe40e9a081..5f2a874d3e7 100644 --- a/src/mongo/db/ftdc/ftdc_mongod.cpp +++ b/src/mongo/db/ftdc/ftdc_mongod.cpp @@ -60,7 +60,8 @@ void registerMongoDCollectors(FTDCController* controller) { "local", BSON("collStats" << "oplog.rs" - << "waitForLock" << false))); + << "waitForLock" << false + << "numericOnly" << true))); if (serverGlobalParams.clusterRole != ClusterRole::ShardServer) { // GetDefaultRWConcern controller->addOnRotateCollector(std::make_unique<FTDCSimpleInternalCommandCollector>( diff --git a/src/mongo/db/pipeline/storage_stats_spec.idl b/src/mongo/db/pipeline/storage_stats_spec.idl index 74c6775673c..8052f09de51 100644 --- a/src/mongo/db/pipeline/storage_stats_spec.idl +++ b/src/mongo/db/pipeline/storage_stats_spec.idl @@ -48,3 +48,6 @@ structs: waitForLock: type: optionalBool default: true + numericOnly: + type: optionalBool + default: false diff --git a/src/mongo/db/stats/storage_stats.cpp b/src/mongo/db/stats/storage_stats.cpp index a2253d49706..7bf30e0cd3d 100644 --- a/src/mongo/db/stats/storage_stats.cpp +++ b/src/mongo/db/stats/storage_stats.cpp @@ -53,6 +53,7 @@ Status appendCollectionStorageStats(OperationContext* opCtx, auto scale = storageStatsSpec.getScale().value_or(1); bool verbose = storageStatsSpec.getVerbose(); bool waitForLock = storageStatsSpec.getWaitForLock(); + bool numericOnly = storageStatsSpec.getNumericOnly(); const auto bucketNss = nss.makeTimeseriesBucketsNamespace(); const auto isTimeseries = nss.isTimeseriesBucketsCollection() || @@ -122,7 +123,11 @@ Status appendCollectionStorageStats(OperationContext* opCtx, result->appendNumber("maxSize", collection->getCappedMaxSize() / scale); } - recordStore->appendCustomStats(opCtx, result, scale); + if (numericOnly) { + recordStore->appendNumericCustomStats(opCtx, result, scale); + } else { + recordStore->appendAllCustomStats(opCtx, result, scale); + } const IndexCatalog* indexCatalog = collection->getIndexCatalog(); result->append("nindexes", indexCatalog->numIndexesTotal(opCtx)); diff --git a/src/mongo/db/storage/devnull/devnull_kv_engine.cpp b/src/mongo/db/storage/devnull/devnull_kv_engine.cpp index b244ce0ebb1..982a1a8e318 100644 --- a/src/mongo/db/storage/devnull/devnull_kv_engine.cpp +++ b/src/mongo/db/storage/devnull/devnull_kv_engine.cpp @@ -145,9 +145,9 @@ public: virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive) {} - virtual void appendCustomStats(OperationContext* opCtx, - BSONObjBuilder* result, - double scale) const { + virtual void appendNumericCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const { result->appendNumber("numInserts", _numInserts); } diff --git a/src/mongo/db/storage/devnull/ephemeral_catalog_record_store.h b/src/mongo/db/storage/devnull/ephemeral_catalog_record_store.h index 5170412252f..536d4b8d9c8 100644 --- a/src/mongo/db/storage/devnull/ephemeral_catalog_record_store.h +++ b/src/mongo/db/storage/devnull/ephemeral_catalog_record_store.h @@ -90,9 +90,9 @@ public: virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive); - virtual void appendCustomStats(OperationContext* opCtx, - BSONObjBuilder* result, - double scale) const {} + virtual void appendNumericCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const {} virtual int64_t storageSize(OperationContext* opCtx, BSONObjBuilder* extraInfo = nullptr, diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store.h b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store.h index a000617d1fe..18a438303f5 100644 --- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store.h +++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store.h @@ -96,9 +96,9 @@ public: virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive); - virtual void appendCustomStats(OperationContext* opCtx, - BSONObjBuilder* result, - double scale) const {} + virtual void appendNumericCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const {} virtual void updateStatsAfterRepair(OperationContext* opCtx, long long numRecords, diff --git a/src/mongo/db/storage/record_store.h b/src/mongo/db/storage/record_store.h index bd5ad8ebd8f..77a6d6e2782 100644 --- a/src/mongo/db/storage/record_store.h +++ b/src/mongo/db/storage/record_store.h @@ -491,11 +491,24 @@ public: /** * @param scaleSize - amount by which to scale size metrics - * appends any custom stats from the RecordStore or other unique stats + * Appends any numeric custom stats from the RecordStore or other unique stats, it should + * avoid any expensive calls */ - virtual void appendCustomStats(OperationContext* opCtx, - BSONObjBuilder* result, - double scale) const = 0; + virtual void appendNumericCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const = 0; + + + /** + * @param scaleSize - amount by which to scale size metrics + * Appends all custom stats from the RecordStore or other unique stats, it can be more + * expensive than RecordStore::appendNumericCustomStats + */ + virtual void appendAllCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const { + appendNumericCustomStats(opCtx, result, scale); + }; /** * When we write to an oplog, we call this so that that the storage engine can manage the diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp index cb0837ddd01..566745b8223 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp @@ -113,6 +113,16 @@ void checkOplogFormatVersion(OperationContext* opCtx, const std::string& uri) { fassertNoTrace(39998, appMetadata.getValue().getIntField("oplogKeyExtractionVersion") == 1); } + +void appendNumericStats(WT_SESSION* s, const std::string& uri, BSONObjBuilder& bob) { + Status status = + WiredTigerUtil::exportTableToBSON(s, "statistics:" + uri, "statistics=(fast)", &bob); + if (!status.isOK()) { + bob.append("error", "unable to retrieve statistics"); + bob.append("code", static_cast<int>(status.code())); + bob.append("reason", status.reason()); + } +} } // namespace MONGO_FAIL_POINT_DEFINE(WTCompactRecordStoreEBUSY); @@ -1679,9 +1689,20 @@ void WiredTigerRecordStore::validate(OperationContext* opCtx, results->valid = false; } -void WiredTigerRecordStore::appendCustomStats(OperationContext* opCtx, - BSONObjBuilder* result, - double scale) const { +void WiredTigerRecordStore::appendNumericCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const { + WiredTigerSession* session = WiredTigerRecoveryUnit::get(opCtx)->getSessionNoTxn(); + WT_SESSION* s = session->getSession(); + + BSONObjBuilder bob(result->subobjStart(_engineName)); + + appendNumericStats(s, getURI(), bob); +} + +void WiredTigerRecordStore::appendAllCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const { WiredTigerSession* session = WiredTigerRecoveryUnit::get(opCtx)->getSessionNoTxn(); WT_SESSION* s = session->getSession(); BSONObjBuilder bob(result->subobjStart(_engineName)); @@ -1710,13 +1731,7 @@ void WiredTigerRecordStore::appendCustomStats(OperationContext* opCtx, bob.append("type", type); } - Status status = - WiredTigerUtil::exportTableToBSON(s, "statistics:" + getURI(), "statistics=(fast)", &bob); - if (!status.isOK()) { - bob.append("error", "unable to retrieve statistics"); - bob.append("code", static_cast<int>(status.code())); - bob.append("reason", status.reason()); - } + appendNumericStats(s, getURI(), bob); } void WiredTigerRecordStore::waitForAllEarlierOplogWritesToBeVisibleImpl( diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h index 95d6b6635fa..821cda6bf3a 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h @@ -188,9 +188,13 @@ public: ValidateResults* results, BSONObjBuilder* output); - virtual void appendCustomStats(OperationContext* opCtx, - BSONObjBuilder* result, - double scale) const; + virtual void appendNumericCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const; + + virtual void appendAllCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const; virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp index 3fbf34025b8..7ccc4e7eb64 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test.cpp @@ -315,7 +315,7 @@ TEST(WiredTigerRecordStoreTest, AppendCustomStatsMetadata) { ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); BSONObjBuilder builder; - rs->appendCustomStats(opCtx.get(), &builder, 1.0); + rs->appendAllCustomStats(opCtx.get(), &builder, 1.0); BSONObj customStats = builder.obj(); BSONElement wiredTigerElement = customStats.getField(kWiredTigerEngineName); @@ -333,6 +333,30 @@ TEST(WiredTigerRecordStoreTest, AppendCustomStatsMetadata) { ASSERT_EQUALS(creationStringElement.type(), String); } +TEST(WiredTigerRecordStoreTest, AppendCustomNumericStats) { + std::unique_ptr<RecordStoreHarnessHelper> harnessHelper = newRecordStoreHarnessHelper(); + unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore("a.c")); + + ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); + BSONObjBuilder builder; + rs->appendNumericCustomStats(opCtx.get(), &builder, 1.0); + BSONObj customStats = builder.obj(); + + BSONElement wiredTigerElement = customStats.getField(kWiredTigerEngineName); + ASSERT_TRUE(wiredTigerElement.isABSONObj()); + BSONObj wiredTiger = wiredTigerElement.Obj(); + + ASSERT_FALSE(wiredTiger.hasField("metadata")); + ASSERT_FALSE(wiredTiger.hasField("creationString")); + + BSONElement cacheElement = wiredTiger.getField("cache"); + ASSERT_TRUE(cacheElement.isABSONObj()); + BSONObj cache = cacheElement.Obj(); + + BSONElement bytesElement = cache.getField("bytes currently in the cache"); + ASSERT_TRUE(bytesElement.isNumber()); +} + BSONObj makeBSONObjWithSize(const Timestamp& opTime, int size, char fill = 'x') { BSONObj objTemplate = BSON("ts" << opTime << "str" << ""); |