必须先停服并备份,否则 rs.initiate 会失败;需执行 db.shutdownServer() 停服、mongodump 全量备份、清空 local 目录,并确保配置文件 YAML 缩进正确、host 可解析、连接串含 replicaSet 参数且 driver 版本 ≥4.0。

必须先停服并备份,否则 rs.initiate 会失败
单机升级副本集不是“加个配置重启就行”,rs.initiate() 要求节点处于干净、未初始化状态。如果原单机服务正在运行且已有数据,直接启动 --replSet 并执行 rs.initiate() 会报错:already initialized 或 replica set ID mismatch。
实操建议:
- 先连接原单机实例,执行
db.shutdownServer()停止服务 - 用
mongodump -o /backup/$(date +%Y%m%d)全量备份(尤其含--authenticationDatabase参数时) - 确认
dbPath目录下没有local数据库文件夹(它由副本集自动生成,残留会导致冲突) - Windows 用户注意:若用服务方式运行,需用
sc stop MongoDB停止服务,再删掉data/db/local
配置文件里加 replication: replSetName 是基础,但缩进和空格不能错
在 mongod.conf 中添加副本集名称,看似简单,但 YAML 格式极其敏感。常见错误是复制粘贴导致缩进用 Tab 或混用空格,结果 mongod 启动失败,日志报 Invalid config file。
正确写法(以 rs0 为例):
replication: replSetName: rs0
关键点:
-
replication:和replSetName:必须顶格,冒号后跟一个空格 -
replSetName:下方内容必须缩进 2 个空格(不是 Tab,不是 4 个空格) - Linux 下可执行
mongod --config /etc/mongod.conf --dryRun验证配置语法 - Windows 用户若用命令行启动(不依赖 config),必须显式加
--replSet rs0参数
rs.initiate() 传 config 对象时,host 必须可被所有成员解析
即使你只搭单节点伪副本集(开发用),rs.initiate(config) 中的 host 字段也不能写 127.0.0.1 或 localhost——因为副本集成员之间要互相通信,而 localhost 在不同机器上指向不同地址。
典型场景与处理:
- 本地开发单机伪副本集:用
host: "127.0.0.1:27017"可行,但后续加 secondary 时必须统一改用局域网 IP - 生产环境多机部署:所有
host值必须是其他节点能 ping 通的 IP(如"192.168.1.10:27017"),不能混用域名和 IP - 仲裁节点(arbiterOnly)也要填真实可访问的 host,否则
rs.status()显示REMOVED或STARTUP2卡住 - 初始化后立刻执行
rs.status(),若看到health: 0,大概率是网络不通或防火墙拦了 27017 端口
升级后应用连接字符串必须带 replicaSet 参数
副本集启用后,旧连接串 mongodb://127.0.0.1:27017/mydb 仍能连上,但事务、读写偏好(readPreference)、自动故障转移等功能全部失效。不改连接串,等于白配副本集。
必须改成:
mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/mydb?replicaSet=rs0
注意事项:
- 多个 host 用英文逗号分隔,末尾不能有逗号
-
?replicaSet=rs0中的rs0必须和配置文件里replSetName完全一致(大小写敏感) - Driver 版本要 ≥ 4.0(老版本如 pymongo 3.x 不支持 replicaSet 查询参数)
- Spring Boot 应用需在
spring.data.mongodb.uri中显式加?replicaSet=...,否则@Transactional抛Transaction numbers are only allowed on a replica set member
local 数据库里的 oplog.rs 大小默认只有 5% 磁盘空间(Linux)或 192MB(Windows),而 oplog 是故障恢复和同步的唯一依据。如果业务写入量大,这个默认值撑不过几小时,secondary 就会因 oplog 截断无法追上 primary。上线前务必检查并按需调大:db.runCommand({replSetResizeOplog: 1, size: 2048})(单位 MB)。


















