wei/个人文档/MongoDB副本集.md
2026-06-04 13:57:41 +08:00

5.9 KiB
Raw Permalink Blame History

不需要手动同步数据。MongoDB副本集会自动同步数据。但是根据你10上已有数据的大小初始化同步的方式会有所不同。

1. 两种同步方式

A. 初始同步Initial Sync- 自动进行

如果11是全新的没有数据MongoDB会自动执行初始同步

  • 11会从10复制所有数据
  • 自动创建所有数据库和集合
  • 自动复制所有索引
  • 整个过程自动完成,无需人工干预

B. 增量同步

如果11已经有部分数据MongoDB会使用增量同步

  • 从oplog中复制自上次同步以来的变化
  • 自动补全缺失的数据

2. 正确搭建步骤10已有数据

步骤1配置10已有数据的主节点

确保10的配置文件正确

# /usr/local/mongodb/conf/mongo.conf
net:
  port: 37017
  bindIp: 0.0.0.0

storage:
  dbPath: /usr/local/mongodb/data  # 这里已经有数据

systemLog:
  destination: file
  path: /usr/local/mongodb/logs/mongodb.log
  logAppend: true

processManagement:
  fork: true

replication:
  replSetName: rs0

启动10

/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/conf/mongo.conf

步骤2准备11从节点

重要确保11的数据目录是空的或不存在

# 在11上执行
# 停止MongoDB如果正在运行
pkill mongod

# 清空数据目录(如果已有数据)
rm -rf /usr/local/mongodb/data/*
# 或者备份后删除

# 确保目录存在
mkdir -p /usr/local/mongodb/data

11的配置文件与10相同启动11

/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/conf/mongo.conf

步骤3初始化副本集在10上

连接到10

/usr/local/mongodb/bin/mongo --host 192.168.124.10 --port 37017

初始化副本集,只添加10自己

// 先只添加10自己
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "10.101.2.197:37017", priority: 10 }
  ]
})

等待几秒确认10已成为主节点

rs.status()

步骤4添加从节点11

// 添加11作为从节点
rs.add({ host: "10.101.3.43:37017", priority: 1 })

// 或者更详细的配置
rs.add({
  host: "192.168.124.11:37017",
  priority: 1,
  votes: 1,
  hidden: false,
  slaveDelay: 0
})

可重新配置权重

// 获取当前配置
var cfg = rs.conf();

// 修改对应ID 权重
cfg.members[0].priority = 10; // _id: 0 
cfg.members[1].priority = 1;  // _id: 1 

//应用新配置
rs.reconfig(cfg);

3. 监控同步进度

查看同步状态:

// 在10上查看
rs.status()

// 重点关注11的状态
rs.status().members[1]

查看同步进度:

// 在11上执行
rs.slaveOk()  // 3.6版本用这个
use local
db.oplog.rs.find().sort({$natural: -1}).limit(1)

// 查看正在同步的数据库
db.currentOp().inprog.forEach(function(op) {
  if (op.msg && op.msg.indexOf("initial sync") !== -1) {
    printjson(op);
  }
})

查看数据同步详情:

// 在11上查看各数据库同步状态
show dbs

// 查看具体集合的数据量
use your_database_name
db.collection_name.count()

4. 同步过程的注意事项

数据量大时的建议:

  1. 网络带宽确保10和11之间的网络畅通
  2. oplog大小检查10的oplog是否足够大
    use local
    db.oplog.rs.stats()
    
  3. 磁盘空间确保11有足够的磁盘空间

如果同步中断:

// 查看同步错误
rs.status().members[1].lastHeartbeatMessage

// 重启同步
rs.syncFrom("192.168.124.10:37017")

5. 验证同步完成

检查点:

  1. 状态检查

    rs.status().members[1].stateStr === "SECONDARY"
    rs.status().members[1].health === 1
    
  2. 数据一致性检查

    // 在10上
    use your_database
    db.stats()
    
    // 在11上启用读取后
    rs.slaveOk()
    use your_database
    db.stats()  // 应该与10相同
    
  3. 索引检查

    // 在10上
    db.collection.getIndexes()
    
    // 在11上
    db.collection.getIndexes()  // 应该相同
    

6. 设置10始终为主节点

// 确保10优先级更高
var cfg = rs.conf();
cfg.members[0].priority = 10;  // 10的优先级很高
cfg.members[1].priority = 1;   // 11的优先级较低
rs.reconfig(cfg);

7. 特殊情况的处理

情况1数据量非常大TB级

如果数据量非常大,初始同步可能很慢,可以考虑:

  1. 使用物理备份恢复:

    # 在10上创建备份
    mongodump --host 192.168.124.10 --port 37017 --out /backup/
    
    # 在11上恢复
    mongorestore --host 192.168.124.11 --port 37017 /backup/
    
  2. 然后添加到副本集

情况2需要保证业务连续性

可以在业务低峰期执行:

// 设置11的优先级为0暂时不参与选举
rs.add({ host: "192.168.124.11:37017", priority: 0 })

// 等待同步完成
// 然后修改优先级
var cfg = rs.conf();
cfg.members[1].priority = 1;
rs.reconfig(cfg);

8. 最佳实践建议

  1. 顺序很重要

    • 先启动并配置主节点10
    • 再启动从节点11数据目录为空
    • 最后添加从节点到副本集
  2. 监控同步

    // 定期检查同步状态
    while (true) {
      printjson(rs.status().members[1]);
      sleep(5000);  // 每5秒检查一次
    }
    
  3. 性能考虑

    • 初始同步期间10的负载会增加
    • 考虑在业务低峰期操作
    • 监控网络流量和磁盘IO

总结

你不需要手动同步数据MongoDB会自动完成。你需要做的

  1. 确保10已有数据并正确配置
  2. 确保11的数据目录是空的
  3. 先初始化10为单成员副本集
  4. 然后添加11自动同步开始
  5. 设置优先级确保10始终为主

整个过程是自动化的MongoDB会处理所有的数据复制和同步工作。