MySQL в systemd: почему не запускается
MySQL под systemd падает в основном по трём причинам: права или состояние каталога данных, нехватка памяти при заданном размере буферного пула, и повреждение данных после аварийного завершения. Причина почти всегда в собственном журнале ошибок MySQL, а не в выводе systemd.
О службе
MySQL пишет подробный журнал ошибок в отдельный файл (обычно /var/log/mysql/error.log). В журнал systemd попадают лишь несколько строк, из которых причина не видна. Поэтому разбор всегда начинается с собственного файла: там и версия, и параметры запуска, и точное сообщение об ошибке.
Вторая особенность — память. Размер буферного пула InnoDB задаётся в настройках и выделяется при старте. Если он больше доступной памяти, сервер либо не стартует, либо его убивает ядро. На небольших виртуальных машинах это самая частая причина внезапных падений после увеличения настроек.
Третья — запуск от пользователя mysql. Каталог данных должен принадлежать ему целиком. После восстановления из резервной копии под root служба перестаёт стартовать, и лечится это возвратом владельца, а не правкой unit-файла.
Как устроена
| Имя unit | mysql.service в Debian и Ubuntu, mysqld.service в RHEL |
|---|---|
| Журнал ошибок | /var/log/mysql/error.log — основной источник причин |
| Каталог данных | /var/lib/mysql, владелец mysql:mysql |
| Проверка настроек | mysqld --validate-config в версиях 8.0 и новее |
| Порт по умолчанию | 3306; unix-сокет обычно /run/mysqld/mysqld.sock |
Частые ошибки
25 записей базы отмечены за этой службой.
Коды выхода
- status=1/FAILURE в systemdКод 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
- status=205/LIMITS в systemdКод 205/LIMITS: systemd не смог применить ограничения ресурсов из Limit*=. Обычно значение недопустимо или превышает жёсткий предел.
Сообщения журнала
- Permission denied в журнале службыОтказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
- Address already in use при запуске службыПорт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Connection refused в журнале службыСоединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- Данные теряются при перезапуске службыСлужба не успевает сохранить состояние при остановке: короткий таймаут, неверный сигнал, отсутствие обработки завершения.
- Приложение не стартует: блокировка миграций базыСлужба зависает или падает на применении миграций: осталась блокировка после прерванного запуска.
Состояния результата
- Failed with result 'oom-kill'Состояние oom-kill: процесс службы убит из-за нехватки памяти. Как понять, упёрлись в предел службы или в память машины.
- Failed with result 'timeout'Состояние timeout: служба не уложилась в отведённое время при запуске, остановке или перезагрузке настроек.
- Failed with result 'core-dump'Состояние core-dump: процесс службы аварийно завершился и сохранил дамп памяти. Как открыть дамп и прочитать трассировку.
- Job for … failed because a timeout was exceededЗадание на запуск прервано по таймауту. Как отличить медленный старт от заблокированного и правильно настроить TimeoutStartSec.
Ресурсы и ограничения
- No space left on device в журнале службыНет места на устройстве: разбор по свободным блокам, по inode, по журналу systemd и по удалённым, но открытым файлам.
- Too many open files в журнале службыСлужба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
Сигналы
- signal=ABRT (status=6/ABRT) в systemdПроцесс службы завершён сигналом ABRT: программа сама прервала работу после внутренней проверки. Где искать причину.
- signal=BUS (status=7/BUS) в systemdПроцесс службы завершён сигналом BUS: ошибка доступа к памяти, часто из-за усечённого файла в отображении или заполненного диска.
- signal=KILL (status=9/KILL) в systemdПроцесс службы убит сигналом KILL. Кто мог его послать: OOM-killer, таймаут остановки systemd, администратор.
- signal=SEGV (status=11/SEGV) в systemdПроцесс службы завершён сигналом SEGV: обращение к недопустимой памяти. Как собрать дамп и что смотреть.
Конфигурация unit
- Пределы ресурсов в unit-файле не применяютсяПочему limits.conf не действует на службы и как проверить действующие пределы процесса.
Ошибки служб
- MySQL убит из-за памяти: буферный пул больше доступной памятиMySQL падает сразу после старта или через минуты: размер innodb_buffer_pool_size превышает память машины.
- MySQL: Can't connect to local server through socketКлиент не находит unix-сокет MySQL: сервер не запущен, путь к сокету другой, каталог в /run не создан.
- MySQL: Can't open the mysql.plugin table и повреждение системных таблицMySQL не запускается: недоступны или повреждены системные таблицы. Права на каталог данных, версия схемы, восстановление.
- MySQL: InnoDB не запускается после аварийного завершенияОшибки InnoDB при старте: повреждение страниц, несовпадение журнала, режим принудительного восстановления.
- MySQL: Too many connectionsБаза отказывает в новых подключениях: исчерпан max_connections или предел дескрипторов службы.
- MySQL: журнал двоичных изменений заполнил дискМесто кончилось из-за binlog: не настроена очистка, отстала репликация, слишком большой срок хранения.
- MySQL: репликация остановилась с ошибкойПодписчик перестал применять изменения: конфликт данных, пропущенная транзакция, недоступный основной сервер.
Коды выхода этой службы
Числа в status=N ниже 200 назначает сама программа, 200 и выше — systemd, когда не смог подготовить запуск.
| status | Что означает у этой службы | Куда смотреть |
|---|---|---|
1/FAILURE |
ошибка настроек, права на каталог данных или повреждённые таблицы. | разбор |
убит сигналом KILL |
нехватка памяти: чаще всего из-за размера буферного пула InnoDB. | разбор |
6/ABRT |
внутренняя проверка InnoDB не прошла — обычно признак повреждения данных. | разбор |
Диагностика
Главный источник: точное сообщение об ошибке запуска.
sudo tail -60 /var/log/mysql/error.logКод и сигнал, с которыми завершился процесс.
systemctl status mysql --no-pager -lПроверка настроек без запуска сервера (MySQL 8.0 и новее).
sudo mysqld --validate-configВладелец каталога данных и его размер.
sudo ls -ld /var/lib/mysql && sudo du -sh /var/lib/mysqlПамять машины и пределы службы: для падений по KILL это главные числа.
free -h && systemctl show mysql -p MemoryMax -p MemoryPeakПараметры unit, которые тут важны
- LimitNOFILE=MySQL открывает много файлов таблиц; значение по умолчанию мало
- MemoryMax=ограничение памяти базе задавать только с учётом буферного пула
- TimeoutStartSec=восстановление InnoDB после сбоя может занять минуты
- User=служба работает от mysql, каталог данных должен принадлежать ему
Источники
- Документация MySQL: запуск и устранение неполадок
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)