15%

Zaoszczędź 15% na wszystkich usługach hostingowych

Sprawdź swoje umiejętności i zdobądź Rabat na dowolny plan hostingowy

Użyj kodu:

Skills
Rozpocznij
09.10.2024

Błąd MySQL: Serwer zakończył działanie bez aktualizacji pliku PID — kompletny przewodnik diagnostyki i naprawy

Błąd "The server quit without updating PID file" oznacza, że MySQL zakończył działanie, zanim zdążył zapisać swój identyfikator procesu do skonfigurowanego pliku `.pid` — twarde zatrzymanie uniemożliwiające daemonowi przyjmowanie połączeń. Ten błąd jest niemal zawsze objawem głębszego problemu: błędnej konfiguracji w `my.cnf`, niezgodności uprawnień do katalogu danych, pełnej partycji dyskowej, uszkodzenia na poziomie tabel lub konfliktu portów z drugą instancją MySQL lub MariaDB.

Ten przewodnik omawia każdą potwierdzoną przyczynę źródłową, dostarcza dokładnych poleceń powłoki do diagnozowania i naprawy każdej z nich oraz obejmuje przypadki brzegowe, które ogólne poradniki zazwyczaj pomijają.

Czym jest plik PID i dlaczego jego brak ma znaczenie

MySQL zapisuje swój identyfikator procesu (PID) do małego pliku tekstowego — zazwyczaj `/var/run/mysqld/mysqld.pid` — natychmiast po zainicjowaniu daemona. Systemy init, menedżery usług (systemd, SysVinit) i narzędzia monitorujące odczytują ten plik, aby wysyłać sygnały do właściwego procesu. Jeśli MySQL ulegnie awarii, zakończy działanie nieprawidłowo lub napotka krytyczny błąd podczas uruchamiania, nigdy nie dochodzi do momentu zapisania tego pliku. Menedżer usług zgłasza wtedy komunikat "quit without updating PID file".

Zrozumienie tej sekwencji jest kluczowe: błąd pliku PID jest *konsekwencją*, a nie przyczyną źródłową. Skupianie się na samym pliku PID bez uprzedniego przeczytania dziennika błędów to najczęstszy błąd popełniany przez administratorów.

Typowe przyczyny źródłowe w skrócie

Przyczyna źródłowaTypowy objaw w dzienniku błędówSystemy, których dotyczy
Nieprawidłowa ścieżka `pid-file` w `my.cnf``Can't start server: can't create PID file`Wszystkie dystrybucje
Nieprawidłowy właściciel `/var/run/mysqld``Permission denied` w katalogu PIDDebian/Ubuntu po aktualizacjach
Pełny dysk lub wyczerpanie i-węzłów`No space left on device`Każdy serwer z małą partycją `/var`
Uszkodzony `ibdata1` lub logi redo InnoDB`InnoDB: Corruption detected`MySQL 5.7, 8.0, MariaDB
Nieaktualny plik `.pid` po poprzedniej awarii`A mysqld process already exists`Każdy system po twardym restarcie
Port 3306 jest już zajęty`Can't start server: Bind on TCP/IP port`Konfiguracje wieloinstancyjne
Odmowa polityki AppArmor lub SELinux`apparmor="DENIED"` w syslogUbuntu, RHEL/CentOS
Niezgodny `datadir` po aktualizacji pakietu`[ERROR] Fatal error: Can't open and lock privilege tables`Aktualizacje głównych wersji

Krok 1 — Najpierw przeczytaj dziennik błędów MySQL

Każdy kolejny krok zależy od tego, co mówi dziennik błędów. Nie pomijaj tego kroku.

“`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"

“`

Szukaj wierszy zawierających `[ERROR]`, `[FATAL]`, `Aborting` lub `InnoDB`. Pierwszy wpis `[ERROR]` w sekwencji uruchamiania jest niemal zawsze prawdziwą przyczyną.

Krok 2 — Zweryfikuj i napraw katalog pliku PID

Katalog PID jest często odtwarzany jako należący do `root` po restarcie systemu, ponieważ `/var/run` jest montowaniem `tmpfs` w nowoczesnych dystrybucjach Linux. Jest to jedna z najczęściej pomijanych przyczyn w Ubuntu 20.04+ i 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

“`

Aby utrwalić to między restartami w systemach systemd, utwórz regułę `tmpfiles.d`:

“`bash

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

“`

Potwierdź, że ścieżka PID skonfigurowana w `my.cnf` odpowiada właśnie utworzonemu katalogowi:

“`bash

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

“`

Krok 3 — Sprawdź właściciela i uprawnienia katalogu danych

Katalog danych MySQL musi być w całości własnością systemowego użytkownika `mysql`. Aktualizacje pakietów, ręczne kopiowanie plików lub przywracanie z kopii zapasowej często to psują.

“`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 {} ;

“`

Ważny przypadek brzegowy: Jeśli przywróciłeś kopię zapasową używając `rsync` lub `cp` jako `root`, plik gniazda `/var/lib/mysql/mysql.sock` może również należeć do roota. Usuń go — MySQL odtworzy go przy uruchomieniu:

“`bash

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

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

“`

Krok 4 — Sprawdź dostępność miejsca na dysku i i-węzłów

Pełny dysk po cichu uniemożliwia MySQL zapisanie jakiegokolwiek pliku, w tym pliku PID i logów binarnych.

“`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

“`

Jeśli partycja jest pełna, typowymi winowajcami są logi binarne (`mysql-bin.000*`), przypadkowo pozostawione włączone ogólne logi zapytań lub pliki zrzutów pamięci. Aby bezpiecznie wyczyścić stare logi binarne z poziomu MySQL:

“`bash

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

“`

Krok 5 — Usuń nieaktualne pliki PID i konfliktujące procesy

Po panice jądra, utracie zasilania lub `kill -9`, na dysku może pozostać nieaktualny plik PID. MySQL odmawia uruchomienia, jeśli go znajdzie.

“`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

“`

Jeśli inna instancja MySQL lub MariaDB rzeczywiście działa i zajmuje port 3306:

“`bash

sudo ss -tlnp | grep 3306

sudo systemctl stop mariadb

sudo systemctl stop mysql

sudo killall -9 mysqld mysqld_safe

“`

Poczekaj trzy sekundy po zakończeniu procesów przed próbą restartu, aby stany TIME_WAIT gniazda jądra mogły się wyczyścić.

Krok 6 — Sprawdź polityki AppArmor i SELinux

Ta przyczyna jest niemal nigdy nie wspominana w podstawowych poradnikach, a jednak odpowiada za znaczny odsetek błędów pliku PID w systemach Ubuntu i rodziny RHEL.

Ubuntu / AppArmor:

“`bash

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

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

“`

Jeśli AppArmor blokuje MySQL, zaktualizuj profil lub tymczasowo ustaw go w tryb narzekania do celów diagnostycznych:

“`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

“`

Typowa poprawka dla problemów z kontekstem SELinux po przeniesieniu katalogu danych:

“`bash

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

sudo restorecon -Rv /new/datadir

“`

Krok 7 — Diagnozuj i naprawiaj uszkodzenia InnoDB

Jeśli dziennik błędów zawiera komunikaty takie jak `InnoDB: Corruption detected`, `[ERROR] InnoDB: Unable to lock ./ibdata1` lub odwołania do niespójności logów redo, przestrzeń tabel InnoDB jest uszkodzona.

W przypadku tabel MyISAM użyj `mysqlcheck`:

“`bash

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

“`

W przypadku uszkodzenia InnoDB, `mysqlcheck` jest niewystarczający. Właściwe podejście to włączenie trybu wymuszonego odzyskiwania InnoDB w `my.cnf`:

“`ini

[mysqld]

innodb_force_recovery = 1

“`

Uruchom MySQL z tym ustawieniem, natychmiast zrzuć wszystkie bazy danych, a następnie odbuduj:

“`bash

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

“`

Zwiększaj `innodb_force_recovery` od 1 do 6 tylko wtedy, gdy niższe wartości nie uruchamiają serwera. Na poziomie 4 i wyżej możliwa jest utrata danych — traktuj instancję jako tylko do odczytu i natychmiast eksportuj dane.

Po pomyślnym zrzucie:

“`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

“`

Krok 8 — Izoluj błędy konfiguracji w my.cnf

Pojedynczy błąd typograficzny lub nieprawidłowa dyrektywa w `my.cnf` przerwie uruchamianie przed zapisaniem pliku PID. MySQL 8.0+ jest bardziej rygorystyczny w kwestii nieznanych opcji niż wersja 5.7.

“`bash

Validate configuration without starting the server

mysqld –validate-config

Or test with verbose output

mysqld –verbose –help > /dev/null

“`

Wykonaj kopię zapasową i zredukuj konfigurację do wartości domyślnych:

“`bash

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

“`

Typowe problematyczne dyrektywy po aktualizacjach głównych wersji obejmują przestarzałe opcje takie jak `query_cache_size`, `query_cache_type`, `innodb_file_format` i `innodb_large_prefix` — wszystkie usunięte w MySQL 8.0.

Krok 9 — Uruchom ponownie MySQL i zweryfikuj

“`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

“`

Krok 10 — Ponowna instalacja MySQL (ostateczność z zachowaniem danych)

Ponowna instalacja powinna nastąpić dopiero po wyczerpaniu wszystkich powyższych kroków diagnostycznych. Przed kontynuowaniem wykonaj kopię zapasową wszystkich danych:

“`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)/

“`

Następnie usuń i zainstaluj ponownie:

“`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

“`

Przywróć ze zrzutu:

“`bash

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

“`

Wybór odpowiedniego środowiska hostingowego, aby zapobiec nawrotom

Wiele z tych awarii — wyczerpanie dysku, resetowanie uprawnień po restartach, rywalizacja o zasoby ze współhostowanymi usługami — to problemy infrastrukturalne w równym stopniu co problemy MySQL. Uruchomienie produkcyjnej bazy danych na odpowiednio skonfigurowanym serwerze z dedykowanymi zasobami eliminuje całe kategorie tych błędów.

Jeśli zarządzasz aplikacją opartą na MySQL, środowisko VPS Hosting zapewnia pełny dostęp root, izolowane zasoby oraz możliwość konfigurowania `tmpfiles.d`, profili AppArmor i nadpisań jednostek systemd bez ograniczeń. W przypadku baz danych o dużym ruchu wymagających gwarantowanych IOPS i RAM, Serwery Dedykowane całkowicie eliminują wszelkie obawy związane z współdzieleniem zasobów.

Dla zespołów preferujących zarządzany panel sterowania zamiast bezpośredniej administracji przez CLI, VPS z cPanel zapewnia interfejsy zarządzania MySQL wraz z dostępem na poziomie serwera. Jeśli Twój stos wymaga również konfiguracji domen i DNS, Rejestracja Domen i Certyfikaty SSL mogą być zarządzane u tego samego dostawcy, zmniejszając nakład pracy operacyjnej.

Macierz decyzyjna: którą poprawkę zastosować jako pierwszą

Objaw w dzienniku błędówPierwsza czynnośćSzacowany czas rozwiązania
`Permission denied` w katalogu PID lub danychNapraw właściciela za pomocą `chown mysql:mysql`2 minuty
`No space left on device`Wyczyść logi binarne, rozszerz dysk5–30 minut
`A mysqld process already exists`Usuń nieaktualny plik PID, zakończ osierocony proces2 minuty
`Bind on TCP/IP port: Address already in use`Zatrzymaj konfliktującą instancję, sprawdź `ss -tlnp`5 minut
`InnoDB: Corruption detected`Włącz `innodb_force_recovery`, zrzuć dane, odbuduj30 minut do kilku godzin
`apparmor="DENIED"` w syslogZaktualizuj profil AppArmor lub ustaw tryb narzekania10 minut
`unknown variable` w dziennikuUruchom `mysqld –validate-config`, napraw `my.cnf`5 minut
Brak konkretnego błędu, wszystko inne zawodziZainstaluj ponownie MySQL, przywróć z kopii zapasowej1–2 godziny

Lista kontrolna kluczowych wniosków technicznych

  • Zawsze czytaj `/var/log/mysql/error.log` lub `/var/log/mysqld.log` przed dotknięciem jakiegokolwiek pliku — pierwsza linia `[ERROR]` identyfikuje rzeczywistą przyczynę.
  • W systemach systemd z `tmpfs` na `/var/run`, utwórz trwałą regułę `/etc/tmpfiles.d/mysqld.conf`, aby zapobiec resetowaniu uprawnień przy każdym restarcie.
  • Po każdym `rsync` lub ręcznym przywróceniu kopii zapasowej, uruchom `chown -R mysql:mysql /var/lib/mysql` przed próbą uruchomienia MySQL.
  • Sprawdzaj `df -i` (użycie i-węzłów) obok `df -h` (miejsce na dysku) — pełna tablica i-węzłów daje identyczne objawy jak pełny dysk.
  • W przypadku uszkodzenia InnoDB używaj `innodb_force_recovery` stopniowo od 1 wzwyż; nigdy nie przechodź od razu do poziomu 6.
  • Weryfikuj składnię `my.cnf` za pomocą `mysqld –validate-config` przed restartem — pozwala to wykryć błędy typograficzne bez nieudanej próby uruchomienia.
  • Usuń przestarzałe dyrektywy MySQL 5.7 (`query_cache_*`, `innodb_file_format`) przed aktualizacją do MySQL 8.0.
  • W Ubuntu sprawdzaj odmowy AppArmor w `/var/log/syslog`; w RHEL/AlmaLinux sprawdzaj SELinux za pomocą `ausearch -c mysqld`.

Często zadawane pytania

Jaki jest najszybszy sposób na znalezienie przyczyny niepowodzenia uruchomienia MySQL?

Uruchom `sudo tail -50 /var/log/mysql/error.log` i poszukaj pierwszej linii zawierającej `[ERROR]` lub `[FATAL]`. Ta jedna linia identyfikuje przyczynę źródłową w zdecydowanej większości przypadków i określa, którą poprawkę zastosować.

Dlaczego katalog PID traci swoje uprawnienia po restarcie?

W dystrybucjach Linux używających `tmpfs` dla `/var/run` (co obejmuje Ubuntu 18.04+ i Debian 10+), całe drzewo `/var/run` jest odbudowywane w pamięci podczas rozruchu. Każdy katalog niezdefiniowany w `/etc/tmpfiles.d/` jest odtwarzany jako należący do `root:root`. Rozwiązaniem jest dodanie reguły `tmpfiles.d`: `echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf`.

Czy mogę odzyskać dane, jeśli MySQL w ogóle nie uruchamia się z powodu uszkodzenia InnoDB?

Tak, w większości przypadków. Ustaw `innodb_force_recovery = 1` w `my.cnf`, uruchom MySQL i natychmiast uruchom `mysqldump –all-databases`. Jeśli poziom 1 nie uruchamia serwera, zwiększ do 2, potem do 3 i tak dalej. Na poziomach 4–6 część danych może być nieodwracalna, ale większość tabel jest zazwyczaj nienaruszona.

Jak zapobiec ponownemu zatrzymaniu MySQL przez błąd "no space left on device"?

Włącz wygasanie logów binarnych: ustaw `binlog_expire_logs_seconds = 604800` (7 dni) w `my.cnf`. Dodatkowo wyłącz ogólny dziennik zapytań w środowisku produkcyjnym (`general_log = 0`) i skonfiguruj alert użycia dysku przy 80% pojemności w swoim systemie monitorowania.

Czy ten błąd występuje również w MariaDB i czy naprawa jest taka sama?

Tak. MariaDB używa tego samego mechanizmu pliku PID i tej samej struktury katalogu danych co MySQL. Wszystkie kroki diagnostyczne w tym przewodniku mają bezpośrednie zastosowanie do MariaDB, z tą jedyną różnicą, że nazwa usługi to `mariadb` zamiast `mysql` w poleceniach `systemctl`, a dziennik błędów może znajdować się pod adresem `/var/log/mariadb/mariadb.log` w zależności od dystrybucji.

15%

Zaoszczędź 15% na wszystkich usługach hostingowych

Sprawdź swoje umiejętności i zdobądź Rabat na dowolny plan hostingowy

Użyj kodu:

Skills
Rozpocznij