前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MongoDB 文档被delete后,如何回收磁盘空间?

MongoDB 文档被delete后,如何回收磁盘空间?

原创
作者头像
贺春旸的技术博客
发布2024-07-18 15:18:27
1050
发布2024-07-18 15:18:27
举报
文章被收录于专栏:DBA 平台和工具

在回答这个问题之前,先了解一下 MySQL InnoDB 存储引擎是如何回收磁盘空间的。

假设有一张表包含 1000 万条记录,删除其中的 800 万条记录,此时 InnoDB 的磁盘空间不会自动释放。要回收磁盘空间,需要执行以下命令:

代码语言:sql
复制
ALTER TABLE tableName ENGINE=InnoDB;

MongoDB 的 WiredTiger 存储引擎也有类似的行为。要回收磁盘空间,可以执行以下命令:

代码语言:javascript
复制
use dbName
// 在副本集 primary 上执行需要加 force 选项
db.runCommand({compact: "collectionName", force: true})

下面通过一个测试用例来实际演示这一过程。

首先,插入 100 万条随机生日数据到 MongoDB 的 demo 集合中。

代码语言:javascript
复制
function getRandomDate() {
    const start = new Date(1950, 0, 1);
    const end = new Date(2005, 11, 31);
    return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}

for (var i = 1; i <= 1000000; i++) {
    db.demo.insert({
        name: "name" + i,
        birthday: getRandomDate()
    });
    if (i % 10000 === 0) {
        print(`Inserted ${i} records`);
    }
}

print("Insertion complete");

接下来,删除所有生日在 1980 年 1 月 1 日之前的记录。

代码语言:javascript
复制
db.demo.count({ birthday: { $lt: new Date("1980-01-01") } });
db.demo.deleteMany({ birthday: { $lt: new Date("1980-01-01") } });

删除操作后,检查 demo 集合可以回收的磁盘空间(单位:字节)。

代码语言:javascript
复制
db.demo.stats().wiredTiger["block-manager"]["file bytes available for reuse"];

最后,执行磁盘空间回收操作。

代码语言:javascript
复制
// 在副本集 primary 上执行需要加 force 选项
db.runCommand({compact: "demo", force: true});

需要注意的是,在 MongoDB 4.4 版本之前,compact 操作会阻塞 CRUD 操作。而在 MongoDB 4.4 及更新的版本中,compact 操作不会阻塞 CRUD 操作,但会阻塞元数据操作,例如删除集合、删除索引和创建新索引。

最后附上统计库里每个集合可回收的空间(GB)脚本

代码语言:javascript
复制
// 使用指定的数据库
use yourDB

// 定义常量
var bytesInGB = 1024 * 1024 * 1024;

// 获取所有集合名称
var cols = db.getCollectionNames();

// 创建一个对象来存储每个集合的可回收空间
var collectionSpace = {};

// 计算总可回收空间
var totalReclaimableSpace = 0;

// 遍历每个集合
cols.forEach(function(col) {
    if(col != 'system.profile') {
        var stats = db[col].stats();
        var reclaimableSpace = stats.wiredTiger["block-manager"]["file bytes available for reuse"];
        
        // 将字节转换为GB并保留两位小数
        var spaceInGB = (reclaimableSpace / bytesInGB).toFixed(2);
        
        // 存储每个集合的可回收空间
        collectionSpace[col] = spaceInGB;
        
        // 累加总可回收空间
        totalReclaimableSpace += reclaimableSpace;
    }
});

// 打印每个集合的可回收空间
print("每个集合可回收的空间(GB):");
for (var col in collectionSpace) {
    print("集合:" + col + " -> 可回收空间(GB): " + collectionSpace[col]);
}

// 打印总可回收空间
print("\n总共可回收空间(GB): " + (totalReclaimableSpace / bytesInGB).toFixed(2));

参考文献:

https://www.percona.com/blog/using-compact-in-percona-server-for-mongodb-from-version-4-4/

https://www.percona.com/blog/how-to-reclaim-disk-space-in-percona-server-for-mongodb/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档