你现在的情况是:三台机器上都执行了 rs.initiate(),这会导致每台机器都独立地成为了自己的单节点副本集
(各自成为一个不同的副本集),它们彼此之间并不知道对方的存在,所以整个副本集无法形成。
🔥 问题本质
MongoDB 的副本集只能由一个节点执行一次 rs.initiate() 来初始化整个副本集。
你在三台机器上都执行了,相当于创建了三个互不相关的副本集,这是错误的操作。
✅ 正确做法(修复步骤)
✅ 步骤 1:停止所有节点上的 MongoDB 服务
清理数据目录(dbpath)
bash
复制
1 | # 每台机器上执行 |
✅ 步骤 2:清理副本集配置(每台机器都要做)
MongoDB 会把副本集配置保存在 local.replset 集合中,你需要清理掉这些配置。
bash
复制
1 | # 进入 MongoDB shell(单节点启动,不指定 replSet) |
⚠️ 注意:这个操作会清除副本集配置和 oplog,不会影响你的业务数据(除非你业务数据也放在 local 库)。
✅ 步骤 3:重新以副本集模式启动 MongoDB(所有节点)
bash
复制
1 | mongod --replSet rs0 --bind_ip 0.0.0.0 --dbpath /data/db --port 27017 --fork --logpath /var/log/mongod.log |
✅ 步骤 4:只在一个节点(主节点)上执行初始化
连接任意一台节点(建议选你希望的 PRIMARY),执行:
JavaScript
复制
1 | rs.initiate({ |
| 字段 | 含义 |
|---|---|
_id: "replicaset" |
创建或指定一个名为 replicaset 的副本集。 |
members |
列出这个副本集里的所有成员(节点)。 |
_id: 0/1/2 |
每个成员在副本集内的唯一标识符。 |
host |
每个成员的 IP:端口,告诉副本集怎么找到它们。 |
- 当前你连接的这台节点(假设是 192.168.0.245)会成为 PRIMARY。
- 它会尝试与 192.168.0.246、192.168.0.247 建立心跳连接。
- 如果这两台节点已经以
--replSet replicaset启动且数据目录干净,它们会进入 SECONDARY 状态。 - 最终形成一个 三节点副本集(1 主 2 从)。
✅ 步骤 5:验证副本集状态
JavaScript
复制
1 | rs.status() |
✅ 总结一句话
每台都执行
rs.initiate()是错误的,必须清理配置后,只用一台机器初始化整个副本集。
如你不确定该删哪个目录、如何备份,我可以帮你写个脚本。