15%

Save 15% on All Hosting Services

Test your skills and get Discount on any hosting plan

Use code:

Skills
Get Started
09.10.2024

MySQL Error: The Server Quit Without Updating PID File — Complete Diagnostic and Fix Guide

The "The server quit without updating PID file" error means MySQL terminated before it could write its process identifier to the configured `.pid` file — a hard stop that prevents the daemon from accepting connections. This failure is almost always a symptom of a deeper issue: a misconfiguration in `my.cnf`, a permissions mismatch on the data directory, a full disk partition, table-level corruption, or a port conflict with a second MySQL or MariaDB instance.

This guide walks through every confirmed root cause, provides exact shell commands to diagnose and repair each one, and covers edge cases that generic tutorials routinely miss.

What the PID File Actually Does and Why Its Absence Matters

MySQL writes its process ID (PID) to a small plain-text file — typically `/var/run/mysqld/mysqld.pid` — immediately after the daemon initializes. Init systems, service managers (systemd, SysVinit), and monitoring tools read this file to send signals to the correct process. If MySQL crashes, exits abnormally, or encounters a fatal error during startup, it never reaches the point of writing that file. The service manager then reports the "quit without updating PID file" message.

Understanding this sequence is critical: the PID file error is a *consequence*, not the root cause. Chasing the PID file itself without reading the error log first is the single most common mistake administrators make.

Common Root Causes at a Glance

Root CauseTypical Symptom in Error LogAffected Systems
Wrong `pid-file` path in `my.cnf``Can't start server: can't create PID file`All distros
Incorrect ownership on `/var/run/mysqld``Permission denied` on PID directoryDebian/Ubuntu after upgrades
Full disk or inode exhaustion`No space left on device`Any server with small `/var`
Corrupted `ibdata1` or InnoDB redo logs`InnoDB: Corruption detected`MySQL 5.7, 8.0, MariaDB
Stale `.pid` file from a previous crash`A mysqld process already exists`Any system after hard reboot
Port 3306 already in use`Can't start server: Bind on TCP/IP port`Multi-instance setups
AppArmor or SELinux policy denial`apparmor="DENIED"` in syslogUbuntu, RHEL/CentOS
Mismatched `datadir` after package upgrade`[ERROR] Fatal error: Can't open and lock privilege tables`Major version upgrades

Step 1 — Read the MySQL Error Log First

Every other step depends on what the error log says. Do not skip this.

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

“`

Search for lines containing `[ERROR]`, `[FATAL]`, `Aborting`, or `InnoDB`. The first `[ERROR]` entry in the startup sequence is almost always the true cause.

Step 2 — Verify and Fix the PID File Directory

The PID directory is often recreated as `root`-owned after a system reboot because `/var/run` is a `tmpfs` mount on modern Linux distributions. This is one of the most frequently overlooked causes on Ubuntu 20.04+ and 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

“`

To make this persistent across reboots on systemd systems, create a `tmpfiles.d` rule:

“`bash

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

“`

Confirm the PID path configured in `my.cnf` matches the directory you just created:

“`bash

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

“`

Step 3 — Audit Data Directory Ownership and Permissions

MySQL's data directory must be owned entirely by the `mysql` system user. Package upgrades, manual file copies, or restores from backup frequently break this.

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

“`

Important edge case: If you restored a backup using `rsync` or `cp` as `root`, the socket file `/var/lib/mysql/mysql.sock` may also be root-owned. Remove it — MySQL will recreate it on startup:

“`bash

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

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

“`

Step 4 — Check Disk Space and Inode Availability

A full disk silently prevents MySQL from writing any file, including the PID file and binary logs.

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

“`

If the partition is full, common culprits are binary logs (`mysql-bin.000*`), general query logs left enabled accidentally, or core dump files. To safely purge old binary logs from within MySQL:

“`bash

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

“`

Step 5 — Eliminate Stale PID Files and Conflicting Processes

After a kernel panic, power loss, or `kill -9`, a stale PID file may remain on disk. MySQL refuses to start if it finds one.

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

“`

If another MySQL or MariaDB instance is genuinely running and occupying port 3306:

“`bash

sudo ss -tlnp | grep 3306

sudo systemctl stop mariadb

sudo systemctl stop mysql

sudo killall -9 mysqld mysqld_safe

“`

Wait three seconds after killing processes before attempting a restart to allow kernel socket TIME_WAIT states to clear.

Step 6 — Check AppArmor and SELinux Policies

This cause is almost never mentioned in basic tutorials, yet it is responsible for a significant percentage of PID file errors on Ubuntu and RHEL-family systems.

Ubuntu / AppArmor:

“`bash

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

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

“`

If AppArmor is blocking MySQL, either update the profile or temporarily set it to complain mode for 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

“`

A common fix for SELinux context issues after moving the data directory:

“`bash

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

sudo restorecon -Rv /new/datadir

“`

Step 7 — Diagnose and Repair InnoDB Corruption

If the error log contains messages like `InnoDB: Corruption detected`, `[ERROR] InnoDB: Unable to lock ./ibdata1`, or references to redo log inconsistencies, the InnoDB tablespace itself is damaged.

For MyISAM tables, use `mysqlcheck`:

“`bash

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

“`

For InnoDB corruption, `mysqlcheck` is insufficient. The correct approach is to enable InnoDB forced recovery mode in `my.cnf`:

“`ini

[mysqld]

innodb_force_recovery = 1

“`

Start MySQL with this setting, immediately dump all databases, then rebuild:

“`bash

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

“`

Increment `innodb_force_recovery` from 1 to 6 only if lower values fail to start the server. At level 4 and above, data loss is possible — treat the instance as read-only and export immediately.

After a successful dump:

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

“`

Step 8 — Isolate Configuration Errors in my.cnf

A single typo or an invalid directive in `my.cnf` will abort startup before the PID file is written. MySQL 8.0+ is stricter about unknown options than 5.7 was.

“`bash

Validate configuration without starting the server

mysqld –validate-config

Or test with verbose output

mysqld –verbose –help > /dev/null

“`

Back up and strip the configuration to defaults:

“`bash

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

“`

Common problematic directives after major version upgrades include deprecated options like `query_cache_size`, `query_cache_type`, `innodb_file_format`, and `innodb_large_prefix` — all removed in MySQL 8.0.

Step 9 — Restart MySQL and Validate

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

“`

Step 10 — Reinstalling MySQL (Last Resort with Data Preservation)

Reinstallation should only happen after exhausting every diagnostic step above. Before proceeding, back up all 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)/

“`

Then remove and reinstall:

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

“`

Restore from dump:

“`bash

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

“`

Choosing the Right Hosting Environment to Prevent Recurrence

Many of these failures — disk exhaustion, permission resets after reboots, resource contention from co-hosted services — are infrastructure problems as much as MySQL problems. Running a production database on a properly provisioned server with dedicated resources eliminates entire categories of these errors.

If you are managing a MySQL-backed application, a VPS Hosting environment gives you full root access, isolated resources, and the ability to configure `tmpfiles.d`, AppArmor profiles, and systemd unit overrides without restriction. For high-traffic databases requiring guaranteed IOPS and RAM, Dedicated Servers remove all resource-sharing concerns entirely.

For teams that prefer a managed control panel rather than direct CLI administration, VPS with cPanel provides MySQL management interfaces alongside server-level access. If your stack also requires domain and DNS configuration, Domain Registration and SSL Certificates can be managed from the same provider, reducing operational overhead.

Decision Matrix: Which Fix to Apply First

Symptom in Error LogFirst ActionEstimated Resolution Time
`Permission denied` on PID or data dirFix ownership with `chown mysql:mysql`2 minutes
`No space left on device`Purge binary logs, expand disk5–30 minutes
`A mysqld process already exists`Remove stale PID file, kill orphan process2 minutes
`Bind on TCP/IP port: Address already in use`Stop conflicting instance, check `ss -tlnp`5 minutes
`InnoDB: Corruption detected`Enable `innodb_force_recovery`, dump, rebuild30 minutes to several hours
`apparmor="DENIED"` in syslogUpdate AppArmor profile or set complain mode10 minutes
`unknown variable` in logRun `mysqld –validate-config`, fix `my.cnf`5 minutes
No specific error, all else failsReinstall MySQL, restore from backup1–2 hours

Technical Key-Takeaway Checklist

  • Always read `/var/log/mysql/error.log` or `/var/log/mysqld.log` before touching any file — the first `[ERROR]` line identifies the actual cause.
  • On systemd systems with `tmpfs` on `/var/run`, create a persistent `/etc/tmpfiles.d/mysqld.conf` rule to prevent permission resets on every reboot.
  • After any `rsync` or manual backup restore, run `chown -R mysql:mysql /var/lib/mysql` before attempting to start MySQL.
  • Check `df -i` (inode usage) alongside `df -h` (disk space) — a full inode table produces identical symptoms to a full disk.
  • For InnoDB corruption, use `innodb_force_recovery` incrementally from 1 upward; never jump straight to level 6.
  • Validate `my.cnf` syntax with `mysqld –validate-config` before restarting — this catches typos without a failed start attempt.
  • Remove deprecated MySQL 5.7 directives (`query_cache_*`, `innodb_file_format`) before upgrading to MySQL 8.0.
  • On Ubuntu, check AppArmor denials in `/var/log/syslog`; on RHEL/AlmaLinux, check SELinux with `ausearch -c mysqld`.

Frequently Asked Questions

What is the fastest way to find why MySQL failed to start?

Run `sudo tail -50 /var/log/mysql/error.log` and look for the first line containing `[ERROR]` or `[FATAL]`. That single line identifies the root cause in the vast majority of cases and determines which fix to apply.

Why does the PID directory lose its permissions after a reboot?

On Linux distributions using `tmpfs` for `/var/run` (which includes Ubuntu 18.04+ and Debian 10+), the entire `/var/run` tree is rebuilt in memory at boot. Any directory not defined in `/etc/tmpfiles.d/` is recreated as `root:root`. The fix is to add a `tmpfiles.d` rule: `echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf`.

Can I recover data if MySQL will not start at all due to InnoDB corruption?

Yes, in most cases. Set `innodb_force_recovery = 1` in `my.cnf`, start MySQL, and immediately run `mysqldump –all-databases`. If level 1 does not start the server, increment to 2, then 3, and so on. At levels 4–6, some data may be unrecoverable, but the majority of tables are typically intact.

How do I prevent "no space left on device" from taking down MySQL again?

Enable binary log expiration: set `binlog_expire_logs_seconds = 604800` (7 days) in `my.cnf`. Additionally, disable the general query log in production (`general_log = 0`) and set up a disk usage alert at 80% capacity through your monitoring system.

Does this error occur on MariaDB as well, and is the fix the same?

Yes. MariaDB uses the same PID file mechanism and the same data directory structure as MySQL. All diagnostic steps in this guide apply directly to MariaDB, with the only difference being that the service name is `mariadb` instead of `mysql` in `systemctl` commands, and the error log may be located at `/var/log/mariadb/mariadb.log` depending on the distribution.

15%

Save 15% on All Hosting Services

Test your skills and get Discount on any hosting plan

Use code:

Skills
Get Started