У меня есть набор реплик с 3 узлами (первичный + 2 вторичных). Все они работают под управлением Mongo 4.0.18 с использованием движка MMAPv1. Я пытаюсь переключить набор реплик на использование WiredTiger.
Я прочитал учебник MongoDB о том, как Измените набор реплик на WiredTiger. В этом руководстве рассказывается, как изменить каждый узел. на месте: перевести в офлайн, перенастроить, вернуть в онлайн. Я не следую этим инструкциям как есть, но вместо этого хочу представить новый узлов в набор реплик и (когда все будет хорошо) списать старые узлы из набора.
Я запустил новый экземпляр AWS EC2 с Mongo, настроенным для WiredTiger, и вручную добавил его в набор реплик, следуя инструкциям Добавить участников в набор реплик руководство. (По сути, rs.add({ host: ip_of_new_instance + ":27017", priority: 0, votes: 0 })
)
Новый узел переключает состояние с OTHER
к STARTUP2
, населяет dbPath
папка с множеством новых collection-*
и index-*
файлы и в конечном итоге переключает состояние на SECONDARY
. Все выглядит хорошо. Я могу видеть все коллекции / документы через mongo
оболочка при запуске $ mongo db_name
с нового узла, и я все еще могу получить доступ к основному, запустив $ mongo 'mongodb://username:password@mongodb.private:27017/db_name?authSource=admin&replicaSet=rs0'
.
ТЕМ НЕ МЕНИЕ, в момент перехода нового узла из STARTUP2 в SECONDARY мое приложение начинает давать сбой, сообщая об ошибке Mongo:
Cache Reader Не найдены ключи для HMAC, действительные для времени: {ts: Timestamp (1591711351, 1)} с идентификатором: 6817586637606748161
Мне не удалось воспроизвести эту ошибку Mongo вне приложения (Rocket.Chat, построенный на платформе Meteor). Возможно, проблема в этом. Или, возможно, приложение делает что-то, чего я не пробовал из оболочки mongo, например отслеживание oplog. [Обновление: я пробовал, но не уверен, что делаю правильно: db.oplog.rs.find().tailable({ awaitData: true })
возвращает дюжину документов, прежде чем запрашивать it
]
Однако если я начну процесс создания нового узла с нуля, просто изменив один вещь - установите storage.engine на mmapv1 вместо wiredTiger - тогда все работает хорошо. Мое приложение работает нормально. Я не знаю, почему приложение работает, когда все узлы работают под управлением mmapv1, но не работает, когда есть узел wiredTiger, тем более что механизм - это внутреннее устройство узла, непрозрачное для клиента.
Я заметил странное несоответствие между запуском mmapv1 и wiredTiger. Узел, на котором запущен wiredTiger, включает два ключа (operationTime
и $clusterTime
) в ответ на определенные команды (например, db.adminCommand({ getParameter: '*' })
). Ни один из узлов mmapv1 (новый или старый) не включает эти ключи в свои ответы. Поскольку сообщение об ошибке Mongo в журналах моего приложения содержит ссылку на время, Я очень подозреваю, что наличие $clusterTime
только на узле wiredTiger каким-то образом связано с основной проблемой.
Я не знаю, как это исправить. Я искал решения в Google, но не нашел серьезных зацепок - только несколько ссылок на это сообщение об ошибке, ни одна из которых не кажется полностью верной: