MongoDB的碎片化问题

太阳2年前技术文章869

一、碎片化问题

1.1 为什么会出现碎片化的问题

在生产业务中,一般会对集合数据进行频繁的增删改,常见的碎片化原因有:

1、记录被remove,但是其空间没有被复用

drop命令会直接删除集合的物理文件,空间立即被回收;但是remove命令删除文档记录后,其文件物理空间不会被回收

2、记录update,记录实际占用变小,但是空间没有被复用

1.2 如何处理碎片化问题

1、compact命令

1)业务低峰期,在secondary节点执行compact命令;

2)将已经compact完毕的secondary节点提升为primary节点;

3)对降级为secodary的节点做compact。

2、重建collection

     3、新添加一个secondary节点,然后将该节点升级为primary节点(数据量非常大的情况下为了不影响业务)

二、compact命令

2.1 语法

db.runCommand({compact:'dsir',force:true})		//若在primary节点执行,需要指定force:true

2.2 compact所需权限

use admin
db.createRole(
   {
      role: "myCustomCompactRole",
      privileges: [
         {
            resource: { "db" : "<database>" , "collection" : "<collection>" },
            actions: [ "compact" ]
         }
      ],
      roles: []
   }
)

db.grantRoleToUser("myCompactUser", [ "dbAdmin" | "myCustomCompactRole" ] )

2.3 compact注意点

1、compact主要做了哪些操作

1)检查所操作compact集合是否满足条件

1)前面80%的空间里,是否有20%的空闲空间,用于写入文件后面20%的数据
2)前面90%的空间里,是否有10%的空闲空间,用于写入文件后面10%的数据

2)若满足任一条件,引擎层开始执行compact,执行期间阻塞该DB上左右读写操作,并将该集合文件后面的数据往前面空闲的空间写,然后逐步 truancate 文件回收物理空间。

3)若不满足以上任一条件,说明执行compact肯定无法回收10%的物理空间,那么该集合当前无需进行compact,直接退出compact操作。

2、compact的特点(影响)

1)compact 一个集合,会加集合所在DB的互斥写锁,会导致该DB上所有的读写请求都阻塞;而且 compact 执行的时间跟集合的数据量相关,数据量越大compact执行时间越久,所以强烈建议在业务低峰期执行,避免影响业务。

2)如果您使用db.killOp()方法终止操作,或者在压缩操作完成之前重启服务器,请注意以下事项:

1.如果启用了日志记录,无论压缩操作的状态如何,数据都将保持有效和可用。您可能必须手动重新构建索引。
2.如果没有启用日志记录,当compact操作被中断时,无法保证数据有效性
3.在这两种情况下,集合中现有的大部分空闲空间都可能无法重用。需要重新执行compact恢复对空间空间的使用。

3)compact操作在每个节点都是独立的,不会随着primary节点的操作传递到secondary节点;

4)如果想要在primary节点执行conpact操作,需要标识force:true;

5)在secondary节点执行compact操作时,该节点的状态会转换为RECOVERING,期间业务无法访问该节点;

3、各引擎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 查看数据库存储空间占用

use db
db.stats()

use db
db.runCommand({dbStats : 1,scale : 1073741824})   //scale指定单位为GB

3.2 查看集合存储空间占用

use db
db.collbame.stats()

use db
db.runCommand({"collStats":"oplog.rs",scale:1048576})  //scale指定单位,单位为MB


相关文章

C++ 编程:程序组成部分 & 函数 & 输入

C++ 编程:程序组成部分 & 函数 & 输入

程序结构首先从一个最简单的程序来看 C++ 程序结构:第一部分:#include <iostream> 专业名词叫:预处理器编译指令 其实效果就类似于导包; 第二部分:main() 程序的...

Linux系统调优参数应用实践

Linux系统调优参数应用实践

1 基于内存方面的性能参数调优1.1 cache与buffer解读1.1.1 cache出现的原因与功能计算机硬件中CPU、内存、磁盘是最主要的三大部分,其中,CPU发展到今天,执行速度最快,而内存相...

大数据基础之HDFS入门

大数据基础之HDFS入门

一、NameNode是整个文件系统的管理节点。它维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表。二、NameNode的工作特点Namenode始终在内存中保存meteda...

scylladb通过扩缩容节点迁移数据

环境: Scyllsdb版本:4.2一、上线新节点1、确认集群状态和检查配置· 首先确认集群各节点状态是Up Normal (UN),[root@172-16-121-153 scylla]# nod...

数据湖技术之iceberg(八)Spark与Iceberg整合DDL操作

数据湖技术之iceberg(八)Spark与Iceberg整合DDL操作

1.CREATE TABLE 创建表Create table 创建Iceberg表,创建表不仅可以创建普通表还可以创建分区表,再向分区表中插入一批数据时,必须对数据中分区列进行排序,否则会出现文件关闭...

ACOS-可观测运维套件

ACOS-可观测运维套件

一、背景随着企业分布式应用、云计算的不断深入发展,业务系统的逻辑结构变得越来越复杂,面对企业运维复杂的环境和海量运维数据,在日常运维和生产运营中,会面临以下挑战:(1)多云,多系统,多服务,多数据的中...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。