我有一个 3 节点副本集(主节点 + 2 个从节点)。它们都使用 MMAPv1 引擎运行 Mongo 4.0.18。我正在尝试将副本集切换为使用 WiredTiger。
我阅读了 MongoDB 教程,了解如何将副本集更改为WiredTiger。该教程指导如何更改每个节点就地:将其脱机、重新配置、重新联机。我不会原封不动地遵循这些说明,而是想介绍新的节点到副本集并且(当一切正常时)从集合中退役旧节点。
我启动了一个新的 AWS EC2 实例,其中为 WiredTiger 配置了 Mongo,并手动将其添加到副本集中,如下所示将成员添加到副本集教程。(本质上,rs.add({ host: ip_of_new_instance + ":27017", priority: 0, votes: 0 })
)
新节点将状态从 切换OTHER
为STARTUP2
,dbPath
用许多新文件collection-*
和index-*
文件填充其文件夹,并最终将状态切换为。一切看起来都很好。从新节点运行时,SECONDARY
我可以通过 shell 查看所有集合/文档,并且我仍然可以通过运行 来访问主节点。mongo
$ mongo db_name
$ mongo 'mongodb://username:[email protected]:27017/db_name?authSource=admin&replicaSet=rs0'
然而当新节点从 STARTUP2 转换为 SECONDARY 时,我的应用程序开始失败,并报告 Mongo 错误:
缓存读取器未找到对时间有效的 HMAC 密钥:{ts:Timestamp(1591711351,1)},ID:6817586637606748161
我无法在应用程序(基于 Meteor 框架构建的 Rocket.Chat)之外重现此 Mongo 错误。也许问题就在这里。或者应用程序正在执行一些我尚未从 mongo shell 尝试过的操作,例如跟踪 oplog。[更新:我尝试过,但不确定我是否做对了:db.oplog.rs.find().tailable({ awaitData: true })
在提示之前返回了十几个文档it
]
但是,如果我从头开始启动新节点进程,只需更改一东西——将 storage.engine 设置为 mmapv1 而不是 wiredTiger——然后一切正常。我的应用程序正常运行。我不知道为什么当所有节点都在运行 mmapv1 时应用程序可以工作,但当有 wiredTiger 节点时却失败了,特别是因为引擎是节点内部的东西,对客户端不透明。
我注意到运行 mmapv1 和 wiredTiger 之间存在奇怪的差异。运行 wiredTiger 的节点在对某些命令(例如)的响应中包含两个键(operationTime
和) 。所有 mmapv1 节点(新节点或旧节点)均未在其响应中包含这些键。由于我的应用程序日志中的 Mongo 错误消息包含对$clusterTime
db.adminCommand({ getParameter: '*' })
时间,我非常怀疑$clusterTime
仅有的wiredTiger 节点上的问题与底层问题有某种关联。
我不知道该如何解决这个问题。我一直在谷歌上搜索解决方案,但没有找到任何有力的线索——只有几个提到该错误消息的地方,似乎都没有完全切中要害:
- https://stackoverflow.com/questions/60876115/error-while-converting-a-mongodb-cluster-into-a-replica-set
- https://developer.mongodb.com/community/forums/t/error-while-converting-a-cluster-into-a-replica-set/2022 (与上文重复)
- https://jira.mongodb.org/browse/SERVER-32845 “当收到带有 $clusterTime 的 isMaster 命令时,仲裁器失败”
- https://jira.mongodb.org/browse/SERVER-33947 “仲裁器使用 clusterTime 回复 isMaster “未找到对时间有效的 HMAC 密钥””
- https://jira.mongodb.org/browse/SERVER-32639 “一旦 FCV 检查被删除,独立副本集中的仲裁器就无法使用 auth on 签署或验证 clusterTime”(前两个被认为是这个的重复,尽管这个不包含那个错误消息)