Mongo数据库备份恢复后大小校验的bash脚本实现方案咨询
MongoDB备份恢复数据校验bash脚本实现方案
前置依赖
- 运行脚本的机器已安装MongoDB对应版本的
mongosh(老版本用mongo)客户端,且有权限连通源、目标环境的Mongo实例 - 所用Mongo账号对校验的数据库有读权限
- 系统已安装
jq工具用于JSON数据解析
具体实现步骤
1. 封装获取库统计指标的公共函数
该函数接收Mongo连接串、待校验数据库名作为入参,返回db.stats()中的核心对比指标JSON:
get_db_stats() { local MONGO_URI="$1" local DB_NAME="$2" # 输出JSON格式的核心统计指标,过滤无关字段 mongosh "$MONGO_URI/$DB_NAME" --quiet --eval " const stats = db.stats(); JSON.stringify({ dataSize: stats.dataSize, objects: stats.objects, indexSize: stats.indexSize, storageSize: stats.storageSize }) " | jq -c . }
2. 拉取源端、目标端的统计数据
替换以下配置中的连接信息为实际环境参数:
# 自定义配置项 SOURCE_MONGO_URI="mongodb://账号:密码@源端地址:27017/?authSource=admin" TARGET_MONGO_URI="mongodb://账号:密码@目标端地址:27017/?authSource=admin" CHECK_DB="待校验的数据库名" # 允许的数据大小误差率,可根据需求调整 ALLOW_DIFF_RATE=1 # 拉取两端统计数据 SOURCE_STATS=$(get_db_stats "$SOURCE_MONGO_URI" "$CHECK_DB") TARGET_STATS=$(get_db_stats "$TARGET_MONGO_URI" "$CHECK_DB") # 提取各字段值 SOURCE_OBJ=$(echo "$SOURCE_STATS" | jq .objects) TARGET_OBJ=$(echo "$TARGET_STATS" | jq .objects) SOURCE_DATA_SIZE=$(echo "$SOURCE_STATS" | jq .dataSize) TARGET_DATA_SIZE=$(echo "$TARGET_STATS" | jq .dataSize) SOURCE_IDX_SIZE=$(echo "$SOURCE_STATS" | jq .indexSize) TARGET_IDX_SIZE=$(echo "$TARGET_STATS" | jq .indexSize)
3. 指标对比与异常抛出
核心优先校验文档数(必须完全一致),数据大小可根据需求设置允许的误差范围,避免存储格式、压缩配置带来的误报:
ERROR=0 echo "=== 数据库${CHECK_DB}校验结果 ===" echo "文档数:源端${SOURCE_OBJ} | 目标端${TARGET_OBJ}" echo "数据大小:源端${SOURCE_DATA_SIZE}字节 | 目标端${TARGET_DATA_SIZE}字节" echo "索引总大小:源端${SOURCE_IDX_SIZE}字节 | 目标端${TARGET_IDX_SIZE}字节" # 校验文档数 if [ "$SOURCE_OBJ" -ne "$TARGET_OBJ" ]; then echo "[ERROR] 文档数量不匹配,差值为$((SOURCE_OBJ - TARGET_OBJ))条" ERROR=1 fi # 校验数据大小误差 if [ "$SOURCE_DATA_SIZE" -ne 0 ];then DIFF_RATE=$(echo "scale=4; ($SOURCE_DATA_SIZE - $TARGET_DATA_SIZE)/$SOURCE_DATA_SIZE * 100" | bc) DIFF_ABS=$(echo "scale=0; $DIFF_RATE < 0 ? -$DIFF_RATE : $DIFF_RATE" | bc) if [ $(echo "$DIFF_ABS > $ALLOW_DIFF_RATE" | bc) -eq 1 ];then echo "[ERROR] 数据大小差异超过允许值${ALLOW_DIFF_RATE}%,当前差异率为${DIFF_RATE}%" ERROR=1 fi fi # 最终判断 if [ $ERROR -ne 0 ];then echo ">>> 校验不通过,备份恢复存在数据异常" exit 1 else echo ">>> 校验通过,两端核心指标一致" exit 0 fi
注意事项
- 老版本MongoDB没有
mongosh的话,把代码中mongosh替换为mongo即可正常运行 - 无需对比
fileSize或磁盘上的库文件大小:逻辑备份不会导出源库的碎片化空闲空间,恢复后目标库的文件大小小于源端属于正常现象 - 若两端Mongo的存储引擎、压缩算法配置不同,
storageSize存在差异属于正常情况,优先以文档数、dataSize作为校验标准即可
内容的提问来源于stack exchange,提问作者charles
相关产品推荐
相关产品推荐

