Mongodb 集群的恢复

要做一个mongodb集群的迁移和恢复,真是折腾死人了。记录并顺便吐槽一下:

mongodb的tools真的是太简易、粗糙、丑陋了。

线上的源数据库是腾讯的服务,要废弃搬迁到内网,足足折腾了一个星期。

线上源数据库环境如下:

  • 云数据库 TencentDB
  • 4C/8GB/500GB
  • 3节点

于是在线下对等建立了mongo集群,同样配置,同样3节点。

噩梦由此开始啊,注意线下集群的memory配置一定要高:

  • 32GB
  • 用户名和密码一定要和线上完全一致
  • 如果用户名密码不一致,Document恢复完毕,Index无法建立,因为是完全恢复,会覆盖admin这个db

然后开始dump线上数据

1mongodump --uri="mongodb://root:xxxxxxxx@10.1.2.3:27017/?authSource=admin"

然后生成一个24G大小得dump文件夹,压缩后2.4G,传输到线下库上准备恢复

 1# 大量恢复必须扩大文件句柄,否则过不去
 2ulimit -n 655360
 3
 4# 一定要记录下来开始的时间戳,后面有用
 5date
 6Sun May 11 06:34:02 PM CST 2025
 7
 8# 开始恢复,漫长的一天开始了
 9# 必须放到screen中执行,否则网络不好,断了也会很悲剧
10
11screen -L
12
13./mongorestore \
14   --drop \
15   --host=192.168.111.222 \
16   --port=27017 \
17   --username=root \
18   --authenticationDatabase=admin \
19   --nsExclude=admin \
20   /root/dump
21   
22 ctrl+a+d

其实刚开始线下三节点得配置是8G,然后恢复用了一晚,报错,直接把shard3给打崩了,虽然三节点都是docker启动得,有自动恢复机制,但是mongorestore可不管这个,中断期间有1000个Document没有恢复成功。

重试了2次后才发现这问题,2天已经过去了,意识到就立刻把内存提升到32G,再次进行恢复。

但是新建的集群的密码跟源库这时是不一致的,又一天过去了,Document文档是恢复完毕,Index又无法建立,因为用户名和密码不一致,Fuck!

又双叒再次开始恢复,这下天下大吉了,然后这还不算完!

restore后,其实又过了一天,那要追平之后的数据,就得用上实时同步工具了,这里用的是阿里的mongoshake

下载:

1wget https://github.com/alibaba/MongoShake/releases/download/release-v2.8.5-20250403/mongo-shake-v2.8.5.tgz
2
3tar zxvf mongo-shake-v2.8.5.tgz
4cd mongo-shake-v2.8.5
5wget https://raw.githubusercontent.com/alibaba/MongoShake/refs/heads/develop/conf/collector.conf

我们需要注意collector.conf的以下地方:

 1# 源数据库
 2mongo_urls = mongodb://root:xxxxxxxx@10.1.2.3:27017/?authSource=admin
 3# 目标数据库
 4tunnel.address = mongodb://root:xxxxxxxx@192.168.4.5:27017/?authSource=admin
 5
 6# 同步模式,all表示全量+增量同步,full表示全量同步,incr表示增量同步。
 7# 也就是说,其实我们一开始就可以用full模式来进行同步,那为什么不呢?看下面的解释
 8sync_mode = incr
 9
10# 那还有一个问题:就是如果mongoshake的collector进程掉了,比如被OOM了
11# 下次再启动,会重新全量同步还是接着增量同步呢?
12# 答案是:同步的时候,collector会在源库建立一个mongoshake的db,里面有个表ckpt_default,里面放着同步信息
13# collector重启后会读取这个表进行增量同步,哪怕 sync_mode=full
14# 所以如果想重启后重新全量同步,那就需要手动删了这个表,或者换个表名,比如换成ckpt_sync
15
16# 那mongoshake实际是根据oplog进行同步的,那如果以前的oplog有删除,我们就必须用dump和restore进行一次完整备份恢复
17# 然后再进行追平,那刚开始我们记录下来的时间戳就有用了
18# Sun May 11 06:34:02 PM CST 2025 下午16点34分
19# collector用的是UST时间,我们的时间是东八区,CST,所以要减去8小时,16-8=8
20# 那就是:2025-05-11T08:30:00Z  时间稍稍前推一点,然后追平数据
21
22checkpoint.storage.db = mongoshake
23checkpoint.storage.collection = ckpt_default
24checkpoint.start_position = 2025-05-11T08:30:00Z

然后注意,源库实际是个代理,直接连的话,有三个节点,而mongoshake是够不到这三个节点的,所以需要强制改成一个直接连接:

1mongo_urls = mongodb://root:xxxxxxxx@10.1.2.3:27017/?authSource=admin&connect=direct

然后就开始同步

1# 注意,一定放到screen里
2screen -L
3
4# verbose 需要是0,记录到文本文件,便于之后持续观察
5./collector.linux -conf=collector.conf -verbose 0

看日志有同步的,就OK

image-20250513134512063


Mongodb 如何升级
comments powered by Disqus