Kesalahan MySQL: Server Berhenti Tanpa Memperbarui File PID — Panduan Diagnostik dan Perbaikan Lengkap
Kesalahan "The server quit without updating PID file" berarti MySQL berhenti sebelum dapat menulis pengenal prosesnya ke file `.pid` yang dikonfigurasi — penghentian paksa yang mencegah daemon menerima koneksi. Kegagalan ini hampir selalu merupakan gejala dari masalah yang lebih dalam: kesalahan konfigurasi di `my.cnf`, ketidaksesuaian izin pada direktori data, partisi disk yang penuh, kerusakan tingkat tabel, atau konflik port dengan instance MySQL atau MariaDB kedua.
Panduan ini membahas setiap penyebab utama yang telah dikonfirmasi, menyediakan perintah shell yang tepat untuk mendiagnosis dan memperbaiki masing-masing, serta mencakup kasus-kasus khusus yang sering diabaikan oleh tutorial umum.
Apa yang Sebenarnya Dilakukan File PID dan Mengapa Ketidakhadirannya Penting
MySQL menulis ID prosesnya (PID) ke file teks biasa yang kecil — biasanya `/var/run/mysqld/mysqld.pid` — segera setelah daemon diinisialisasi. Sistem init, manajer layanan (systemd, SysVinit), dan alat pemantauan membaca file ini untuk mengirim sinyal ke proses yang tepat. Jika MySQL crash, keluar secara tidak normal, atau mengalami kesalahan fatal saat startup, ia tidak pernah mencapai titik penulisan file tersebut. Manajer layanan kemudian melaporkan pesan "quit without updating PID file".
Memahami urutan ini sangat penting: kesalahan file PID adalah *akibat*, bukan penyebab utama. Mengejar file PID itu sendiri tanpa membaca log kesalahan terlebih dahulu adalah kesalahan paling umum yang dilakukan administrator.
Penyebab Utama Umum Sekilas
| Penyebab Utama | Gejala Umum dalam Log Kesalahan | Sistem yang Terpengaruh |
|---|---|---|
| — | — | — |
| Path `pid-file` yang salah di `my.cnf` | `Can't start server: can't create PID file` | Semua distro |
| Kepemilikan yang salah pada `/var/run/mysqld` | `Permission denied` pada direktori PID | Debian/Ubuntu setelah pembaruan |
| Disk penuh atau kehabisan inode | `No space left on device` | Server mana pun dengan `/var` kecil |
| `ibdata1` rusak atau log redo InnoDB | `InnoDB: Corruption detected` | MySQL 5.7, 8.0, MariaDB |
| File `.pid` lama dari crash sebelumnya | `A mysqld process already exists` | Sistem mana pun setelah reboot paksa |
| Port 3306 sudah digunakan | `Can't start server: Bind on TCP/IP port` | Pengaturan multi-instance |
| Penolakan kebijakan AppArmor atau SELinux | `apparmor="DENIED"` di syslog | Ubuntu, RHEL/CentOS |
| `datadir` tidak cocok setelah pembaruan paket | `[ERROR] Fatal error: Can't open and lock privilege tables` | Pembaruan versi mayor |
Langkah 1 — Baca Log Kesalahan MySQL Terlebih Dahulu
Setiap langkah lainnya bergantung pada apa yang dikatakan log kesalahan. Jangan lewati ini.
“`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"
“`
Cari baris yang mengandung `[ERROR]`, `[FATAL]`, `Aborting`, atau `InnoDB`. Entri `[ERROR]` pertama dalam urutan startup hampir selalu merupakan penyebab sebenarnya.
Langkah 2 — Verifikasi dan Perbaiki Direktori File PID
Direktori PID sering kali dibuat ulang dengan kepemilikan `root` setelah reboot sistem karena `/var/run` adalah mount `tmpfs` pada distribusi Linux modern. Ini adalah salah satu penyebab yang paling sering diabaikan pada Ubuntu 20.04+ dan 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
“`
Agar persisten setelah reboot pada sistem systemd, buat aturan `tmpfiles.d`:
“`bash
echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf
“`
Konfirmasi bahwa path PID yang dikonfigurasi di `my.cnf` sesuai dengan direktori yang baru saja Anda buat:
“`bash
sudo grep -i "pid" /etc/mysql/my.cnf /etc/mysql/mysql.conf.d/*.cnf 2>/dev/null
“`
Langkah 3 — Audit Kepemilikan dan Izin Direktori Data
Direktori data MySQL harus sepenuhnya dimiliki oleh pengguna sistem `mysql`. Pembaruan paket, salinan file manual, atau pemulihan dari backup sering kali merusak ini.
“`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 {} ;
“`
Kasus khusus penting: Jika Anda memulihkan backup menggunakan `rsync` atau `cp` sebagai `root`, file socket `/var/lib/mysql/mysql.sock` mungkin juga dimiliki oleh root. Hapus — MySQL akan membuatnya kembali saat startup:
“`bash
sudo rm -f /var/lib/mysql/mysql.sock
sudo rm -f /var/run/mysqld/mysqld.sock
“`
Langkah 4 — Periksa Ruang Disk dan Ketersediaan Inode
Disk yang penuh secara diam-diam mencegah MySQL menulis file apa pun, termasuk file PID dan binary log.
“`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
“`
Jika partisi penuh, penyebab umum adalah binary log (`mysql-bin.000*`), log kueri umum yang dibiarkan aktif secara tidak sengaja, atau file core dump. Untuk menghapus binary log lama dengan aman dari dalam MySQL:
“`bash
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"
“`
Langkah 5 — Hapus File PID Lama dan Proses yang Berkonflik
Setelah kernel panic, kehilangan daya, atau `kill -9`, file PID lama mungkin tetap ada di disk. MySQL menolak untuk memulai jika menemukannya.
“`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
“`
Jika instance MySQL atau MariaDB lain benar-benar berjalan dan menempati port 3306:
“`bash
sudo ss -tlnp | grep 3306
sudo systemctl stop mariadb
sudo systemctl stop mysql
sudo killall -9 mysqld mysqld_safe
“`
Tunggu tiga detik setelah mematikan proses sebelum mencoba restart untuk memberi waktu status TIME_WAIT socket kernel untuk dibersihkan.
Langkah 6 — Periksa Kebijakan AppArmor dan SELinux
Penyebab ini hampir tidak pernah disebutkan dalam tutorial dasar, namun bertanggung jawab atas persentase yang signifikan dari kesalahan file PID pada sistem Ubuntu dan keluarga RHEL.
Ubuntu / AppArmor:
“`bash
sudo dmesg | grep -i apparmor | grep -i mysql
sudo grep -i "DENIED" /var/log/syslog | grep mysql
“`
Jika AppArmor memblokir MySQL, perbarui profil atau atur sementara ke mode complain untuk diagnosis:
“`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
“`
Perbaikan umum untuk masalah konteks SELinux setelah memindahkan direktori data:
“`bash
sudo semanage fcontext -a -t mysqld_db_t "/new/datadir(/.*)?"
sudo restorecon -Rv /new/datadir
“`
Langkah 7 — Diagnosa dan Perbaiki Kerusakan InnoDB
Jika log kesalahan mengandung pesan seperti `InnoDB: Corruption detected`, `[ERROR] InnoDB: Unable to lock ./ibdata1`, atau referensi ke inkonsistensi redo log, tablespace InnoDB itu sendiri rusak.
Untuk tabel MyISAM, gunakan `mysqlcheck`:
“`bash
sudo mysqlcheck –all-databases –repair –user=root –password
“`
Untuk kerusakan InnoDB, `mysqlcheck` tidak cukup. Pendekatan yang benar adalah mengaktifkan mode pemulihan paksa InnoDB di `my.cnf`:
“`ini
[mysqld]
innodb_force_recovery = 1
“`
Mulai MySQL dengan pengaturan ini, segera dump semua database, lalu bangun ulang:
“`bash
mysqldump –all-databases –single-transaction -u root -p > full_backup.sql
“`
Tingkatkan `innodb_force_recovery` dari 1 ke 6 hanya jika nilai yang lebih rendah gagal memulai server. Pada level 4 ke atas, kehilangan data mungkin terjadi — perlakukan instance sebagai hanya-baca dan ekspor segera.
Setelah dump berhasil:
“`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
“`
Langkah 8 — Isolasi Kesalahan Konfigurasi di my.cnf
Satu kesalahan ketik atau direktif yang tidak valid di `my.cnf` akan membatalkan startup sebelum file PID ditulis. MySQL 8.0+ lebih ketat tentang opsi yang tidak dikenal dibandingkan 5.7.
“`bash
Validate configuration without starting the server
mysqld –validate-config
Or test with verbose output
mysqld –verbose –help > /dev/null
“`
Cadangkan dan sederhanakan konfigurasi ke default:
“`bash
sudo cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak.$(date +%F)
“`
Direktif bermasalah yang umum setelah pembaruan versi mayor mencakup opsi yang sudah tidak digunakan seperti `query_cache_size`, `query_cache_type`, `innodb_file_format`, dan `innodb_large_prefix` — semuanya dihapus di MySQL 8.0.
Langkah 9 — Restart MySQL dan Validasi
“`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
“`
Langkah 10 — Menginstal Ulang MySQL (Upaya Terakhir dengan Pelestarian Data)
Penginstalan ulang hanya boleh dilakukan setelah menghabiskan setiap langkah diagnostik di atas. Sebelum melanjutkan, cadangkan semua data:
“`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)/
“`
Kemudian hapus dan instal ulang:
“`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
“`
Pulihkan dari dump:
“`bash
mysql -u root -p < /backup/full_$(date +%F).sql
“`
Memilih Lingkungan Hosting yang Tepat untuk Mencegah Terulangnya Masalah
Banyak dari kegagalan ini — kehabisan disk, reset izin setelah reboot, persaingan sumber daya dari layanan yang di-host bersama — adalah masalah infrastruktur sebanyak masalah MySQL. Menjalankan database produksi pada server yang disediakan dengan baik dengan sumber daya khusus menghilangkan seluruh kategori kesalahan ini.
Jika Anda mengelola aplikasi berbasis MySQL, lingkungan VPS Hosting memberi Anda akses root penuh, sumber daya yang terisolasi, dan kemampuan untuk mengonfigurasi `tmpfiles.d`, profil AppArmor, dan penggantian unit systemd tanpa batasan. Untuk database dengan lalu lintas tinggi yang memerlukan IOPS dan RAM yang terjamin, Dedicated Servers menghilangkan semua kekhawatiran berbagi sumber daya sepenuhnya.
Untuk tim yang lebih memilih panel kontrol yang dikelola daripada administrasi CLI langsung, VPS dengan cPanel menyediakan antarmuka manajemen MySQL bersama akses tingkat server. Jika stack Anda juga memerlukan konfigurasi domain dan DNS, Pendaftaran Domain dan Sertifikat SSL dapat dikelola dari penyedia yang sama, mengurangi beban operasional.
Matriks Keputusan: Perbaikan Mana yang Diterapkan Pertama
| Gejala dalam Log Kesalahan | Tindakan Pertama | Perkiraan Waktu Penyelesaian |
|---|---|---|
| — | — | — |
| `Permission denied` pada direktori PID atau data | Perbaiki kepemilikan dengan `chown mysql:mysql` | 2 menit |
| `No space left on device` | Hapus binary log, perluas disk | 5–30 menit |
| `A mysqld process already exists` | Hapus file PID lama, matikan proses orphan | 2 menit |
| `Bind on TCP/IP port: Address already in use` | Hentikan instance yang berkonflik, periksa `ss -tlnp` | 5 menit |
| `InnoDB: Corruption detected` | Aktifkan `innodb_force_recovery`, dump, bangun ulang | 30 menit hingga beberapa jam |
| `apparmor="DENIED"` di syslog | Perbarui profil AppArmor atau atur mode complain | 10 menit |
| `unknown variable` di log | Jalankan `mysqld –validate-config`, perbaiki `my.cnf` | 5 menit |
| Tidak ada kesalahan spesifik, semua upaya gagal | Instal ulang MySQL, pulihkan dari backup | 1–2 jam |
Daftar Periksa Poin Penting Teknis
- Selalu baca `/var/log/mysql/error.log` atau `/var/log/mysqld.log` sebelum menyentuh file apa pun — baris `[ERROR]` pertama mengidentifikasi penyebab sebenarnya.
- Pada sistem systemd dengan `tmpfs` di `/var/run`, buat aturan `/etc/tmpfiles.d/mysqld.conf` yang persisten untuk mencegah reset izin pada setiap reboot.
- Setelah `rsync` atau pemulihan backup manual, jalankan `chown -R mysql:mysql /var/lib/mysql` sebelum mencoba memulai MySQL.
- Periksa `df -i` (penggunaan inode) bersama `df -h` (ruang disk) — tabel inode yang penuh menghasilkan gejala yang identik dengan disk yang penuh.
- Untuk kerusakan InnoDB, gunakan `innodb_force_recovery` secara bertahap dari 1 ke atas; jangan langsung ke level 6.
- Validasi sintaks `my.cnf` dengan `mysqld –validate-config` sebelum restart — ini menangkap kesalahan ketik tanpa percobaan start yang gagal.
- Hapus direktif MySQL 5.7 yang sudah tidak digunakan (`query_cache_*`, `innodb_file_format`) sebelum memperbarui ke MySQL 8.0.
- Di Ubuntu, periksa penolakan AppArmor di `/var/log/syslog`; di RHEL/AlmaLinux, periksa SELinux dengan `ausearch -c mysqld`.
Pertanyaan yang Sering Diajukan
Apa cara tercepat untuk mengetahui mengapa MySQL gagal memulai?
Jalankan `sudo tail -50 /var/log/mysql/error.log` dan cari baris pertama yang mengandung `[ERROR]` atau `[FATAL]`. Satu baris tersebut mengidentifikasi penyebab utama dalam sebagian besar kasus dan menentukan perbaikan mana yang harus diterapkan.
Mengapa direktori PID kehilangan izinnya setelah reboot?
Pada distribusi Linux yang menggunakan `tmpfs` untuk `/var/run` (termasuk Ubuntu 18.04+ dan Debian 10+), seluruh pohon `/var/run` dibangun ulang di memori saat boot. Direktori mana pun yang tidak didefinisikan di `/etc/tmpfiles.d/` dibuat ulang sebagai `root:root`. Perbaikannya adalah menambahkan aturan `tmpfiles.d`: `echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf`.
Bisakah saya memulihkan data jika MySQL sama sekali tidak mau memulai karena kerusakan InnoDB?
Ya, dalam sebagian besar kasus. Atur `innodb_force_recovery = 1` di `my.cnf`, mulai MySQL, dan segera jalankan `mysqldump –all-databases`. Jika level 1 tidak memulai server, tingkatkan ke 2, lalu 3, dan seterusnya. Pada level 4–6, beberapa data mungkin tidak dapat dipulihkan, tetapi sebagian besar tabel biasanya masih utuh.
Bagaimana cara mencegah "no space left on device" mematikan MySQL lagi?
Aktifkan kedaluwarsa binary log: atur `binlog_expire_logs_seconds = 604800` (7 hari) di `my.cnf`. Selain itu, nonaktifkan log kueri umum di produksi (`general_log = 0`) dan siapkan peringatan penggunaan disk pada kapasitas 80% melalui sistem pemantauan Anda.
Apakah kesalahan ini juga terjadi pada MariaDB, dan apakah perbaikannya sama?
Ya. MariaDB menggunakan mekanisme file PID yang sama dan struktur direktori data yang sama seperti MySQL. Semua langkah diagnostik dalam panduan ini berlaku langsung untuk MariaDB, dengan satu-satunya perbedaan bahwa nama layanannya adalah `mariadb` bukan `mysql` dalam perintah `systemctl`, dan log kesalahan mungkin berada di `/var/log/mariadb/mariadb.log` tergantung pada distribusinya.
