运维,数据库··约 8 分钟读完
MongoDB 副本集搭建遇到的 10 个坑及解决方法
MongoDB副本集搭建避坑指南 本文总结了Docker+物理机混合部署MongoDB副本集时常见的10个问题及解决方案。核心问题集中在: Keyfile配置:权限需设为400且属主为mongodb用户(UID 999),主从库必须使用相同文件(占问题70%) 网络与端口:容器初始化需用内部端口(27017),避免--network host与-p参数冲突 数据残留:从库若曾独立初始化需清除/data目录重建 版本一致性:主从版本差异可能导致同步异常,建议主库版本≤从库 认证流程:应先关闭--auth创建首
数据库mongodb
MongoDB 副本集搭建遇到的 10 个坑及解决方法
本文记录了在 Docker + 物理机混合部署 MongoDB 副本集过程中踩过的所有坑,附完整解决方案。
坑 1:rs.initiate() 初始化失败
报错:
No host described in new configuration 1 for replica set rs0 maps to this node
原因:Docker 容器内 docker exec 执行时,MongoDB 监听的是容器内部端口(默认 27017),但 host 字段填了宿主机映射端口(如 8017)。
解决:
# ❌ 错误(写了宿主机端口)
docker exec mongo_node1 mongo --eval 'rs.initiate({members:[{_id:0, host:"127.0.0.1:8017"}]})'
# ✅ 正确(写容器内部端口)
docker exec mongo_node1 mongo --eval 'rs.initiate({members:[{_id:0, host:"127.0.0.1:27017"}]})'
坑 2:添加从库时 Authentication failed
报错:
39.105.184.238:8017 failed with Authentication failed
原因:主库用了 --keyFile 启动(节点间认证),但从库没配 keyfile。
解决:主从必须使用相同的 keyfile,从库启动时加 --keyFile 参数:
docker run -d --name mongo_node1 \
-v /data/mongodb.key:/data/mongodb.key:ro \
mongo:3.6.23 \
mongod --replSet rs0 --keyFile /data/mongodb.key
坑 3:Keyfile 文件路径错误
报错:
Error reading file /data/mongodb.key: No such file or directory
原因:-v 挂载时宿主机路径指向了不存在的文件。
解决:
# 确认宿主机文件存在
ls -la /data/mongodb.key
# 确认挂载参数正确
-v /data/mongodb.key:/data/mongodb.key:ro
# ↑ 宿主机路径 ↑ 容器内路径
坑 4:Keyfile Permission denied
报错:
error opening file: /data/mongodb.key: Permission denied
原因:keyfile 权限是 400,但属主是 root。容器内 MongoDB 使用 mongodb 用户(uid 999),读不了 root 的文件。
解决:
chown 999:999 /data/mongodb.key
坑 5:Keyfile permissions are too open
报错:
permissions on /data/mongodb.key are too open
原因:MongoDB 要求 keyfile 权限 ≤ 400。
解决:
chmod 400 /data/mongodb.key
坑 6:Received heartbeat from member with the same member ID
报错:
Received heartbeat from member with the same member ID as ourself: 0
原因:从库之前执行过 rs.initiate(),导致 _id: 0 和主库冲突。MongoDB 的 local.system.replset 中残留了旧配置。
解决:彻底清除从库数据:
docker stop mongo_node1 && docker rm mongo_node1
rm -rf /data/mongo/sec/*
# 重新启动容器后,在主库重新 rs.add()
坑 7:--network host 和 -p 冲突
报错:无报错,但端口映射不生效。
原因:
# ❌ 这两个参数互斥
docker run --network host -p 8017:27017 ...
二选一:
# 方案 A:host 网络(端口自动暴露)
docker run --network host ...
# 方案 B:bridge 网络 + 端口映射
docker run -p 8017:27017 ...
坑 8:主从 MongoDB 版本不一致
现象:
WARNING: shell and server versions do not match
MongoDB server version: 2.6.10
原因:主库是 2.6,从库是 3.6,差三个大版本。
风险:
- oplog 格式可能不兼容
- 同步可能出现意外行为
- 部分命令行为不同
建议:尽量统一版本,主库版本 ≤ 从库版本。
坑 9:--auth 模式下无法创建第一个用户
报错:
Error: couldn't add user: there are no users authenticated
原因:--auth 开启后需要先有用户才能操作,但还没创建第一个用户,死循环了。
解决:暂时关掉 --auth 创建用户后再开启:
# 1. 不带 --auth 启动
mongod -f mongod.conf # 先注释 security.authorization
# 2. 创建用户
mongo admin --eval 'db.createUser({user:"admin", pwd:"123456", roles:[{role:"root", db:"admin"}]})'
# 3. 开启 --auth 重启
mongod -f mongod.conf # 恢复 security.authorization
坑 10:rs.add() 长时间卡住 / 超时
现象:执行 rs.add() 后没有返回,或 SSH 超时。
排查步骤:
# 1. 检查网络
ping 从库IP
telnet 从库IP 8017
# 2. 检查从库日志
docker logs mongo_node1 --tail 20
# 3. 检查从库能否连上主库
docker exec mongo_node1 mongo 主库IP:8017 --eval 'rs.status()'
# 4. 确认 keyfile 一致
md5sum /data/mongodb.key # 对比主从两边是否一样
总结
10 个坑中,70% 是 keyfile 相关(路径、权限、内容不一致),20% 是端口和网络配置,10% 是数据残留。
如果从头搭建一次,建议按这个顺序:
- 主库启动并初始化(不开 auth)
- 配好 keyfile(chmod 400 + chown 999:999)
- 从库启动并加入副本集
- 验证同步状态
- 创建用户并开启 auth
- 应用连接测试