几个小时前,我们运行实例的服务器发生了中断mongos
。解决根本问题后,mongos
无法启动并出现以下错误:
"ctx":"ReplicaSetMonitor-TaskExecutor","msg":"Invariant failure","attr":{"expr":"!groupAndId.groupData","file":"src/mongo/s/sharding_task_executor_pool_controller.cpp","line":134}
"ctx":"ReplicaSetMonitor-TaskExecutor","msg":"\n\n***aborting after invariant() failure\n\n"
"ctx":"ReplicaSetMonitor-TaskExecutor","msg":"Writing fatal message","attr":{"message":"Got signal: 6 (Aborted).\n"}
现在,其他mongos
需要mongod
重新启动的实例也无法启动并出现相同的错误 - 因此,随着时间的推移,它们可能都会一一失败并且无法再次启动。
我们的 MongoDB 集群包含 5 个数据分片和 1 个配置分片,每个分片由 3 个成员副本集组成。让我们标记每个数据分片 A、B、C、D、E,以及每个实例 A1、A2、A3、B1、B2 等...
仔细检查失败的mongos
实例后,我注意到 RSM 拓扑更改日志中出现了一些奇怪的情况。主机似乎在 replset 之间混淆了。请注意 replset-B 的拓扑更改,包含其集合中的 1 个主机,但包含其他集合的主机,但同时“setName”属性显示 replset-A。
"ctx":"ReplicaSetMonitor-TaskExecutor",
"msg":"RSM Topology Change",
"attr":{
"replicaSet":"replset-B",
"newTopologyDescription":"{
id: \"bfcaaf31-9ead-497b-85b9-1e98dbf97805\",
topologyType: \"ReplicaSetNoPrimary\",
servers: {
server-B1:27017: {
address: \"server-B1:27017\", type: \"Unknown\",
minWireVersion: 0, maxWireVersion: 0,
lastUpdateTime: new Date(-9223372036854775808),
hosts: {}, arbiters: {}, passives: {}
},
server-A1:27017: {
address: \"server-A1:27017\", type: \"Unknown\",
minWireVersion: 0, maxWireVersion: 0,
lastUpdateTime: new Date(-9223372036854775808),
hosts: {}, arbiters: {}, passives: {}
},
server-A2:27017: {
address: \"server-A2:27017\", type: \"Unknown\",
minWireVersion: 0, maxWireVersion: 0,
lastUpdateTime: new Date(-9223372036854775808),
hosts: {}, arbiters: {}, passives: {}
},
server-A3:27017: {
address: \"server-A3:27017\", type: \"Unknown\",
minWireVersion: 0, maxWireVersion: 0,
lastUpdateTime: new Date(-9223372036854775808),
hosts: {}, arbiters: {}, passives: {}
}
},
logicalSessionTimeoutMinutes: 30,
setName: \"replset-A\",
compatible: true
}",
"previousTopologyDescription":"{
id: \"2e9451c0-f13e-4d77-b9f9-6900ee5754ab\",
topologyType: \"Unknown\",
servers: {
server-B2:27017: {
address: \"server-B2:27017\", type: \"Unknown\",
minWireVersion: 0, maxWireVersion: 0,
lastUpdateTime: new Date(-9223372036854775808),
hosts: {}, arbiters: {}, passives: {}
},
server-B3:27017: {
address: \"server-B3:37017\", type: \"Unknown\",
minWireVersion: 0, maxWireVersion: 0,
lastUpdateTime: new Date(-9223372036854775808),
hosts: {}, arbiters: {}, passives: {}
}
},
compatible: true
}"
}
我sh.status()
在一个正常运行的mongos
实例上运行,你瞧,它shard-B
显示为replset-B/server-A1:27017,server-A2:27017,server-A3:27017
. 我不知道这是怎么发生的。我们这个集群已经运行了几年了,最后一次对拓扑的更改是在几周前添加了 shard-E。所有这些都mongod.conf
具有正确的 replSet 名称,在每个副本集的主节点上执行rs.conf()
和都没有显示出不一致的情况。rs.status()
我什至尝试config.shards
直接更新集合并通过配置主节点$set
为有问题的分片设置正确的主机mongos
,但它不仅不起作用(其他mongos
实例因相同的错误而失败),而且它恢复了回来一段时间后到旧的(错误的)连接字符串(我怀疑这也与ShardRegistry
更新的机制有关)。config.shards
运行db.runCommand({getShardMap: 1})
给出了以下结果(我怀疑这是某个地方发生冲突的另一个症状):
"connStrings" : {
...all good until...
"replset-B/server-A1:27017,server-A2:27017,server-A3:27017" : "shard-B",
}
我已经快无计可施了。停机并不是一个真正的选择,我想知道是否有更了解 MongoDB 内部运作的人可以分享一些对此的见解。
发现问题了。问题在于 DNS 配置 - 其中一台 B 服务器的主机名映射指向 A 服务器的 IP 地址。不知何故,这需要一段时间才能显现出来。