如何跳过mongorestore的E11000重复键错误,恢复崩溃后的大MongoDB
一、跳过已恢复数据,续传备份
针对重复键错误导致的恢复崩溃,核心思路是分集合确认已恢复文档数,针对性跳过已插入的数据:
统计目标库中已恢复的文档数
连接目标MongoDB,执行命令查看指定集合的已存在文档数量:mongo tuplesdb --eval "db.cco.countDocuments()"替换
cco为对应集合名,重复操作遍历所有集合。统计备份文件的总文档数
用bsondump解析备份的bson文件,统计总文档数:bsondump tuples-webisadb-april-2016/tuplesdb/cco.bson | wc -l同样替换
cco为对应集合名。跳过已恢复数据,单独恢复剩余部分
使用mongorestore的--skip参数跳过已插入的文档,只恢复剩余内容:mongorestore --db tuplesdb --collection cco --skip [已恢复文档数] tuples-webisadb-april-2016/tuplesdb/cco.bson注:此方法依赖备份bson文件按插入顺序存储,若你的
_id为有序自增格式,逻辑完全成立。替代方案:自动去重续传
若不想逐个集合处理,可将bson转成json后用mongoimport的--upsert参数,自动跳过已存在的文档:# 转换bson为json格式 bsondump tuples-webisadb-april-2016/tuplesdb/cco.bson > cco.json # 导入时自动处理重复文档 mongoimport --db tuplesdb --collection cco --upsert --file cco.json此方法无需手动统计,适合批量处理,但转json会占用额外磁盘空间。
二、大MongoDB备份恢复的优化方法
针对200GB级别的大备份,以下方法可大幅提升恢复速度,降低崩溃概率:
并行恢复多个集合
利用mongorestore的--parallel参数,根据CPU核心数调整并行数(如8核CPU设为--parallel 6),同时恢复多个集合:nohup mongorestore --parallel 6 tuples-webisadb-april-2016 > mongorestore.out 2> mongorestore.err < /dev/null临时调整mongod配置提升写入性能
修改启动参数或mongod.conf:- 增大WiredTiger缓存:将
storage.wiredTiger.engineConfig.cacheSizeGB设为可用内存的70%左右(如32GB内存设为22) - 临时关闭journaling(风险提示:仅适合备份恢复,完成后务必重新开启):启动时添加
--nojournal参数 - 降低写入确认级别:恢复时使用
--writeConcern "{w:0}",无需等待节点写入确认,大幅提速
- 增大WiredTiger缓存:将
先恢复数据,后建索引
默认mongorestore会先创建索引再插入数据,速度极慢。可先跳过索引恢复,之后手动批量创建:# 仅恢复数据,不创建索引 mongorestore --noIndexRestore tuples-webisadb-april-2016 # 从备份的metadata.json中提取索引定义,手动创建 mongo tuplesdb --eval "db.cco.createIndex({...})"使用高速存储介质
将MongoDB数据目录(/data/webisadb/mongodb)挂载到SSD磁盘,写入速度比HDD提升数倍,减少恢复时间和崩溃概率。
内容的提问来源于stack exchange,提问作者Horst Mueller

