mongo数据丢失,mongodb误删除恢复
墨初 知识笔记 146阅读
Author:skate
Time:2023/10/22

一、问题描述
产线用户反馈一个的mongo实例磁盘空间告警使用率超过90%使用状况 1630.9/1800GB让其通过数据库运维平台找到占用大空间的表然后清理历史数据用户清理数据后发现使用的磁盘空间没有减少

二、问题分析
mongo实例信息
配置| 2 vCPUs | 4GB
版本4.0
存储引擎WiredTiger
磁盘使用率90.61%(使用状况 1630.9/1800 GB)
查看占用磁盘空间大的表
通过数据库运维平台查看如上三个表占用磁盘空间最大而且数据逻辑大小远远小于数据占用的存储空间说明数据清理产生了有大量的碎片一般来说磁盘碎片会被数据库继续使用当有新数据插入时会重复利用这些碎片。
但是我们目前碎片占用空间太大需要回收下
三、解决方案
可以通过如下命令回收集合的的磁盘碎片
db.runCommand({compact:<collection_name>,force:true})
因为MongoDB 4.4及之前的版本执行compact命令会导致集合所属的数据库被锁定且该数据库的读写操作将被阻塞建议在业务低峰期操作操作的步骤如下
1、先在备库执行compact命令
db.runCommand({compact:<collection_name>})
2、然后主备切换
3、在新的备库执行compact命令
db.runCommand({compact:<collection_name>})
A.阿里云的mongo实例说明
阿里云的mongo实例如果需要compact需要我们自己按如上步骤手工操作
B.的mongo实例特殊说明
默认的mongo实例的管理员用户rwuser默认是没有执行compact权限的如果需要执行这个命令联系工程师让工程师帮其在后台执行或者升级mongo实例的小版本向申请开通compact命令权限这个compact命令是低频的目前命令提供给执行即可。
RocksDB在删除数据后将删除操作直接转化为追加写在积攒了一定数据量的冗余数据后会自动触发后台compact线程对同一数据的多版本进行归并聚合从而释放多余的磁盘空间因此建议等待系统自动回收。当磁盘空间使用率较高接近只读状态阈值时手工操作回收
WiredTiger在删除数据进行数据多版本归并聚合后也会空余出磁盘空间碎片但wiredTiger并不会将这部分磁盘空间返还给操作系统而是打上标记预留给当前collection后续的写入此collection后续的写入会优先使用这部分预留的磁盘空间如果需要释放这部分磁盘空间可以尝试通过执行compact命令进行释放注此命令会阻塞正常业务。
具体操作步骤
1、通过数据库运维平台查看哪些集合占用磁盘空间大、碎片率高碎片率超过50%就要注意了
2、在备库执行集合压缩命令降低对主库的写操作的阻塞在业务低峰期操作
use tbm
db.runCommand({compact:zjthStdTag}) //耗时424.702s (7.08min)
db.runCommand({compact:ztzbStdTag}) //耗时379.738s (6.33min)
db.runCommand({compact:hrkStdTag}) //耗时46.857s
3、主备库倒换
4、在新备库执行集合压缩命令
use tbm
db.runCommand({compact:zjthStdTag})
db.runCommand({compact:ztzbStdTag})
db.runCommand({compact:hrkStdTag})
把2-4步骤发给工程师让其在后台执行帮手工回收集合磁盘空间
四、结果收益
经过compact后磁盘利用率从90%降低到25%磁盘空间回收了1180G
---end---