mongodb空间不足的解决方案
下面是由于 mongodb 副本集中某个库越来越大的几次解决方案,仅供参考:
第一期:更换机器->迁移最大库
- 问题描述:由于 mongodb 数据越来越大,导致磁盘空间(/mnt 使用率 96%)不足,数据清理效果不明显,其中最大的库 xxxxx_tong 有 1.1T
[root@u-176-mongo ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 99G 4.3G 90G 5% /
/dev/vdb ext4 1.8T 1.7T 72G 96% /mnt
[root@u-176-mongo ~]# cat /etc/mongod27017.conf | grep dbPath
dbPath: "/mnt/mongodb/data27017"
[root@u-176-mongo ~]# cd /mnt/mongodb/data27017
[root@u-176-mongo ~]# du -sh * | sort -rh | head -1
1.1T xxxxx_tong
解决方案:
- 第1步,购买一台新机器(作为新的主库),多买1块 2TB 的磁盘并挂载为 /data,安装 mongo 实例,配置不变(/mnt 仍为数据目录)
- 第2步,在 /data 分区下创建目录(用于存放最大的库),并创建软链到 dbPath 目录下
#.在新盘/data创建目录,存放最大的库
mkdir /data/mongodb/data27017/xxxxx_tong
#.创建软链到数据目录
ln -sv /data/mongodb/data27017/xxxxx_tong /mnt/mongodb/data27017/xxxxx_tong
- 第3步,先确认副本集无延迟,再将主节点的权重调到最低,触发选举之后将主节点从副本集中移除
- 第4步,将2台机器关机,然后对换内网ip,开机之后将新的节点加入副本集,会触发全量初始化
- 第5步,待新机器初始化完成之后,再将该节点的优先级调到最高,再次触发选举,选为主节点
注:其他节点可参考此法,详细过程请参考本站 mongodb副本集更换主节点计划
第二期:拆分最大库
- 问题描述:由于最大的库 xxxxx_tong 越来越大(达到1.6T,/data 使用率达到 94%),删无可删,所以决定将42张表、600G数据迁移到一个新库 xxx_growth(新库默认目录/mnt)
[root@u-176-mongo ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 99G 4.3G 90G 5% /
/dev/vdb ext4 1.8T 1.6T 109G 94% /data
/dev/vdc ext4 1.8T 391G 1.3T 24% /mnt
[root@u-176-mongo ~]# cat /etc/mongod27017.conf | grep dbPath
dbPath: "/mnt/mongodb/data27017"
解决方案:
- 登录主节点,将42张表按照从小到大的顺序执行 renameCollection 操作(会迁移数据+索引)
//.创建新库
use xxx_growth;
db.createCollection("test_2026");
//.批量迁移表
use admin;
db.runCommand({'renameCollection':'xxxxx_tong.aaa','to':'xxx_growth.aaa'});
- 拆分之后的效果如下:
[root@u-176-mongo ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 99G 4.3G 90G 5% /
/dev/vdb ext4 1.8T 1.6T 109G 94% /data #.迁移之前
/dev/vdc ext4 1.8T 391G 1.3T 24% /mnt #.迁移之前
/dev/vdb ext4 1.8T 1013G 658G 61% /data #.迁移之后
/dev/vdc ext4 1.8T 779G 892G 47% /mnt #.迁移之后
遇到的问题
- 问题1:对2个 200G 的大表执行 renameCollection 操作之后(此时副本集存在延迟),由于主库(节点1)发生OOM导致服务停止,随后触发自动选举,节点2变为新主库。将节点1的mongo服务启动之后,其状态为 ROLLBACK,30分钟之后又变为 PRIMARY(因为节点1的优先级最高),在此过程中节点1的 xxx_growth 目录从 417G 变为 409G 最后为 558G。
注:在此过程,不建议做其他操作(
比如将节点1从副本集移除,以消除节点1的ROLLBACK状态)等它回滚完成吧。
- 问题2:节点3的状态变为 RECOVERING、且延迟一直不断增大、应用程序访问副本集失败,随将其优先级改为0、设置隐藏(避免参与选举/防止应用程序读取),但延迟仍在变大。
注:计划后期关闭节点3的mongo服务、删除数据目录(不要删配置文件)、启动mongo、触发初始同步,从主库全量拉数据,完成之后变为SECONDARY,再修改优先级并取消hidden属性
#.杀掉mongo进程
ps -ef | grep -v grep | grep mongod | awk '{print $2}' | xargs kill -9
#.删除数据目录
rm -rf /mnt/mongodb/data27017
rm -rf /data/mongodb/data27017/xxxxx_tong
#.重新创建数据目录
mkdir -p /mnt/mongodb/data27017
mkdir -p /data/mongodb/data27017/xxxxx_tong
ln -sv /data/mongodb/data27017/xxxxx_tong /mnt/mongodb/data27017/xxxxx_tong
#.启动mongo进程
numactl --interleave=all /opt/mongodb/bin/mongod -f /etc/mongod27017.conf
- 问题3:执行 renameCollection 在新库下面有一个临时表没有清理:tmpCJWjw.renameCollection(行数=1878726, 数据=205414.48MB)
//.查看行数
db.getCollection("tmpCJWjw.renameCollection").count()
//.删表
db.getCollection("tmpCJWjw.renameCollection").drop()