Ubuntu 22.04 上 apt 安装的 mongodb-org 默认不支持副本集,因其配置文件未启用 replication 块且 systemd 启动脚本未传 --replSet 参数;需为每个节点创建独立 service 文件、显式配置 replSetName、bindIp、oplogSizeMB,并在启用认证时预先创建 clusterAdmin 用户。

为什么 Ubuntu 22.04 上直接 apt 安装的 mongodb-org 默认不支持副本集?
因为 mongodb-org 包默认安装的是单节点配置,/etc/mongod.conf 中没有启用 replication 配置块,且 systemd 启动脚本未传入 --replSet 参数。即使你手动加了 replSetName,mongod 也会拒绝启动并报错:replSet was not specified on the command line or in config file。这不是 bug,是设计使然:APT 安装包面向通用场景,默认禁用复制功能以避免误配引发数据不一致。
如何用 systemd 管理三个副本集节点(非 Docker)?
不能共用同一个 mongod.service 单元。必须为每个实例创建独立 service 文件,例如:
-
/etc/systemd/system/mongod-node1.service:绑定27017,dbPath指向/data/db1 -
/etc/systemd/system/mongod-node2.service:绑定27018,dbPath指向/data/db2 -
/etc/systemd/system/mongod-node3.service:绑定27019,dbPath指向/data/db3
每个 service 文件中 ExecStart 必须显式带 --replSet rs0 和 --bind_ip 127.0.0.1,192.168.x.x(若跨机器则填真实内网 IP)。配置文件里 replication.replSetName 必须与命令行一致,否则初始化失败。启动顺序无关紧要,但首次运行前所有节点的 dbPath 必须为空目录(否则会因 oplog 不匹配拒绝加入副本集)。
初始化副本集时最常见的连接失败原因
在 mongosh 中执行 rs.initiate() 前,确保:
- 三个节点都已
systemctl start mongod-node1成功,且systemctl status mongod-node1显示active (running) - 每个节点的
mongod.conf中net.bindIp包含本地 IP(如127.0.0.1,192.168.1.10),不能只写127.0.0.1或0.0.0.0(后者在启用访问控制后会被拒绝) - 防火墙放行对应端口:
sudo ufw allow 27017 && sudo ufw allow 27018 && sudo ufw allow 27019 - 连接时用完整 host:port:
mongosh "mongodb://192.168.1.10:27017,192.168.1.10:27018,192.168.1.10:27019/?replicaSet=rs0",而不是只连一个地址
如果 rs.status() 返回 "members" : [] 或成员状态为 STARTUP 长时间不变化,大概率是网络互通性或 bindIp 配置错误。
启用访问控制后,副本集初始化必须提前创建用户
一旦在 mongod.conf 中设置了 security.authorization: enabled,就必须在 rs.initiate() 之前,在**每个节点的 admin 数据库中创建具有 clusterAdmin 角色的用户**,否则初始化过程无法完成内部认证。示例:
use admin
db.createUser({
user: "repluser",
pwd: "strongPass123!",
roles: ["clusterAdmin"]
})
然后在连接字符串中带上认证信息:mongosh -u repluser -p strongPass123! --authenticationDatabase admin "mongodb://..."。注意:这个用户不是用于应用连接的,而是副本集内部通信和初始化所必需的;应用连接应使用单独的、权限最小化的数据库用户。
副本集真正稳定前,最容易被忽略的是 oplog 大小——Ubuntu 默认 /data/db 分区往往太小,而 oplog.rs 默认占 5% 的磁盘空间。如果日志写入频繁,几小时就可能填满,导致 secondary 节点同步中断。务必在 mongod.conf 中显式设置 replication.oplogSizeMB(例如 1024),并在初始化后用 rs.printSecondaryReplicationInfo() 检查 lag 是否持续增长。











