Skip to content

MongoDB 分片集群恢复

恢复准备工作

  1. 停止所有相关服务

    bash
    # 停止mongos路由
    sudo systemctl stop mongos
    
    # 停止分片上的mongod进程
    sudo systemctl stop mongod
    
    # 停止配置服务器
    sudo systemctl stop mongod-config
  2. 备份现有数据

    bash
    # 备份配置服务器数据
    cp -r /data/configdb /backup/configdb-$(date +%Y%m%d)
    
    # 备份分片数据
    cp -r /data/shard1 /backup/shard1-$(date +%Y%m%d)
    cp -r /data/shard2 /backup/shard2-$(date +%Y%m%d)
  3. 准备恢复介质:确保备份文件可用,验证备份完整性

组件恢复顺序

  • 配置服务器:首先恢复配置服务器,确保配置数据完整性
  • 分片:逐个恢复分片,确保数据一致性
  • mongos路由:最后恢复mongos路由,连接配置服务器和分片

配置服务器恢复

配置服务器恢复步骤

  1. 停止所有配置服务器

    bash
    sudo systemctl stop mongod-config1
    sudo systemctl stop mongod-config2
    sudo systemctl stop mongod-config3
  2. 清理数据目录

    bash
    rm -rf /data/configdb1/*
    rm -rf /data/configdb2/*
    rm -rf /data/configdb3/*
  3. 从备份恢复主配置服务器

    bash
    # 恢复主配置服务器
    mongorestore --host config1:27019 --db config /backup/configdb/config
  4. 重新初始化配置服务器副本集

    javascript
    // 连接到主配置服务器
    mongosh --host config1:27019
    
    // 初始化配置服务器副本集
    rs.initiate({
      _id: "configrs",
      configsvr: true,
      members: [
        { _id: 0, host: "config1:27019" },
        { _id: 1, host: "config2:27019" },
        { _id: 2, host: "config3:27019" }
      ]
    })
  5. 验证配置服务器状态

    javascript
    rs.status()

分片恢复

单个分片恢复步骤

  1. 停止分片上的mongod进程

    bash
    sudo systemctl stop mongod-shard1
  2. 清理分片数据目录

    bash
    rm -rf /data/shard1/*
  3. 从备份恢复分片数据

    bash
    # 恢复分片数据
    mongorestore --host shard1-primary:27018 --db mydb /backup/shard1/mydb
  4. 重新初始化分片副本集

    javascript
    // 连接到分片主节点
    mongosh --host shard1-primary:27018
    
    // 初始化分片副本集
    rs.initiate({
      _id: "shard1rs",
      members: [
        { _id: 0, host: "shard1-primary:27018" },
        { _id: 1, host: "shard1-secondary1:27018" },
        { _id: 2, host: "shard1-secondary2:27018" }
      ]
    })
  5. 验证分片状态

    javascript
    rs.status()

多个分片恢复注意事项

  • 逐个恢复:按顺序恢复每个分片,避免同时恢复导致的资源竞争
  • 数据一致性:确保所有分片恢复到相同的时间点
  • 验证分片连接:恢复后验证分片之间的连接

mongos路由恢复

mongos路由恢复步骤

  1. 配置mongos路由

    yaml
    # mongos.conf
    sharding:
      configDB: configrs/config1:27019,config2:27019,config3:27019
    
    net:
      bindIp: 0.0.0.0
      port: 27017
  2. 启动mongos路由

    bash
    sudo systemctl start mongos
  3. 验证mongos状态

    bash
    mongosh --host mongos:27017 --eval "db.adminCommand({ getCmdLineOpts: 1 })"
  4. 添加分片到集群

    javascript
    // 连接到mongos
    mongosh --host mongos:27017
    
    // 添加分片
    sh.addShard("shard1rs/shard1-primary:27018")
    sh.addShard("shard2rs/shard2-primary:27018")
  5. 验证分片集群状态

    javascript
    sh.status()

数据一致性验证

分片集群完整性检查

  1. 检查配置数据一致性

    javascript
    // 检查配置集合
    db.getSiblingDB('config').collections.find()
    db.getSiblingDB('config').shards.find()
    db.getSiblingDB('config').chunks.find().count()
  2. 检查分片数据分布

    javascript
    // 检查数据库分片状态
    sh.status("verbose")
    
    // 检查集合分片状态
    db.collection.getShardDistribution()
  3. 验证数据完整性

    javascript
    // 统计集合文档数
    db.collection.countDocuments()
    
    // 抽样检查数据
    db.collection.aggregate([
      { $sample: { size: 10 } },
      { $project: { _id: 1, keyField: 1 } }
    ])

常见恢复场景

单个分片故障恢复

  1. 隔离故障分片

    javascript
    // 移除故障分片
    sh.removeShard("shard1rs")
  2. 恢复分片数据:按照单个分片恢复步骤操作

  3. 重新添加分片

    javascript
    sh.addShard("shard1rs/shard1-primary:27018")
  4. 平衡数据

    javascript
    // 启用平衡器
    sh.setBalancerState(true)
    
    // 等待平衡完成
    sh.getBalancerState()

配置服务器故障恢复

  1. 恢复单个配置服务器

    bash
    # 停止故障配置服务器
    sudo systemctl stop mongod-config2
    
    # 清理数据目录
    rm -rf /data/configdb2/*
    
    # 从正常配置服务器同步数据
    mongod --configsvr --replSet configrs --dbpath /data/configdb2 --port 27019 --bind_ip 0.0.0.0
  2. 重新加入配置服务器副本集

    javascript
    // 连接到主配置服务器
    mongosh --host config1:27019
    
    // 重新添加配置服务器
    rs.reconfig({
      _id: "configrs",
      configsvr: true,
      members: [
        { _id: 0, host: "config1:27019" },
        { _id: 1, host: "config2:27019" },
        { _id: 2, host: "config3:27019" }
      ]
    })

mongos路由故障恢复

  1. 停止故障mongos

    bash
    sudo systemctl stop mongos
  2. 检查配置文件:验证mongos配置正确性

  3. 重启mongos

    bash
    sudo systemctl start mongos
  4. 验证连接

    bash
    mongosh --host mongos:27017 --eval "db.runCommand({ ping: 1 })"

恢复后优化

索引重建

  • 检查索引状态

    javascript
    db.collection.getIndexes()
  • 重建索引

    javascript
    // 重建单个索引
    db.collection.reIndex("indexName")
    
    // 重建所有索引
    db.collection.reIndex()

平衡器优化

  • 调整平衡器窗口

    javascript
    // 设置平衡器窗口
    sh.setBalancerWindow({
      start: "22:00",
      stop: "06:00"
    })
  • 调整块大小

    javascript
    // 调整默认块大小为128MB
    db.adminCommand({ setDefaultChunkSize: 128 })

监控恢复后的性能

  • 监控分片状态

    javascript
    sh.status()
  • 监控操作性能

    javascript
    // 查看慢查询
    db.collection.find().explain()
    
    // 查看操作统计
    db.serverStatus().opcounters

常见问题(FAQ)

Q1: 分片集群恢复的最佳实践是什么?

A1: 分片集群恢复的最佳实践:

  • 严格按照配置服务器→分片→mongos路由的顺序恢复
  • 恢复前备份现有数据
  • 验证备份完整性
  • 恢复后进行数据一致性检查
  • 监控恢复后的性能

Q2: 如何处理单个分片故障?

A2: 单个分片故障处理步骤:

  1. 隔离故障分片
  2. 从备份恢复分片数据
  3. 重新加入集群
  4. 启动平衡器平衡数据

Q3: 配置服务器全部故障如何恢复?

A3: 配置服务器全部故障恢复:

  1. 从最新备份恢复主配置服务器
  2. 初始化配置服务器副本集
  3. 恢复其他配置服务器,加入副本集
  4. 验证配置数据完整性

Q4: 恢复后数据不一致怎么办?

A4: 数据不一致处理方法:

  • 检查分片数据分布
  • 验证配置数据一致性
  • 使用db.collection.validate()检查集合完整性
  • 考虑从一致性备份重新恢复

Q5: 如何优化恢复速度?

A5: 恢复速度优化建议:

  • 使用物理备份恢复(如文件复制)
  • 调整mongorestore的并行度(--numParallelCollections)
  • 恢复时禁用索引构建,恢复后重建
  • 使用高性能存储设备

Q6: 恢复后平衡器不工作怎么办?

A6: 平衡器不工作的解决方法:

  • 检查平衡器状态:sh.getBalancerState()
  • 查看平衡器日志
  • 检查分片连接状态
  • 手动触发平衡:sh.startBalancer()
  • 检查块分布:db.collection.getShardDistribution()