diff options
author | Daniel Ernst <daniel.ernst@mongodb.com> | 2020-01-10 15:18:58 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2020-01-10 15:18:58 +0000 |
commit | 989d23805572e6db103b64f3de76ffa7359a00cd (patch) | |
tree | b86621f6eff35ae806980340adae5c167f4d8247 | |
parent | 8261ac76bdd469bd937c061f6ec4fb213b1298f0 (diff) | |
download | mongo-989d23805572e6db103b64f3de76ffa7359a00cd.tar.gz |
SERVER-42037 Add freeListSize collection stat with scale support
-rw-r--r-- | jstests/noPassthroughWithMongod/free_storage_size.js | 43 | ||||
-rw-r--r-- | src/mongo/db/stats/storage_stats.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/storage/record_store.h | 9 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h | 2 |
5 files changed, 71 insertions, 0 deletions
diff --git a/jstests/noPassthroughWithMongod/free_storage_size.js b/jstests/noPassthroughWithMongod/free_storage_size.js new file mode 100644 index 00000000000..7526e91ea04 --- /dev/null +++ b/jstests/noPassthroughWithMongod/free_storage_size.js @@ -0,0 +1,43 @@ +/** + * Tests that db.collection.stats().freeStorageSize is a non-zero value after records are + * inserted and then some deleted. + * + * @tags: [ + * # freeStorageSize is currently only supported by WT. + * requires_wiredtiger + * ] + */ + +(function() { +"use strict"; + +const forceCheckpoint = () => { + assert.commandWorked(db.fsyncLock()); + assert.commandWorked(db.fsyncUnlock()); +}; + +const dbName = "freeStorageSizeTest"; +const collName = "foo"; +const testDB = db.getSiblingDB(dbName); +const coll = testDB.getCollection(collName); + +const kDocsToInsert = 150; +const kDocsToRemove = kDocsToInsert / 2; + +// Insert docs. +for (let i = 0; i < kDocsToInsert; i++) { + assert.commandWorked(coll.insert({a: i})); +} + +forceCheckpoint(); + +// Remove docs to free up space. +assert.commandWorked(coll.remove({a: {$lt: kDocsToRemove}})); + +forceCheckpoint(); + +// Check that freeStorageSize is non-zero. +let collStats = assert.commandWorked(testDB.runCommand({collStats: collName})); +assert(collStats.hasOwnProperty("freeStorageSize"), tojson(collStats)); +assert.gt(collStats.freeStorageSize, 0); +})(); diff --git a/src/mongo/db/stats/storage_stats.cpp b/src/mongo/db/stats/storage_stats.cpp index 63e5540fdaf..dff609e2afa 100644 --- a/src/mongo/db/stats/storage_stats.cpp +++ b/src/mongo/db/stats/storage_stats.cpp @@ -85,6 +85,11 @@ Status appendCollectionStorageStats(OperationContext* opCtx, static_cast<long long>(recordStore->storageSize(opCtx, result, verbose ? 1 : 0)); result->appendNumber("storageSize", storageSize / scale); + auto freeStorageSize = static_cast<long long>(recordStore->freeStorageSize(opCtx)); + if (freeStorageSize != 0) { + result->appendNumber("freeStorageSize", freeStorageSize / scale); + } + recordStore->appendCustomStats(opCtx, result, scale); IndexCatalog* indexCatalog = collection->getIndexCatalog(); diff --git a/src/mongo/db/storage/record_store.h b/src/mongo/db/storage/record_store.h index 5bf95d6cb36..e549507f5a7 100644 --- a/src/mongo/db/storage/record_store.h +++ b/src/mongo/db/storage/record_store.h @@ -254,6 +254,15 @@ public: BSONObjBuilder* extraInfo = nullptr, int infoLevel = 0) const = 0; + /** + * @return file bytes available for reuse + * A return value of zero can mean either no bytes are available, or that the real value is + * unknown. + */ + virtual int64_t freeStorageSize(OperationContext* opCtx) const { + return 0; + } + // CRUD related /** diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp index e1d49b5a2ce..6388ef65ead 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp @@ -872,6 +872,18 @@ int64_t WiredTigerRecordStore::storageSize(OperationContext* opCtx, return size; } +int64_t WiredTigerRecordStore::freeStorageSize(OperationContext* opCtx) const { + invariant(opCtx->lockState()->isReadLocked()); + + WiredTigerSession* session = WiredTigerRecoveryUnit::get(opCtx)->getSessionNoTxn(); + auto result = WiredTigerUtil::getStatisticsValue(session->getSession(), + "statistics:" + getURI(), + "statistics=(fast)", + WT_STAT_DSRC_BLOCK_REUSE_BYTES); + uassertStatusOK(result.getStatus()); + return result.getValue(); +} + // Retrieve the value from a positioned cursor. RecordData WiredTigerRecordStore::_getData(const WiredTigerCursor& cursor) const { WT_ITEM value; diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h index 30985dcd465..a7f67537583 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h @@ -137,6 +137,8 @@ public: BSONObjBuilder* extraInfo = nullptr, int infoLevel = 0) const; + virtual int64_t freeStorageSize(OperationContext* opCtx) const; + // CRUD related virtual bool findRecord(OperationContext* opCtx, const RecordId& id, RecordData* out) const; |