一、MongoDB备份为什么让人头疼
作为NoSQL数据库的扛把子,MongoDB用起来是真香,但说到备份恢复这事儿,不少运维同学都要挠头。原因很简单——它和传统关系型数据库的备份逻辑完全不同。
举个典型场景:你用了分片集群,突然某个分片的主节点挂了。这时候如果用传统的mongodump,可能会遇到以下问题:
- 备份期间数据库持续写入,导致备份数据不一致
- 恢复时分片配置信息丢失
- 大数据量备份慢到怀疑人生
// MongoDB技术栈示例:基本备份命令
mongodump --host=localhost --port=27017 --db=production_db
// 问题1:没有指定--oplog会导致备份期间新增数据丢失
// 问题2:分片集群需要额外处理config server
二、实战派解决方案
方案1:官方推荐的组合拳
MongoDB官方其实给出了黄金组合:副本集 + Oplog。这就像给数据库上了"时光机",可以回滚到任意时间点。
// 创建全量备份
mongodump --host=rs0/localhost:27017,localhost:27018 --db=orders --out=/backup/full
// 增量备份通过oplog实现
mongodump --host=rs0/localhost:27017 --collection=oplog.rs --db=local --query='{ts:{$gte: Timestamp(1630000000,1)}}' --out=/backup/incr
方案2:文件系统快照大法
对于超大型数据库,可以配合LVM或AWS EBS做快照:
# Linux技术栈示例
lvcreate --size 1G --snapshot --name mongo_snap /dev/vg_mongo/mongo_data
# 注意:需要先执行fsync锁住数据库
三、恢复时的骚操作
恢复数据最怕什么?当然是恢复完发现数据对不上!这里分享几个救命技巧:
- 预演恢复:先在临时环境测试
- 索引优先:先恢复索引再恢复数据
- 流量控制:恢复期间限制应用连接
// 带索引恢复的示例
mongorestore --host=rs0/newserver:27017 --db=orders --noIndexRestore /backup/full/orders
mongorestore --host=rs0/newserver:27017 --db=orders --noCollectionData /backup/full/orders
四、避坑指南
- 分片集群:config server必须第一个恢复
- 版本兼容:3.6的备份不能直接恢复到4.0
- 内存陷阱:恢复前调大cacheSizeGB
// 分片集群恢复顺序
1. 恢复config server
2. 恢复shard1
3. 恢复shard2
// 注意每个步骤间隔不要超过oplog窗口
五、进阶技巧
对于特别重要的生产环境,可以考虑这些方案:
- 延迟副本集:专门用于数据恢复
- 混合云备份:本地快照+云存储
- 校验脚本:自动比对数据一致性
# Python技术栈的校验脚本示例
from pymongo import MongoClient
def verify_restore(src_uri, dst_uri):
src = MongoClient(src_uri)['mydb']
dst = MongoClient(dst_uri)['mydb']
for col in src.list_collection_names():
assert src[col].count_documents({}) == dst[col].count_documents({})
六、总结与选型建议
- 中小规模:副本集+oplog足够
- 超大规模:文件系统快照+延迟副本
- 混合架构:考虑MongoDB Atlas的云服务
记住三个关键数字:
- oplog至少保留72小时
- 备份验证频率不低于每周1次
- 恢复演练每季度必须做
评论