文章目录
- 一、如何判断碎片化
- 二、如何处理碎片化
- 2.1 compact
- 2.2 各存储引擎下compact如何释放空间
- 三、常见处理碎片化方案
- 3.1 直接操作
- 3.2 重建collection
- 3.3 单节点启动方式循环处理
一、如何判断碎片化
1、数据库空间占用信息查询
1)查看数据库存储空间占用
-- 通过db.stats()函数查询storageSize参数大小
use db
db.stats()
-- 直接查看目标DB物理存储大小
use db
db.runCommand({dbStats : 1,scale : 1073741824}) //scale指定单位为GB
2)查看集合存储空间占用
-- 通过db.collname.stats()函数查询storageSize参数大小
use db
db.collname.stats()
-- 直接查看目标DB物理存储大小
use db
db.runCommand({"collStats":"oplog.rs",scale:1048576}) //scale指定单位,单位为MB
2、碎片化问题查看,查看目前集合可回收空间
db.collname.stats().wiredTiger["block-manager"]["file bytes available for reuse"]
rs0:PRIMARY> db.aa.stats().wiredTiger["block-manager"]["file bytes available for reuse"]
16384
二、如何处理碎片化
2.1 compact
1、语法
db.runCommand({compact:'dsir',force:true})
2、compact所需权限
use admin
db.createRole(
{
role: "myCustomCompactRole",
privileges: [
{
resource: { "db" : "<database>" , "collection" : "<collection>" },
actions: [ "compact" ]
}
],
roles: []
}
)
db.grantRoleToUser("myCompactUser", [ "dbAdmin" | "myCustomCompactRole" ] )
3、compact主要做了哪些操作?
1)检查所操作compact集合是否满足条件
- 前面80%的空间里,是否有20%的空闲空间,用于写入文件后面20%的数据
- 前面90%的空间里,是否有10%的空闲空间,用于写入文件后面10%的数据
2)若满足任一条件,引擎层开始执行compact,执行期间阻塞该DB上左右读写操作,并将该集合文件后面的数据往前面空闲的空间写,然后逐步 truancate 文件回收物理空间。
3)若不满足以上任一条件,说明执行compact肯定无法回收10%的物理空间,那么该集合当前无需进行compact,直接退出compact操作。
4、compact的影响
1)compact 一个集合,会加集合所在DB的互斥写锁,会导致该DB上所有的读写请求都阻塞;而且 compact 执行的时间跟集合的数据量相关,数据量越大compact执行时间越久,所以强烈建议在业务低峰期执行,避免影响业务。
2)如果您使用db.killOp()方法终止操作,或者在压缩操作完成之前重启服务器,请注意以下事项:
- 如果启用了日志记录,无论压缩操作的状态如何,数据都将保持有效和可用。您可能必须手动重新构建索引。
- 如果没有启用日志记录,当compact操作被中断时,无法保证数据有效性
- 在这两种情况下,集合中现有的大部分空闲空间都可能无法重用。需要重新执行compact恢复对空间空间的使用。
3)compact操作在每个节点都是独立的,不会随着primary节点的操作传递到secondary节点;
4)如果想要在primary节点执行conpact操作,需要标识force:true;
5)在secondary节点执行compact操作时,该节点的状态会转换为RECOVERING,期间业务无法访问该节点;
2.2 各存储引擎下compact如何释放空间
1、WiredTiger
1)compact操作会释放data和index的空间给操作系统;
2)compact执行需要额外的一部分空间。
2、MMAPv1
1)commpact操作可以减少data空间,并且重建index,但是这些空间不会归还给操作系统,只会留给MongoDB供之后的数据写入;
2)如果想要回收MMAPv1的磁盘空间,需要执行initial sync;
3)执行compact操作至少需要当前实例还有2G的空闲空间才可执行。
三、常见处理碎片化方案
3.1 直接操作
- 单节点环境下
直接进行compact操作 - 副本集环境下
1)业务低峰期,在secondary节点执行compact命令;
2)将已经compact完毕的secondary节点提升为primary节点;
3)对降级为secodary的节点做compact。
3.2 重建collection
新添加一个secondary节点,然后将该节点升级为primary节点(数据量非常大的情况下为了不影响业务)
3.3 单节点启动方式循环处理
1)将副本集中某一secondary节点以单节点方式启动,并执行compact命令处理集合碎片化
2)将碎片化处理完毕的节点重新以副本集的方式启动,会将该节点提升为primary节点
3)以1)的方式对其余secondary节点进行碎片化处理
文档参考:
https://docs.mongodb.com/manual/reference/command/compact/index.html