15%

Збережіть 15% на всі хостинг-послуги

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код:

Skills
Почати
09.10.2024

Помилка MySQL: Сервер завершив роботу без оновлення PID-файлу — Повний посібник з діагностики та усунення несправностей

Помилка "The server quit without updating PID file" означає, що MySQL завершив роботу до того, як зміг записати свій ідентифікатор процесу до налаштованого файлу `.pid` — жорстка зупинка, яка перешкоджає демону приймати з’єднання. Ця помилка майже завжди є симптомом глибшої проблеми: неправильна конфігурація в `my.cnf`, невідповідність прав доступу до каталогу даних, переповнений дисковий розділ, пошкодження на рівні таблиць або конфлікт портів з другим екземпляром MySQL або MariaDB.

Цей посібник розглядає кожну підтверджену першопричину, надає точні команди оболонки для діагностики та усунення кожної з них, а також охоплює граничні випадки, які типові посібники зазвичай пропускають.

Що насправді робить PID-файл і чому його відсутність має значення

MySQL записує свій ідентифікатор процесу (PID) до невеликого текстового файлу — зазвичай `/var/run/mysqld/mysqld.pid` — одразу після ініціалізації демона. Init-системи, менеджери служб (systemd, SysVinit) та інструменти моніторингу зчитують цей файл, щоб надсилати сигнали до правильного процесу. Якщо MySQL аварійно завершує роботу, виходить ненормально або стикається з фатальною помилкою під час запуску, він ніколи не досягає точки запису цього файлу. Менеджер служб тоді повідомляє про помилку "quit without updating PID file".

Розуміння цієї послідовності є критично важливим: помилка PID-файлу є *наслідком*, а не першопричиною. Переслідування самого PID-файлу без попереднього читання журналу помилок — це найпоширеніша помилка, яку роблять адміністратори.

Поширені першопричини на перший погляд

ПершопричинаТиповий симптом у журналі помилокУражені системи
Неправильний шлях `pid-file` у `my.cnf``Can't start server: can't create PID file`Усі дистрибутиви
Неправильний власник `/var/run/mysqld``Permission denied` на каталозі PIDDebian/Ubuntu після оновлень
Переповнений диск або вичерпання inode`No space left on device`Будь-який сервер з малим `/var`
Пошкоджений `ibdata1` або журнали повторного виконання InnoDB`InnoDB: Corruption detected`MySQL 5.7, 8.0, MariaDB
Застарілий файл `.pid` від попереднього збою`A mysqld process already exists`Будь-яка система після жорсткого перезавантаження
Порт 3306 вже використовується`Can't start server: Bind on TCP/IP port`Налаштування з кількома екземплярами
Відмова політики AppArmor або SELinux`apparmor="DENIED"` у syslogUbuntu, RHEL/CentOS
Невідповідний `datadir` після оновлення пакету`[ERROR] Fatal error: Can't open and lock privilege tables`Оновлення основних версій

Крок 1 — Спочатку прочитайте журнал помилок MySQL

Кожен наступний крок залежить від того, що говорить журнал помилок. Не пропускайте цей крок.

“`bash

Debian/Ubuntu default path

sudo tail -100 /var/log/mysql/error.log

RHEL/CentOS/AlmaLinux default path

sudo tail -100 /var/log/mysqld.log

If you are unsure of the path, query the running config

mysqld –verbose –help 2>/dev/null | grep "log-error"

“`

Шукайте рядки, що містять `[ERROR]`, `[FATAL]`, `Aborting` або `InnoDB`. Перший запис `[ERROR]` у послідовності запуску майже завжди є справжньою причиною.

Крок 2 — Перевірте та виправте каталог PID-файлу

Каталог PID часто відтворюється з власником `root` після перезавантаження системи, оскільки `/var/run` є монтуванням `tmpfs` у сучасних дистрибутивах Linux. Це одна з найчастіше overlooked причин на Ubuntu 20.04+ та Debian 11+.

“`bash

Check current ownership

ls -ld /var/run/mysqld

Recreate the directory with correct ownership

sudo mkdir -p /var/run/mysqld

sudo chown mysql:mysql /var/run/mysqld

sudo chmod 755 /var/run/mysqld

“`

Щоб зробити це постійним після перезавантажень на системах systemd, створіть правило `tmpfiles.d`:

“`bash

echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf

“`

Переконайтеся, що шлях PID, налаштований у `my.cnf`, відповідає щойно створеному каталогу:

“`bash

sudo grep -i "pid" /etc/mysql/my.cnf /etc/mysql/mysql.conf.d/*.cnf 2>/dev/null

“`

Крок 3 — Перевірте власника та права доступу до каталогу даних

Каталог даних MySQL повинен повністю належати системному користувачу `mysql`. Оновлення пакетів, ручне копіювання файлів або відновлення з резервної копії часто порушують це.

“`bash

Correct ownership recursively

sudo chown -R mysql:mysql /var/lib/mysql

Correct permissions — directories 750, files 640 is more secure than 755/644

sudo find /var/lib/mysql -type d -exec chmod 750 {} ;

sudo find /var/lib/mysql -type f -exec chmod 640 {} ;

“`

Важливий граничний випадок: Якщо ви відновили резервну копію за допомогою `rsync` або `cp` від імені `root`, файл сокета `/var/lib/mysql/mysql.sock` також може належати root. Видаліть його — MySQL відтворить його під час запуску:

“`bash

sudo rm -f /var/lib/mysql/mysql.sock

sudo rm -f /var/run/mysqld/mysqld.sock

“`

Крок 4 — Перевірте наявність вільного місця на диску та доступність inode

Переповнений диск непомітно перешкоджає MySQL записувати будь-який файл, включаючи PID-файл та бінарні журнали.

“`bash

Check disk space

df -h

Check inode usage — often overlooked

df -i

Find the largest directories consuming space

sudo du -sh /var/lib/mysql/* | sort -rh | head -20

“`

Якщо розділ переповнений, типовими винуватцями є бінарні журнали (`mysql-bin.000*`), загальні журнали запитів, випадково залишені увімкненими, або файли core dump. Щоб безпечно очистити старі бінарні журнали зсередини MySQL:

“`bash

mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"

“`

Крок 5 — Усуньте застарілі PID-файли та конфліктуючі процеси

Після паніки ядра, відключення живлення або `kill -9`, застарілий PID-файл може залишитися на диску. MySQL відмовляється запускатися, якщо знаходить такий файл.

“`bash

Check for a stale PID file

cat /var/run/mysqld/mysqld.pid

Verify whether that PID is actually running

ps aux | grep mysqld

If the process is not running but the file exists, remove it

sudo rm -f /var/run/mysqld/mysqld.pid

“`

Якщо інший екземпляр MySQL або MariaDB справді працює та займає порт 3306:

“`bash

sudo ss -tlnp | grep 3306

sudo systemctl stop mariadb

sudo systemctl stop mysql

sudo killall -9 mysqld mysqld_safe

“`

Зачекайте три секунди після завершення процесів перед спробою перезапуску, щоб дозволити станам TIME_WAIT сокетів ядра очиститися.

Крок 6 — Перевірте політики AppArmor та SELinux

Ця причина майже ніколи не згадується в базових посібниках, проте вона відповідає за значний відсоток помилок PID-файлу на Ubuntu та системах сімейства RHEL.

Ubuntu / AppArmor:

“`bash

sudo dmesg | grep -i apparmor | grep -i mysql

sudo grep -i "DENIED" /var/log/syslog | grep mysql

“`

Якщо AppArmor блокує MySQL, або оновіть профіль, або тимчасово встановіть режим скарг для діагностики:

“`bash

sudo aa-complain /usr/sbin/mysqld

“`

RHEL / CentOS / AlmaLinux — SELinux:

“`bash

sudo ausearch -c 'mysqld' –raw | audit2why

sudo sealert -a /var/log/audit/audit.log | grep mysqld

“`

Поширене виправлення проблем контексту SELinux після переміщення каталогу даних:

“`bash

sudo semanage fcontext -a -t mysqld_db_t "/new/datadir(/.*)?"

sudo restorecon -Rv /new/datadir

“`

Крок 7 — Діагностика та відновлення після пошкодження InnoDB

Якщо журнал помилок містить повідомлення на кшталт `InnoDB: Corruption detected`, `[ERROR] InnoDB: Unable to lock ./ibdata1` або посилання на невідповідності журналу повторного виконання, табличний простір InnoDB пошкоджений.

Для таблиць MyISAM використовуйте `mysqlcheck`:

“`bash

sudo mysqlcheck –all-databases –repair –user=root –password

“`

При пошкодженні InnoDB `mysqlcheck` недостатньо. Правильний підхід — увімкнути режим примусового відновлення InnoDB у `my.cnf`:

“`ini

[mysqld]

innodb_force_recovery = 1

“`

Запустіть MySQL з цим налаштуванням, негайно зробіть дамп усіх баз даних, потім відновіть:

“`bash

mysqldump –all-databases –single-transaction -u root -p > full_backup.sql

“`

Збільшуйте `innodb_force_recovery` від 1 до 6 лише якщо нижчі значення не дозволяють запустити сервер. На рівні 4 і вище можлива втрата даних — ставтеся до екземпляра як до режиму лише для читання та негайно виконайте експорт.

Після успішного дампу:

“`bash

sudo systemctl stop mysql

sudo rm -rf /var/lib/mysql/ib_logfile* # Remove corrupt redo logs

Remove innodb_force_recovery from my.cnf

sudo systemctl start mysql

mysql -u root -p < full_backup.sql

“`

Крок 8 — Виявлення помилок конфігурації в my.cnf

Одна помилка друку або недійсна директива в `my.cnf` призведе до переривання запуску до запису PID-файлу. MySQL 8.0+ є суворішим щодо невідомих параметрів, ніж 5.7.

“`bash

Validate configuration without starting the server

mysqld –validate-config

Or test with verbose output

mysqld –verbose –help > /dev/null

“`

Зробіть резервну копію та скиньте конфігурацію до стандартних значень:

“`bash

sudo cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak.$(date +%F)

“`

Поширені проблемні директиви після оновлень основних версій включають застарілі параметри, такі як `query_cache_size`, `query_cache_type`, `innodb_file_format` та `innodb_large_prefix` — усі видалені в MySQL 8.0.

Крок 9 — Перезапустіть MySQL та перевірте

“`bash

sudo systemctl restart mysql

Check service status

sudo systemctl status mysql

Confirm the PID file was written

cat /var/run/mysqld/mysqld.pid

Confirm MySQL is accepting connections

mysqladmin -u root -p status

“`

Крок 10 — Перевстановлення MySQL (крайній захід зі збереженням даних)

Перевстановлення слід виконувати лише після вичерпання кожного діагностичного кроку вище. Перед продовженням зробіть резервну копію всіх даних:

“`bash

If MySQL can start in recovery mode, dump first

mysqldump –all-databases -u root -p > /backup/full_$(date +%F).sql

Copy raw data directory as a secondary backup

sudo rsync -av /var/lib/mysql/ /backup/mysql_datadir_$(date +%F)/

“`

Потім видаліть та перевстановіть:

“`bash

sudo systemctl stop mysql

sudo apt-get remove –purge mysql-server mysql-client mysql-common

sudo apt-get autoremove && sudo apt-get autoclean

sudo rm -rf /var/lib/mysql /etc/mysql

sudo apt-get install mysql-server

sudo mysql_secure_installation

“`

Відновіть з дампу:

“`bash

mysql -u root -p < /backup/full_$(date +%F).sql

“`

Вибір правильного хостингового середовища для запобігання повторенню

Багато з цих збоїв — вичерпання диска, скидання прав доступу після перезавантажень, конкуренція ресурсів від спільно розміщених служб — є проблемами інфраструктури не менше, ніж проблемами MySQL. Запуск виробничої бази даних на належно підготовленому сервері з виділеними ресурсами усуває цілі категорії цих помилок.

Якщо ви керуєте додатком на основі MySQL, середовище VPS Хостинг надає вам повний root-доступ, ізольовані ресурси та можливість налаштовувати `tmpfiles.d`, профілі AppArmor та перевизначення одиниць systemd без обмежень. Для баз даних з високим трафіком, що потребують гарантованих IOPS та RAM, Виділені сервери повністю усувають будь-які проблеми спільного використання ресурсів.

Для команд, які надають перевагу керованій панелі управління, а не прямому адмініструванню через CLI, VPS з cPanel надає інтерфейси управління MySQL поряд з доступом на рівні сервера. Якщо ваш стек також потребує налаштування домену та DNS, Реєстрація доменів та SSL-сертифікати можна керувати від одного провайдера, зменшуючи операційні витрати.

Матриця рішень: яке виправлення застосувати першим

Симптом у журналі помилокПерша діяОрієнтовний час вирішення
`Permission denied` на PID або каталозі данихВиправте власника за допомогою `chown mysql:mysql`2 хвилини
`No space left on device`Очистіть бінарні журнали, розширте диск5–30 хвилин
`A mysqld process already exists`Видаліть застарілий PID-файл, завершіть осиротілий процес2 хвилини
`Bind on TCP/IP port: Address already in use`Зупиніть конфліктуючий екземпляр, перевірте `ss -tlnp`5 хвилин
`InnoDB: Corruption detected`Увімкніть `innodb_force_recovery`, зробіть дамп, відновіть30 хвилин — кілька годин
`apparmor="DENIED"` у syslogОновіть профіль AppArmor або встановіть режим скарг10 хвилин
`unknown variable` у журналіЗапустіть `mysqld –validate-config`, виправте `my.cnf`5 хвилин
Немає конкретної помилки, все інше не допомоглоПеревстановіть MySQL, відновіть з резервної копії1–2 години

Технічний контрольний список ключових висновків

  • Завжди читайте `/var/log/mysql/error.log` або `/var/log/mysqld.log` перед тим, як торкатися будь-якого файлу — перший рядок `[ERROR]` визначає справжню причину.
  • На системах systemd з `tmpfs` на `/var/run`, створіть постійне правило `/etc/tmpfiles.d/mysqld.conf`, щоб запобігти скиданню прав доступу при кожному перезавантаженні.
  • Після будь-якого `rsync` або ручного відновлення резервної копії запустіть `chown -R mysql:mysql /var/lib/mysql` перед спробою запустити MySQL.
  • Перевіряйте `df -i` (використання inode) поряд з `df -h` (місце на диску) — повна таблиця inode дає ідентичні симптоми переповненому диску.
  • При пошкодженні InnoDB використовуйте `innodb_force_recovery` поступово від 1 вгору; ніколи не переходьте одразу до рівня 6.
  • Перевіряйте синтаксис `my.cnf` за допомогою `mysqld –validate-config` перед перезапуском — це виявляє помилки друку без невдалої спроби запуску.
  • Видаліть застарілі директиви MySQL 5.7 (`query_cache_*`, `innodb_file_format`) перед оновленням до MySQL 8.0.
  • На Ubuntu перевіряйте відмови AppArmor у `/var/log/syslog`; на RHEL/AlmaLinux перевіряйте SELinux за допомогою `ausearch -c mysqld`.

Часті запитання

Який найшвидший спосіб дізнатися, чому MySQL не запустився?

Запустіть `sudo tail -50 /var/log/mysql/error.log` та знайдіть перший рядок, що містить `[ERROR]` або `[FATAL]`. Цей єдиний рядок визначає першопричину у переважній більшості випадків та визначає, яке виправлення застосувати.

Чому каталог PID втрачає права доступу після перезавантаження?

У дистрибутивах Linux, що використовують `tmpfs` для `/var/run` (включаючи Ubuntu 18.04+ та Debian 10+), все дерево `/var/run` відтворюється в пам’яті під час завантаження. Будь-який каталог, не визначений у `/etc/tmpfiles.d/`, відтворюється з власником `root:root`. Виправлення полягає в додаванні правила `tmpfiles.d`: `echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf`.

Чи можна відновити дані, якщо MySQL взагалі не запускається через пошкодження InnoDB?

Так, у більшості випадків. Встановіть `innodb_force_recovery = 1` у `my.cnf`, запустіть MySQL та негайно виконайте `mysqldump –all-databases`. Якщо рівень 1 не запускає сервер, збільшіть до 2, потім до 3 і так далі. На рівнях 4–6 деякі дані можуть бути невідновлюваними, але більшість таблиць зазвичай залишається цілою.

Як запобігти тому, щоб помилка "no space left on device" знову не зупиняла MySQL?

Увімкніть термін дії бінарних журналів: встановіть `binlog_expire_logs_seconds = 604800` (7 днів) у `my.cnf`. Крім того, вимкніть загальний журнал запитів у виробництві (`general_log = 0`) та налаштуйте сповіщення про використання диска на рівні 80% через вашу систему моніторингу.

Чи виникає ця помилка також на MariaDB, і чи однакове виправлення?

Так. MariaDB використовує той самий механізм PID-файлу та ту саму структуру каталогу даних, що й MySQL. Усі діагностичні кроки в цьому посібнику безпосередньо застосовуються до MariaDB, з єдиною відмінністю: ім’я служби — `mariadb` замість `mysql` у командах `systemctl`, а журнал помилок може знаходитися за адресою `/var/log/mariadb/mariadb.log` залежно від дистрибутива.

15%

Збережіть 15% на всі хостинг-послуги

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код:

Skills
Почати