上周在客户这边搞灾备环境的数据迁移,做MongoDB的数据迁移的时候出现了很多问题,迁移过程报错了好几次,最终迁移也失败了,并且导致灾备环境的MongoDB集群的账号信息也变成了生产环境的集群信息,导致整个灾备环境都异常,最终在尝试了一些恢复手段依然没有恢复环境之后还是重新部署的灾备环境。

这次之所以能直接重新部署灾备环境是因为这个环境本身就是新部署的,所以当时想的是与其花大量实际去定位问题和解决问题,还不如直接重新部署。而实际上如果把这次的数据迁移当做生产环境进行,重新部署肯定是不太合理的,虽然数据最终也能恢复,但是操作上肯定无法得到客户的认可。

经过这次的数据迁移,我后面也好好的去了解了一下MongoDB的数据迁移的,以及MongoDB自带的库和集合的作用,并且也去整理了公司的产品使用MongoDB创建的库和集合的作用。这篇文章就记录一下MongoDB自带的库的作用。

事故背景

首先我们的生产环境是每天都会做MongoDB的全量备份的,同时公司也提供了增量备份需要备份的库和集合的清单,并且公司也提供了MongoDB的数据迁移的步骤文档。

看这个背景好像做数据迁移不应该有问题的,那问题是如何发生的呢?!

也是经过这次事故之后的复盘,我才真正的去了解了MongoDB自带的库和库里面集合的作用,也正是基于这了解,才知道为什么把备份文档和迁移文档单独去使用没有问题,但是两者结合起来使用就出了问题。

先说结论:MongoDB有三个自带的库(admin、config、local),这三个库是每个集群自己的内置库,存的数据跟业务无关,所以在做数据迁移的时候不能迁移,否则将会导致目标集群的信息变成源集群的信息,特别是账号和集群信息,这将是致命的。

我上周的操作就是按照公司的文档进行了增量备份,然后进行的迁移,但是增量备份的库清单里面就包含了这三个不能迁移的库,所以导致的问题。当时我也是一直吐槽公司提供的备份文档为什么要包含这三个库,这不是在坑人吗,但是后面我理解了备份文档只是告诉我们哪些数据是重要的,需要备份,这个备份相当于是针对当前这个集群的备份,可以保证当前集群出现问题能恢复,并不是为迁移准备的备份。

知道了这个原因,我后面一次成功迁移数据的操作自然就是先将这三个库的备份数据从备份目录中删除,然后再进行数据恢复。

MongoDB 内置库

经过这次的事故,我也花了一些时间重新了解了MongoDB的内置库的作用,以及数据备份和迁移的一些知识,说白了,别人提供的文档只是别人的知识点,只有自己掌握这些知识点才能更有效的操作。

在MongoDB的默认数据库中,包含一些特定用途的集合。以下是一些默认数据库(adminlocalconfig)下常见的集合及其作用:

  1. admin 数据库下的集合:

    • system.users:这个集合包含了MongoDB的用户账户信息,用于身份验证和访问控制。管理员可以在这里创建、编辑和删除用户。
    • system.version:存储MongoDB服务器版本信息。
  2. local 数据库下的集合:

    • me:包含有关当前服务器的信息,如主机名、端口号、副本集成员信息等。

    • startup_log:MongoDB会在此集合中记录服务器启动时的日志信息,用于诊断和故障排除。

    • oplog.rs:这是MongoDB的操作日志,用于支持复制集和故障恢复。
    • replset.election: 这个集合用于存储关于副本集中选举和选主(Primary)操作的信息。它记录了选主过程的细节,以确保正常运行和故障恢复。
    • replset.minvalid: 用于存储每个副本集成员的操作最小有效时间戳(optime)。这是用于确定数据同步起点的关键信息,确保所有成员都有相同的数据。
    • replset.oplogTruncateAfterPoint: 在某些情况下,MongoDB可能会截断操作日志以减小存储需求。这个集合用于记录截断操作日志后的截断点。
  3. config 数据库下的集合:

    • shards:在分片集群中,此集合存储有关分片服务器的信息。
    • chunks:分片集群使用此集合来存储数据块的分布信息。
    • collections:存储配置数据库中的集合信息,包括是否启用分片、分片键等信息。

这些集合是MongoDB默认数据库中的一部分,它们对于MongoDB的管理和运维至关重要。请注意,在实际的生产环境中,开发者和管理员通常不需要直接操作这些集合,而是使用MongoDB提供的管理工具和命令来管理用户、集群配置等。

复盘

实际上,上周第一次进行数据迁移的时候就发现local库是无法进行迁移的,只要这个库在备份目录中进行数据恢复操作就会直接报错,所以这个库其实不会影响数据迁移。

config库存的是分片集群的信息,但是我们的集群是副本集群,所以这个库迁移应该也没有影响,实际这个迁移的时候会报错。

真正影响比较大的是admin库的迁移,由于这个库里面包含了集群的账号和权限信息,所以只要这个库被迁移,那么新集群的账号信息就变成了跟就环境一样,这个也是当时的实际现象,现在回想一下,其实当时只需要使用用户密码更新的命令将用户的密码重新设置成新集群的密码就行了。

总结

不仅仅是针对MongoDB这个数据库,对于其他数据库也是一样,涉及到数据迁移的操作之前应该先去了解清楚备份了哪些数据,哪些数据是能迁移的,哪些是不能的,哪些数据是需要根据现场情况去迁移的。

另一个经验就是不要太依赖文档,文档只是参考,应该先理解文档里面的操作是在干嘛,而现场需要干嘛,只有两者一致,文档才做作为执行的依据。