急急急急,求教,。。。各位大神,公司的 mongodb 挂了半个月没发现,现在 oplog 已经跟不上了

2018-02-06 09:55:03 +08:00
 Mrzhang0320

请教如何恢复数据,官档看了一下,说是要停止实例;或者自动全量同步; 这里大概问一下,自动全量同步 initial sync 1T 数据要多久

7775 次点击
所在节点    MongoDB
27 条回复
timothyye
2018-02-06 10:00:49 +08:00
我们也遇到过,后来直接停掉,从 primary 拷贝数据……
也可以把数据全部删掉,从头同步,花的时间跟你的带宽和磁盘读写速度有关
onion83
2018-02-06 10:01:43 +08:00
看看是否有空闲的副本集实,停掉,全量拷贝数据( scp、注意文件夹权限)包含 oplog,重启即可。
Mrzhang0320
2018-02-06 10:04:18 +08:00
@timothyye 主库不能停,不过还有一台从库;再请问一下 cp 数据的话是不是把 dbpath 的所有数据拷过来就行了
Mrzhang0320
2018-02-06 10:05:37 +08:00
@onion83 是还有一台副本集的实例;只拷贝 dbpath 的数据就可以吗
rrfeng
2018-02-06 10:09:34 +08:00
只有主库的话只能自动全量同步了,时间主要取决于磁盘和 CPU 性能。按照我们之前的经验 1T 如果用 SSD 的话大概要几个小时,不过不同场景下差距也很大,十几个小时也有可能。

如果还有一个从库并且可以停掉(主库完全能暂时抗住压力的话),那直接 rsync dbpath 就可以了。注意文件权限。官方文档有类似的操作说明。注意拷贝时间不能超过存活的从库的 oplog 大小,不然唯一的从库也可能跟不上了…
jy02201949
2018-02-06 10:12:27 +08:00
急啥,都挂了半个月没发现了,说明也不是什么重要业务,全量同步吧
timothyye
2018-02-06 10:19:55 +08:00
@Mrzhang0320 额,我是说把这个 oplog 跟不上,挂掉的实例停掉,然后从一个 primary 或者 secondary 把数据直接 cp 过去……
onion83
2018-02-06 10:32:47 +08:00
1、对,直接拷贝 dbpath 即可。

2、但是,如果整个副本集剩余 1 主 1 从的情况,你将剩下来的 1 从都关掉拷贝数据,整个集群会变成只读状态(不能写数据),你要评估下后果。

3、对于 2,可以尝试不关闭从实例,使用 db.fsyncLock(),将从数据库进入锁定状态,确保在 scp, rsync 过程中 oplog、数据文件锁定,不产生变动。但是,程序有可能会读到过期数据。https://docs.mongodb.com/manual/reference/method/db.fsyncLock/

对于 3,这是新功能和理论知识,我没有在生产环境验证过,但最符合你目前的状况。
Mrzhang0320
2018-02-06 10:44:58 +08:00
@timothyye 好像看了很多资料说在运行的示例不能直接 copy,需要停掉再 copy,不然在写入数据的话 copy 的数据会有问题
Mrzhang0320
2018-02-06 10:45:58 +08:00
@rrfeng 现在是一主两从,挂了一台,不知道停掉两个从 ,会不会像楼下说的,整个集群变成了只读
Mrzhang0320
2018-02-06 10:47:47 +08:00
@onion83 非常感谢, 我们现在的集群 是一主两从,挂了一个从了,还有一主一从再运行,再停一个从就会变成只读了吗?
onion83
2018-02-06 11:20:59 +08:00
1、“我们现在的集群 是一主两从,挂了一个从了,还有一主一从再运行,再停一个从就会变成只读了吗?”

100% 生产环境确认,请谨慎操作。

2、对于 3 是可以尝试的方案,但是请务必理解文档的描述,例如会阻塞读等。

db.fsyncLock() may block reads, including those necessary to verify authentication. Such reads are necessary to establish new connections to a mongod that enforces authorization checks.

很可能需要调整程序,将 read preference 强制为 primary .

3、其实最安全的办法,是将老机器的 datapath 转移一下(mv xxx xxx.old) 然后再做一个空的数据目录,启动从实例会从主库重新全量回放所有 oplog,但是时间无法保证。给你一个经验值,100G 数据,带索引重建,普通 SAS 硬盘大概需要 4 小时左右。

4、终极武器(第三方工具)
http://nosqldb.org/p/5173d275cbce24580a033bd8 (已经验证,相对好用)
https://github.com/Qihoo360/mongosync/
Mrzhang0320
2018-02-06 11:30:11 +08:00
@onion83 我现在是在用你说的第三个方法,但是我实时看那个 datapath 目录大小,发现增加很慢,有时候还会暂停,不知道什么机制,甚至有时候还会减少,我怕 1T 的数据要弄到过年。。。
onion83
2018-02-06 11:48:09 +08:00
1、实时进度可以在日志文件中找到 (配置项 systemLog.path) 中找到,不要告诉我你没有配...
2、数据恢复不是问题,建索引那才叫痛苦 ....
3、慢的请可以看看网络或者 IO 是否有瓶颈,我试过 7 天才恢复 100G 数据... 按你的情况,过完年都不一定能搞完,要么老老实实和老板道个歉,通宵停机维护吧。按千兆网络 70MB/s 来算,全量拷贝数据的时间为 1*1024*1024/70/60/60 = 4.16 小时,5 小时就能安心回家过年:)
Mrzhang0320
2018-02-06 11:59:31 +08:00
@onion83 配了,看情况是得停机了;话说你那个终极武器可以不停机吗?你验证的时候
xkeyideal
2018-02-06 12:07:47 +08:00
@Mrzhang0320 先把锅甩给 DBA 和运维,挂了这么长时间都没有发现,也是奇葩。

停机,拷贝数据最靠谱吧,毕竟数据量太大

mongodb 用来存 1T 的数据,做业务的人也是奇葩
onion83
2018-02-06 12:48:29 +08:00
mongosync 带 oplog 本质上是数据热拷贝和集群的状态无关,其它节点不会感知到目标机的存在,自然也就无需停机了。但是因为其基于 oplog 回放,所以建索引之类的操作依然无法避免,恢复起来的时间也是很长的,但好处是不影响其它机器和线上业务,放着慢慢搞也不迟。

被恢复机器有一些需要注意的事项,例如实例要配置为单独节点( standalone,配置文件中 replication.replSetName 不要设置),最后看 mongosync 的日志文件,当状态为 full sync 的时候,就 kill 掉同步程序,关闭会被恢复数据库,修改配置文件,添加相同的 replication.replSetName,最后在主节点上 rs.add() 被恢复机器即可。

还有一个办法是使用磁盘快照,数据盘全盘打快照后,起实例挂新数据盘,这种方式验证过也是可行的(阿里云)

所以,一个稳妥的生产环境,我觉得至少标配下列条件:

1、一个隐含节点,实时同步数据,并可以用于故障的随时切换。
2、一个隐含节点,延时同步数据,用于数据库误操作无法逆转时的有损恢复。
3、以天为单位的数据盘快照,保留 30 天。
caola
2018-02-06 12:59:08 +08:00
半个月没发现,说明真不是什么重要的服务,
直接全量同步吧,半个月都过去了,也不差这点时间同步
tvboxme
2018-02-06 15:10:30 +08:00
干掉原始数据,当成个新节点全量同步,慢慢等,不着急。
Mrzhang0320
2018-02-06 15:15:08 +08:00
@tvboxme 主要是数据太大了,要是一两百 G 我就直接等了,,而且 不是 ssd,就是普通硬盘

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/428790

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX