即使删除了MongoDB的集合,容量仍然没有减小,需要采取对策
MongoDB删除数据后并不会释放容量,不确定是否会重新利用(请告诉我,如果你验证过的话,我会很高兴)。
如果以节约型方式运营MongoDB,可能会出现“硬盘好像不太行”的情况。
由于在多次实际对应中似乎没有问题,所以我进行了总结。
环境
-
ReplicaSetで3台構成で運用
MongoDB Versionは 2.4.4, 2.4.8 でやった
OS debian squeeze
普遍的解决方案
-
サービスをメンテナンスにして大きなサーバに置き換える
必要ないデータを削除後、サービスをメンテナンスにして repairDatabase する
思考一下。
替换为大型服务器。
优点
-
シンプル
安全そう
簡単そう
缺点
-
サービス一時停止
コストアップ
修复数据库
优势
-
コストキープ
他のデータ不整合とかも取れるぽい
MongoDBぽい
缺点
-
サービス一時停止
時間がどのくらいかかるのか検証しないといけない
ブラックボックス
空き容量がDB容量+2GB無いと実行できない
修复数据库需要与当前数据集大小加上2GB相等的可用磁盘空间。
不想做
-
そもそもサービス停止は出来る限りやりたくない。
少しなら仕方ないけど1日とか半日とか死亡フラグ
よくわからない事は取り返しつかなくなりそうなのでやりたくない
当たり前だけどコストはかけないに越したことはない
マイノリティ根性(もっといい方法は絶対あると信じてた)
用不同的方式试试
- 删除不需要的Collection。
这个处理非常轻松,所以可以批量删除。
但是容量仍没有被释放。
如果将SECONDARY清空并重新进行同步会怎样呢?
容量减少了Σ(゚д゚
逐台减小SECONDARY的容量并进行同步。
全部同步完成后,将PRIMARY和SECONDARY互换(需要短暂暂停应用程序)。
将原PRIMARY也清空并重新同步。
哇,神奇。维护只需约30分钟就能完成。
任务的具体内容
复制集配置
- 主要
10.120.41.197
次要
10.120.41.196
次要
10.120.41.199
删除不需要的收藏品
set:PRIMARY> use dbname;
set:PRIMARY> db.collectionname.drop()
应该消失于一瞬间
将SECONDARY从ReplicaSet中移除
set:PRIMARY> rs.remove("10.120.41.196:27017")
看守直到解除的次要日志平静下来。
停止被卸载的次要MongoDB。
set:REMOVED> use admin;
set:REMOVED> db.shutdownServer();
删除已拆卸的SECONDARY的dbpath和logpath。
如果有不安的感觉,可以将其压缩并备份到其他地方,然后应该能够恢复(未经确认)。
$ sudo rm -r /var/lib/mongodb/*
$ sudo rm -r /var/log/mongodb/*
5. MongoDB重生
请按照各个操作系统的方式进行操作。
$ sudo service mongod start
6. 添加一个ReplicaSet
如果在追加时没有设置来自哪个成员进行同步,就会从PRIMARY进行同步,从而影响到服务。
如果能快速调用rs.syncFrom,就能立即进行同步,所以每次都很着急。(如果您知道更好的方法,请告诉我)
-
PRIMARY側作業
set:PRIMARY> rs.add("10.120.41.196:27017") # 追加するSECONDARY
-
追加するSECONDARY側作業
我会不停地连击,直到它在PRIMARY中被添加。如果出现OK的日志,暂时还好。
如果是大型的数据库,可以从syncFrom的服务器日志中查看是否有slow query等问题,从而明确是否已经成功进行了同步。
如果在PRIMARY中出现了日志,不要慌张,可以考虑执行rs.remove操作。
> rs.syncFrom('10.120.41.199:27017') # もう一つのSECONDARY
7.只需等待同步完成。
set:PRIMARY> rs.status()
如果执行并添加的SECONDARY为 “stateStr” : “SECONDARY”,则表示完成。
8. 还有一个SECONDARY也做同样的事情
这样一来,除了PRIMARY之外的部分会被优化到合适的容量。
最终是「PRIMARY」
将PRIMARY和SECONDARY交换位置
由于发生了几秒钟无法录入的情况,因此必须进行维护。
虽然切换所需的时间只有几秒钟,但从经验来看,维护时间从未超过30分钟。
-
PRIMARY側作業
set:PRIMARY> rs.freeze(15)
set:PRIMARY> rs.stepDown(1)
10. 只要清空元PRIMARY,就完成了。
哼哼,放松一下……
如果您知道比这更好的方法,请务必告诉我,我会非常高兴!