mongoDB释放磁盘占用

今天op说mongo空间满了,然后有了接下来的解决方案:

推荐第二种


在mongo中删除数据并不会直接释放磁盘,而是产生很多碎片。这些碎片会被mongo继续利用。当有新数据插入时,会重复利用这些碎片,而不需要新申请磁盘空间。

但是这会导致的问题是,磁盘可能一直处于高水位的使用水平,对运维来说是一个定时炸弹。因为碎片只会被所属的库使用,但我们经常会新建很多库,这就导致磁盘越来越紧张。

目前我摸索出的是三种方法

1,将备节点清空,重新同步。

在备节点同步的过程中,碎片空间会被整理。备节点同步过去的是完全的数据和索引。

之后再进行一次主备切换。

使备节点成为主节点。

再将主节点数据清空,同步一次。

最终使主备都达到释放碎片的目的。

优点:服务一直可用

缺点:动作过大。要保证同步过程在同步窗口之内。建议将oplog尽量设置大一点

2,使用compact命令

compact是mongo中的压缩命令。可以整理删除数据产生的碎片。

在WiredTiger 数据库引擎下,该命令会将整理出的空间释放给操作系统。

在MMAPv1引擎下,compact会整理碎片,重建索引,但不会将未使用的空间释放给系统,后续新插入的数据依然可以使用这些空间

命令:

进入要执行的数据库

db.runCommand({ compact: <collection name>,force:<boolen> } )

对主备节点分别执行一次该命令

在复制集模式下的一些注意:

该命令会阻塞运行该命令的库,一定要选择好执行的时间

compact命令不会自动复制到secondary节点执行,compact在每个节点成员中都是独立的,在Primary,secondary中执行时都要使用force参数,

当在secondary的collection上执行compact命令时,此secondary节点会变成RECOVERING状态,且无法提供读操作

在capped collection中不必使用compact命令,因为它本身就是固定空间

实验:

当前库占了大约5.8G的磁盘

然后我删除了部分数据

shard1:PRIMARY> db.runCommand({ compact: "fs.files"} )

{

"ok" : 0,

"errmsg" : "will not run compact on an active replica set primary as this is a slow blocking operation. use force:true to force"

}

shard1:PRIMARY> db.runCommand({ compact: "fs.files",force:true} )

这里会卡很久,数据库操作会被锁住

实践证明:能够压缩一些,但并不能达到数据实际的磁盘占用量

3,做repairDatabase

这个命令我没有尝试,谨慎使用。

做repairDatabase要求剩余磁盘要足够大。

但是当我的磁盘告警时,已经不会有足够的磁盘做repairDatabase了

db.runCommand({repairDatabase:1})

注:这个命令一定要谨慎使用,能不用的情况下尽量不用,因为会花费很多时间和性能

官网的一句话是这样说的:

The repairDatabase command compacts all collections in the database. It is identical to running the compact command on each collection individually

不建议直接repairDatabase,不如对需要做压缩的集合进行compact


 


1 背景描述

使用 MongoDB 数据灌满之后,发现空间不够建立索引,于是使用 db.collections.remove() 删除掉一部分数据。

但是删除结束,数据的条数变少了,但是磁盘空间却没有被腾出来。

2 解决问题

使用 compact 命令压缩集合及其索引:

> use test
switched to db test
> show collections
people
system.profile
> db.runCommand({compact:"people"}) # 未指定 force, 报错
{
    "ok" : 0,
    "errmsg" : "will not run compact on an active replica set primary as this is a slow blocking operation. use force:true to force"
}
> db.runCommand({compact:"people", force:true}) # 指定 force, 执行成功
{ "ok" : 1 }

compact优点:
1. compact 只压缩需要的 collection,压缩期间产生的临时文件会就相对较少,对磁盘剩余空间需求较小;
2. compact 去除 collection 所在文件的碎片,其重建索引的 cost 也变小了,对内存的需求也减少;

compact注意点:
1. compact 操作是不会释放磁盘空间的,而是把释放的空间继续给 MongoDB 使用;
2. compact 操作进行时会产生对应的锁,使用 mongostat 可以查看,所以该操作最好在业务量最少下进行;
3. 限制集合 {Capped Collection} 是不需要 compact 的

猜你喜欢

转载自blog.csdn.net/qq_32907195/article/details/112529872