MongoDB: NotWritablePrimary при записи
В наборе репликации писать можно только на основной узел. Сообщение об отсутствии права на запись означает, что узел стал вторичным — из-за выборов, потери связи или намеренного переключения.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Прошли выборы, и основным стал другой узел
Выборы запускаются при потере связи или перезапуске. Приложение, подключённое к конкретному адресу, продолжает писать на теперь уже вторичный узел.
-
Набор не может выбрать основной узел
Без большинства голосов выборы не проходят, и записи нет вовсе. Частая ситуация при двух узлах из трёх недоступных.
-
Узел намеренно выведен из выборов
Узел с приоритетом ноль или в режиме сокрытия не станет основным. Это сделано осознанно и меняется настройкой набора.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Состояние набора репликации.
mongosh --quiet --eval "rs.status()" | head -40Записи о выборах и смене роли.
journalctl -u mongod -n 40 --no-pager | grep -iE "election|primary"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Выборы запускаются при потере связи или перезапуске. Приложение, подключённое к конкретному адресу, продолжает писать на теперь уже вторичный узел.
- Как проверить
-
Посмотрите состояние набора.
mongosh --quiet --eval "rs.status().members.map(m => m.name + ' ' + m.stateStr)" 2>/dev/null
- Как исправить
- Приложение должно подключаться к набору, а не к отдельному адресу: тогда выбор основного узла произойдёт автоматически.
- Почему происходит
- Без большинства голосов выборы не проходят, и записи нет вовсе. Частая ситуация при двух узлах из трёх недоступных.
- Как проверить
-
Посмотрите доступность узлов.
mongosh --quiet --eval "rs.status().members.map(m => m.name + ' ' + m.health)" 2>/dev/null
- Как исправить
- Восстановите связь с большинством узлов. Набор из двух узлов не переживает потерю одного — для этого добавляют арбитра или третий узел.
- Почему происходит
- Узел с приоритетом ноль или в режиме сокрытия не станет основным. Это сделано осознанно и меняется настройкой набора.
- Как проверить
-
Посмотрите настройки набора.
mongosh --quiet --eval "rs.conf().members.map(m => m.host + ' priority=' + m.priority)" 2>/dev/null
- Как исправить
- Меняйте приоритеты настройкой набора, а не перезапуском узлов.
Пример вывода
Узел стал вторичным после выборов. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
mongod[1200]: {"s":"I","c":"REPL","msg":"Stepping down from primary"}
app[4100]: MongoServerError: not primary and secondaryOk=false
mongod[1200]: {"s":"I","c":"REPL","msg":"Starting an election, since we've seen no PRIMARY"}
Связанные ошибки
- MongoDB: Unable to lock file mongod.lock mongod не запускается: остался файл блокировки после аварийного завершения или каталог принадлежит не тому пользователю.
- Connection refused в журнале службы Соединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- HAProxy: cannot bind socket и плавающий адрес HAProxy не запускается на пассивном узле кластера: адрес не поднят. Параметр ip_nonlocal_bind.
- MariaDB Galera: узел не стартует без bootstrap Кластер Galera не поднимается после полной остановки: нужен запуск первого узла особой командой и файл grastate.dat.
- Apache: Invalid command — не включён модуль Apache не запускается: директива требует модуль, который не подключён. Как найти нужный модуль и включить.
- Apache: could not bind to address Apache не занимает порт: конфликт с nginx, порт занят, нет прав на привилегированный порт.
- Apache: конфликт модулей многопроцессности и PHP Apache не запускается после включения модуля PHP: несовместимость с выбранным модулем многопроцессности.
- Apache: правила .htaccess не действуют Файл .htaccess игнорируется: запрещён параметром AllowOverride, нет нужного модуля, файл не читается.
Где встречается чаще всего
Источники
- Документация MongoDB: наборы репликации
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено остановкой основного узла в тестовом наборе из трёх узлов.