dbStats
- dataSize,未压缩数据的大小的,数据的逻辑大小,删除文档会变化,为各 collection stats.size 的累加
- storageSize,block manger实际分配的空间大小(文件大小),删除文档不会发生变化,compact 会,使用压缩后,可能会比 dataSize 小,为各 collection stats.storageSize 的累加
- indexSize,类似于 storageSize,但是反馈的是所有索引表通过 BM 分配的的大小
- fsUsedSize,文件系统当前实际使用空间
- fsTotalSize,文件系统总容量,上面两个值都是通过boost::filesystem::space拿到值,如果共有同一个文件系统,和具体的 Database 没有关联
// src/mongo/db/catalog/database_impl.cpp:284
if (!opCtx->getServiceContext()->getStorageEngine()->isEphemeral()) {
boost::filesystem::path dbpath(
opCtx->getServiceContext()->getStorageEngine()->getFilesystemPathForDb(_name));
boost::system::error_code ec;
boost::filesystem::space_info spaceInfo = boost::filesystem::space(dbpath, ec);
if (!ec) {
output->appendNumber("fsUsedSize", (spaceInfo.capacity - spaceInfo.available) / scale);
output->appendNumber("fsTotalSize", spaceInfo.capacity / scale);
} else {
output->appendNumber("fsUsedSize", -1);
output->appendNumber("fsTotalSize", -1);
log() << "Failed to query filesystem disk stats (code: " << ec.value()
<< "): " << ec.message();
}
}
collStats
- size, collection 中所有document 的未压缩大小
- storageSize,collection 文件大小
- wiredTiger."block-manager"."file size in bytes",等于storageSize
- wiredTiger."block-manager"."file bytes available for reuse",collection 文件可重用的空间大小
- totalIndexSize,collection 上所有索引对应的wt表文件的大小
- indexSizes,Object,分别列出了各个索引的文件大小
- indexDetails.index_name."block-manager"."file size in bytes",类似于 collection,反映的是索引表的文件大小
- indexDetails.index_name."block-manager"."file bytes available for reuse",类似于 collection,反映的是索引表可重用空间大小
- 所以要计算单个 collection(含索引)的磁盘空间碎片率,计算脚本,
function getCollectionDiskSpaceFragRatio(dbname, coll) {
var res = db.getSiblingDB(dbname).runCommand({
collStats: coll
});
var totalStorageUnusedSize = 0;
var totalStorageSize = res['storageSize'] + res['totalIndexSize'];
Object.keys(res.indexDetails).forEach(function(key) {
var size = res['indexDetails'][key]['block-manager']['file bytes available for reuse'];
print("index table " + key + " unused size: " + size);
totalStorageUnusedSize += size;
});
var size = res['wiredTiger']['block-manager']['file bytes available for reuse'];
print("collection table " + coll + " unused size: " + size);
totalStorageUnusedSize += size;
print("collection and index table total unused size: " + totalStorageUnusedSize);
print("collection and index table total file size: " + totalStorageSize);
print("Fragmentation ratio: " + ((totalStorageUnusedSize * 100.0) / totalStorageSize).toFixed(2) + "%");
}
一次查看 db 下的所有 collection 碎片率,
use xxxdb
db.getCollectionNames().forEach((c) => {print("\n\n" + c); getCollectionDiskSpaceFragRatio(db.getName(), c);});
compact
如果碎片率过高,我们需要做 compact,MongoDB 本身提供了 compact 命令,关于 compact 命令的使用和原理,可以参考团队另外一位同学文章:https://developer.aliyun.com/article/709526
如果是 Sharding 实例,需要执行 compact 命令,请按如下方式执行命令:
https://developer.aliyun.com/article/328761
最后,打一个小广告,阿里云 MongoDB 目前上线了 Serverless 版本,让您方便的以超低成本试用 MongoDB,活动期间首购 1 元包月,续费也有 5 折优惠,欢迎试用:https://www.aliyun.com/product/mongodb 。