Решил я как-то перевести свой MongoDB на нормальные рельсы — чтобы управлялся через service, статус показывал, логи в journald писал, и вообще как у людей. До этого я его запускал вручную:
mongod --config /etc/mongod.conf --fork --logpath /var/log/mongodb/mongod.log
Работало, но статус непонятно какой, и каждый раз при старте системы нужно было не забыть запустить. Неудобно.
Думаю: сейчас сделаю sudo systemctl enable mongod, потом sudo systemctl start mongod, и живи спокойно. Ага, щас.
Первая попытка — фиаско с логами
Запускаю
sudo systemctl start mongod
Смотрю статус — failed.
sudo systemctl status mongod
Вижу какую-то кракозябру: code=exited, status=1/FAILURE. Непонятно, лезу в полный лог сервиса:
sudo journalctl -u mongod -n 30
А там чётко написано:
Failed to open /var/log/mongodb/mongod.log
Ну, думаю, классика. Раньше я запускал mongod от своего пользователя, и файл лога создался с правами seligoroff:seligoroff. А сервис пытается работать от пользователя mongodb. Он туда просто не может писать.
Исправляю:
sudo chown -R mongodb:mongodb /var/log/mongodb
Отлично, думаю, теперь-то всё поедет.
Снова
sudo systemctl start mongod
Смотрю статус — опять failed, но теперь ошибка status=14. И в journalctl — пусто, даже фатальной строки нет. Странно.
Вторая попытка — ошибка стала загадочной
status=14— что за зверь? Гуглю, нахожу что-то про проблемы с доступом к данным или сокетам. Проверяю /var/lib/mongodb — права все на mongodb, lock-файла нет.
sudo netstat -tulpn | grep 27018
Порт 27018 свободен. Ничего не горит.
Тогда решаю пойти старым дедовским способом — запустить mongod вручную, но от того же пользователя, от которого работает сервис, и без –fork, чтобы все ошибки вывалились в консоль.
Пишу:
sudo -u mongodb mongod --config /etc/mongod.conf
И… тишина. Просто возвращает управление. Процесса нет. Что за чертовщина?
Тогда добавляю –fork и временный лог-файл:
sudo -u mongodb mongod --config /etc/mongod.conf --fork --logpath /tmp/mongod_manual.log
Вижу сообщение: child process failed, exited with 1. И совет — запустить без –fork. Понял, ловлю ошибку в логе:
sudo cat /tmp/mongod_manual.log
И тут — бинго! Среди обычных строк вижу:
Failed to unlink socket file /tmp/mongodb-27018.sock: Operation not permitted
Вот оно что! Оказывается, когда я раньше запускал mongod от своего пользователя, он создал в /tmp сокет-файл mongodb-27018.sock. А теперь сервис от пользователя mongodb пытается его удалить при старте, но у него прав нет. И тихо падает.
Решение — пять секунд
Удаляю этот бедный сокет ручками:
sudo rm -f /tmp/mongodb-27018.sock
Запускаю сервис:
sudo systemctl start mongod
Смотрю статус:
● mongod.service - active (running)
Ура! Заработало.
Что я вынес из этого
- Если сервис падает с непонятным кодом — запускай процесс вручную от того же пользователя, под которым работает сервис, и без демонизации (–fork). Увидишь всю подноготную.
- Не забывай про временные файлы. Сокеты в /tmp — тоже часть состояния, и они могут оставаться от прошлых запусков от другого юзера.
- Права на логи — это только полбеды. Проверяй всё: и данные, и сокеты, и lock-файлы.
Теперь мой MongoDB стартует через systemd, логи пишет куда надо, и я наконец-то могу делать sudo systemctl status mongod и видеть, что всё ок. Спокойствие, только спокойствие.
