一、先搞懂两个备份的本质:别再用错工具
很多人接触MongoDB备份,第一反应就是找个工具敲命令,根本没搞懂“物理备份”和“逻辑备份”到底差在哪,尤其是碰到分片集群这种复杂场景,一不留神就踩坑。先给大家说透这俩的核心区别,别再混着用。
1.1 物理备份:直接复制底层文件
物理备份说白了就是把MongoDB服务器上存数据的那些物理文件,直接整个复制一份,就像你把电脑里的游戏文件夹整个拷到U盘备份一样。它不管里面的数据是什么格式,也不管逻辑结构,只认磁盘上的二进制文件。
举个例子,MongoDB的分片集群里,每个分片服务器上都有自己的WiredTiger存储引擎文件,物理备份就是把每个分片的/data/db目录(默认路径)整个打包,还有配置服务器的配置文件、路由节点的配置也一起备上。
1.2 逻辑备份:导出可读的逻辑数据
逻辑备份是反过来,它会用MongoDB的API去读数据库里的逻辑数据,比如你存的用户表、订单表,然后把这些数据转成JSON、BSON这种大家能看懂的格式导出来,就像你把游戏里的角色数据导出成一个XML文件备份,不是拷整个游戏文件夹。
比如你要备份一个叫“shop”的数据库,逻辑备份会把shop里的user集合、order集合的数据一条条读出来,转成BSON格式存成备份文件,你甚至能打开这个备份文件看到里面的具体内容。
二、分片集群的坑:为什么普通备份会失效?
分片集群和单节点、副本集完全不一样,它是把数据拆成好几份,分别存在不同的分片服务器上,还有专门的配置服务器存分片规则,路由节点负责转发请求。普通备份逻辑到了这里,很容易出大问题。
2.1 分片集群的核心结构
先给大家理清楚分片集群的三个核心部分,不然说备份大家会懵:
- 配置服务器:存整个集群的元数据,比如哪些数据存在哪个分片上,还有集群的权限、分片规则,相当于整个集群的“大脑”。
- 分片服务器:存实际的业务数据,每个分片可以是单节点,也可以是副本集(为了高可用)。
- 路由节点:不存数据,只负责把用户的请求转发到对应的分片,用户连集群都是连路由节点。
2.2 普通备份的致命问题
比如你用逻辑备份单独备份某个分片,备份出来的数据是不完整的,因为这个分片里的很多数据可能还没同步,或者备份的时候集群正在写数据,导致分片之间的数据不一致;更严重的是,你单独备份分片,没有备份配置服务器的元数据,恢复的时候根本不知道这些备份出来的数据该怎么拼回原来的集群,相当于一堆没用的散文件。
三、物理备份在分片集群的实战:好用但限制多
物理备份是分片集群备份最常用的方案,但很多人不知道它的坑,要么备不出来,要么恢复的时候出问题。
3.1 适用场景
物理备份适合以下几种情况:
- 数据量特别大的场景:比如一个分片集群总数据量有几十TB,逻辑备份要一条条读数据,速度特别慢,物理备份直接拷文件,速度快很多。
- 追求备份速度的场景:比如每天凌晨要做全量备份,要求几小时内完成,物理备份的速度比逻辑备份快很多。
- 要备份整个集群的场景:物理备份能把配置服务器、所有分片、路由节点的配置都一起备上,恢复的时候能还原整个集群的状态。
3.2 具体操作示例
这里统一用MongoDB自带的mongodump(逻辑)和mongodump的物理备份?不对,物理备份常用的是MongoDB自带的mongodump?不,物理备份常用的是用文件系统的快照,或者MongoDB的mongodump其实是逻辑?哦对,MongoDB的mongodump是逻辑备份,物理备份常用的是mongodump的物理?不对,应该是用MongoDB的mongodump是逻辑,物理备份常用的是用文件系统的快照,或者用MongoDB的mongodump的物理模式?哦对,MongoDB 4.2以后支持mongodump的物理备份模式,这里统一用MongoDB 4.4的mongodump(物理模式)来做示例,技术栈统一为MongoDB 4.4。
技术栈:MongoDB 4.4(分片集群) 物理备份的操作步骤(以配置服务器、分片都为副本集为例): 第一步:先停集群的写操作(或者用mongodump的--oplog参数来保证一致性),这里用--oplog来保证备份期间的写操作也能被记录,恢复的时候能同步到最新状态。 第二步:备份配置服务器的副本集,因为配置服务器的元数据是核心,必须先备:
# 备份配置服务器副本集,注意要连配置服务器的主节点
mongodump --uri "mongodb://config1:27019,config2:27019,config3:27019/admin?replicaSet=configRS" --out /backup/config --oplog --gzip --forceTableScan
# 参数说明:
# --uri:配置服务器副本集的连接地址,注意端口是配置服务器的默认端口27019
# --out:备份文件输出目录
# --oplog:记录备份期间的操作日志,保证备份一致性
# --gzip:压缩备份文件,节省空间
# --forceTableScan:强制全表扫描,避免因为索引问题导致备份失败
第三步:备份每个分片的副本集,比如有两个分片shard1和shard2:
# 备份shard1的副本集
mongodump --uri "mongodb://shard1-1:27018,shard1-2:27018,shard1-3:27018/admin?replicaSet=shard1RS" --out /backup/shard1 --oplog --gzip --forceTableScan
# 备份shard2的副本集
mongodump --uri "mongodb://shard2-1:27018,shard2-2:27018,shard2-3:27018/admin?replicaSet=shard2RS" --out /backup/shard2 --oplog --gzip --forceTableScan
# 注意:分片的默认端口是27018,和配置服务器、路由节点区分开
第四步:备份路由节点的配置文件,因为路由节点的配置里有集群的连接信息、权限配置等:
# 备份路由节点的配置文件,比如mongos.conf
cp /etc/mongos.conf /backup/mongos.conf
3.3 优缺点和注意事项
优点:备份速度快,适合大数量级;备份的是底层文件,恢复的时候能还原整个集群的状态;支持增量备份(用oplog)。 缺点:对存储引擎的版本要求严格,比如备份用的是WiredTiger 4.4,恢复的时候也必须用4.4的WiredTiger,不能跨版本恢复;备份的文件是二进制的,不能修改,比如你不能单独恢复某个集合;对磁盘空间要求高,比如总数据量是10TB,备份文件压缩后可能也要3-5TB,需要有足够的磁盘空间。 注意事项:备份的时候必须保证集群的一致性,要么停写,要么用--oplog参数;配置服务器的备份必须优先,因为元数据是核心;每个分片的备份要单独做,不能一起备。
四、逻辑备份在分片集群的实战:灵活但慢
逻辑备份在分片集群里用的人少,但它有自己的优势,适合一些特殊场景。
4.1 适用场景
逻辑备份适合以下几种情况:
- 数据量小的场景:比如集群总数据量只有几GB,逻辑备份的速度足够快。
- 要单独备份某个集合的场景:比如你只想备份用户表,不需要备份整个集群。
- 要跨版本恢复的场景:比如你用MongoDB 4.4做的备份,要恢复到MongoDB 5.0的集群里,逻辑备份支持跨版本。
- 要修改备份数据的场景:比如你要把备份出来的用户数据过滤掉敏感信息,再恢复到测试环境。
4.2 具体操作示例
技术栈:MongoDB 4.4(分片集群) 逻辑备份的操作步骤,这里备份整个集群(注意逻辑备份整个集群的时候,必须连路由节点,不能连分片): 第一步:连路由节点,备份整个集群的所有数据库(除了系统数据库):
# 连路由节点(端口默认27017),备份整个集群
mongodump --uri "mongodb://mongos1:27017,mongos2:27017,mongos3:27017/admin" --out /backup/logic_backup --gzip --excludeCollectionsWithPrefix "system."
# 参数说明:
# --uri:路由节点的连接地址,端口默认27017
# --excludeCollectionsWithPrefix:排除系统集合,比如system.users、system.profile等
# 注意:逻辑备份整个集群的时候,必须连路由节点,这样mongodump会自动把所有分片的数据都拉过来,保证数据的一致性
第二步:如果要单独备份某个集合,比如备份shop数据库的user集合:
# 连路由节点,单独备份shop数据库的user集合
mongodump --uri "mongodb://mongos1:27017/admin" --db shop --collection user --out /backup/user_backup --gzip
4.3 优缺点和注意事项
优点:灵活,可以单独备份某个集合、某个数据库;支持跨版本恢复;备份文件是可读的,可以修改;对磁盘空间的要求相对低,因为可以只备份需要的部分。 缺点:备份速度慢,数据量越大,速度越慢;备份的时候会占用路由节点的CPU和内存,影响业务;不能保证备份期间的写操作的一致性?不对,逻辑备份也可以用--oplog参数,保证备份期间的写操作被记录。 注意事项:备份整个集群的时候必须连路由节点,不能连分片;如果要保证备份的一致性,必须用--oplog参数;数据量超过100GB的时候,不建议用逻辑备份做全量备份,速度会非常慢。
五、怎么选?给大家的选型指南
很多人纠结到底用物理备份还是逻辑备份,其实很简单,根据自己的场景来选:
- 如果你的集群数据量超过100GB,要求备份速度快,要做全量备份,选物理备份。
- 如果你的集群数据量小于100GB,要单独备份某个集合,要跨版本恢复,选逻辑备份。
- 如果你的集群要做容灾备份,选物理备份,因为恢复速度快。
- 如果你的集群要做测试环境的备份,选逻辑备份,因为可以修改备份数据。
还要注意,不管选哪种备份,都要定期做恢复测试,很多人备份完就不管了,真的出问题的时候才发现备份文件是坏的,恢复不了。比如你每个月做一次恢复测试,把备份文件恢复到测试集群,检查数据的完整性。
另外,现在很多人用MongoDB的云服务,比如阿里云的MongoDB、腾讯云的MongoDB,这些云服务都自带备份功能,比如阿里云的MongoDB会自动做物理备份,你只需要设置备份的时间和保留天数就可以,不用自己敲命令。但如果是自建的集群,就要自己选备份方案。
最后说一个大家容易踩的坑:很多人备份的时候只备份分片,不备份配置服务器,恢复的时候根本不知道这些备份出来的数据该怎么拼回原来的集群,相当于一堆没用的散文件。所以不管用哪种备份,都必须备份配置服务器的元数据。
评论
围绕“MongoDB备份恢复的隐藏雷区,物理备份与逻辑备份在分片集群场景下的取舍”参与讨论