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` на PID директориятаDebian/Ubuntu след надстройки
Пълен диск или изчерпване на inode`No space left on device`Всеки сървър с малък `/var`
Повредени `ibdata1` или InnoDB redo логове`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 дистрибуции. Това е една от най-често пренебрегваните причини в 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*`), общите журнали на заявките, оставени случайно активирани, или файловете с дъмп на ядрото. За безопасно изчистване на стари двоични журнали от 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` или препратки към несъответствия в redo журнала, самото 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 проблеми. Работата на производствена база данни на правилно осигурен сървър с dedicated ресурси елиминира цели категории от тези грешки.

Ако управлявате приложение, базирано на MySQL, средата VPS Хостинг ви дава пълен root достъп, изолирани ресурси и възможността да конфигурирате `tmpfiles.d`, AppArmor профили и замени на systemd единици без ограничения. За бази данни с голям трафик, изискващи гарантирани IOPS и RAM, Dedicated сървъри премахват напълно всички притеснения за споделяне на ресурси.

За екипи, предпочитащи управляван контролен панел вместо директна 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
За начало