自动切换后连接报错主因是客户端或驱动仍连旧主主机名,需确保rs.conf().members中所有host在各节点可解析、/etc/hosts同步、ip为真实内网地址、连接串含replicaset参数、各host端口可达、驱动版本达标且sdam拓扑日志显示replicasetwithprimary。

自动切换后连接报错,大概率不是切换本身出问题,而是客户端或驱动仍尝试连旧主节点的主机名,而该主机名此时已无法解析或指向错误 IP。
rs.conf().members 中的 host 名是否能在所有节点上解析
副本集配置里每个 members[i].host 的值(比如 mongo2.example.com:27017)必须在所有成员节点(包括新主、旧主、客户端所在机器)上都能被 getent hosts mongo2.example.com 或 nslookup mongo2.example.com 正确返回可路由的真实 IP。DNS 缓存、/etc/hosts 写错、大小写不一致、多空格都会导致解析失败。
- 检查命令:
hostname -f输出必须和rs.conf().members[i].host左侧完全一致(不含端口) - 所有节点的
/etc/hosts必须同步更新,不能只改一台;IP 不能写127.0.0.1,必须是其他节点能直接访问的真实内网 IP - 修改后运行
nscd -i hosts清缓存,或临时停用systemd-resolved避免干扰
客户端连接字符串是否含 replicaSet 参数且 host 可达
如果连接串里没带 replicaSet=xxx,驱动根本不会启用 SDAM(Server Discovery and Monitoring),也就不会感知主从变化,只会死连第一个 host —— 切换后必然报 NotPrimaryError 或 MongoNetworkError。
- 连接串必须形如:
mongodb://node1:27017,node2:27017,node3:27017/?replicaSet=myrs - 每个 host 都要能
telnet node1 27017通,否则 SDAM 初始化阶段就失败,后续一切免谈 - Java 驱动需 v4.7+,Node.js 需 v5.0+,老版本即使写了
replicaSet也不自动刷新拓扑
驱动日志里 topologyDescription 是否已更新为 ReplicaSetWithPrimary
SDAM 机制是否真正生效,不能只看应用有没有报错,得看驱动底层是否完成了拓扑重建。关键线索藏在拓扑状态日志里。
- Java:开
DEBUG日志,搜topologyDescription,确认有类似ReplicaSetNoPrimary → ReplicaSetWithPrimary的状态跃迁 - Node.js:启动时加
loggerLevel: 'debug',观察是否出现server description updated和新主节点标记为isWritablePrimary: true - 若日志卡在
ReplicaSetNoPrimary,说明至少一个 member.host 解析失败或端口不通,驱动放弃选举
最容易被忽略的是:哪怕 DNS 正常、rs.conf() 看着没问题,只要任意一个 member.host 在客户端机器上 ping 不通或 telnet 不通,SDAM 就会拒绝将整个副本集视为可用 —— 它不挑节点,只认全部在线且可通信。











