MySQL Service Management and Startup Failures
Stopping MySQL removes its socket directory, which is why `ERROR 2002` names a file that is not there. Then a bad setting is added on purpose so `mysqld --validate-config` has something real to catch - and the restart it would have prevented fails into a systemd restart loop.
Foundations Guide 5 of 45 Intermediate
- OSUbuntu 26.04 LTS (resolute)
- MySQL8.4.10-0ubuntu0.26.04.1
- Packagemysql-server (Ubuntu archive)
- TimeAbout 16 min
- Reviewed27 August 2026
Written against the versions above. The unit is named `mysql` on Debian and Ubuntu and `mysqld` on RPM builds. Everything else here is the same.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| db-a01 | 192.168.0.81 | Ubuntu 26.04 LTS | Primary / Source / Replica Set Member 1 | 2 Core | 4 GB | 50 GB |
Before you start
- MySQL installed and running on db-a01.
sudoaccess. This guide deliberately stops the server and breaks its configuration, so run it somewhere nothing depends on.
-
Read the service state
systemctl statusin one view: whether the unit is loaded, whether it is enabled, whether it is running, since when, and the last few log lines.It is the right first command for a service problem because it answers "is it even trying" before you go looking at MySQL itself.
bash Example session systemctl status mysql --no-pager | head -12● mysql.service - MySQL Community Server Loaded: loaded (/usr/lib/systemd/system/mysql.service; enabled; preset: enabled) Active: active (running) since Thu 2026-08-27 12:31:42 UTC; 36s ago Invocation: f31dd5aca1e548dd8148c4aa5e4387f0 Process: 8419 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS) Main PID: 8429 (mysqld) Status: "Server is operational" Tasks: 40 (limit: 1658) Memory: 476M (peak: 476.2M) CPU: 499ms CGroup: /system.slice/mysql.service └─8429 /usr/sbin/mysqldExpected result
loaded,enabled, andactive (running)with a start time.Success conditionYou can read the unit's state and recent history in one command.
-
Read the unit file itself
systemctl catprints the unit as systemd sees it, including any drop-ins. Worth doing once so the service stops being a black box.Two things to note for later: the unit has a
Restart=policy, which is what produces the loop in a few steps' time, andExecStartruns/usr/sbin/mysqlddirectly - the same binary you will run by hand to validate the config.bash Example session systemctl cat mysql | head -22# /usr/lib/systemd/system/mysql.service# MySQL systemd service file [Unit]Description=MySQL Community ServerAfter=network.target [Install]WantedBy=multi-user.target [Service]Type=notifyUser=mysqlGroup=mysqlPermissionsStartOnly=trueExecStartPre=/usr/share/mysql/mysql-systemd-start preExecStart=/usr/sbin/mysqldTimeoutSec=infinityRestart=on-failureRuntimeDirectory=mysqldExpected resultThe
[Unit],[Service]and[Install]sections ofmysql.service.Success conditionYou know what the service actually runs and how it behaves on failure.
-
Stop it, and watch the socket disappear
Three commands that together explain the most common MySQL error message.
is-activereturnsinactivewith exit status 3 - systemd's convention for "not running", and a useful thing to test in a script.Then the client fails with
ERROR 2002 ... (2), and the(2)isENOENT: no such file. The last command shows why -/var/run/mysqld/does not exist at all. The directory is created at startup and removed at shutdown, so a missing socket file is not corruption. It is a stopped server.bash Example session systemctl is-active mysql ; echo "exit=$?"inactiveexit=3sudo mysql -e "SELECT 1" ; echo "exit=$?"ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)exit=1ls -l /var/run/mysqld/ ; echo "exit=$?"ls: cannot access '/var/run/mysqld/': No such file or directoryexit=2Expected result
inactivewith exit 3,ERROR 2002naming the socket, andNo such file or directory.Success conditionYou can recognise ERROR 2002 as a stopped server rather than a broken one.
-
Start it again and validate the configuration
The server comes back, and then a command worth building a habit around.
mysqld --validate-configparses every configuration file the server would read and exits without starting anything.exit=0and no output means the configuration is valid.It costs a fraction of a second and it is the difference between finding a typo now and finding it during a restart at the worst possible moment.
bash Example session sudo systemctl start mysqlsystemctl is-active mysqlactivesudo mysqld --validate-config ; echo "exit=$?"exit=0Expected result
active, thenexit=0with no output from the validator.Success conditionYou have a way to check a config change before it costs you an outage.
-
Break it on purpose
A backup first, then an invalid value appended to the config -
innodb_buffer_pool_size = not-a-size. A plausible typo: the setting is real and the value is not.--validate-confignow prints four errors and exits 1. Read them from the top: the first names the actual problem - an unknown suffix in the value - and the rest are consequences, ending inAborting.This is the whole point of the tool. The server has not been restarted, so it is still running and still serving. Nothing is down.
bash Example session printf 'innodb_buffer_pool_size = not-a-size\n' | sudo tee -a /etc/mysql/mysql.conf.d/mysqld.cnfinnodb_buffer_pool_size = not-a-sizesudo mysqld --validate-config ; echo "exit=$?"2026-08-27T12:32:24.420115Z 0 [ERROR] [MY-000058] [Server] Unknown suffix 'n' used for variable 'innodb-buffer-pool-size' (value 'not-a-size').2026-08-27T12:32:24.420136Z 0 [ERROR] [MY-000077] [Server] /usr/sbin/mysqld: Error while setting value 'not-a-size' to 'innodb-buffer-pool-size'.2026-08-27T12:32:24.420139Z 0 [ERROR] [MY-010746] [Server] Parsing options for plugin 'InnoDB' failed.2026-08-27T12:32:24.420287Z 0 [ERROR] [MY-000067] [Server] unknown variable 'innodb_buffer_pool_size=not-a-size'.2026-08-27T12:32:24.420298Z 0 [ERROR] [MY-010119] [Server] Abortingexit=1Expected result
MY-000058 Unknown suffix 'n', three more errors, andexit=1- with the running server untouched.Success conditionYou have seen the validator catch a real error before it caused an outage.
-
Ignore the warning and restart, which is what usually happens
What the validator was trying to prevent.
systemctl restartfails with exit 1 and points at two other commands. Thenis-activereturns something worse thaninactive-activating. The unit'sRestart=policy is retrying, and it will keep retrying.This state is genuinely confusing in an incident: the service is neither up nor cleanly down, and a monitoring check that only tests
inactivewill not fire.bash Example session sudo systemctl restart mysql ; echo "exit=$?"Job for mysql.service failed because the control process exited with error code.See "systemctl status mysql.service" and "journalctl -xeu mysql.service" for details.exit=1systemctl is-active mysql ; echo "exit=$?"activatingexit=3Expected result
Job for mysql.service failed,exit=1, thenactivating- notinactive.Success conditionYou can recognise a restart loop from
is-activealone. -
Read the journal, then put it back
journalctl -u mysqlis the log for the unit. Therestart counter is at 1and thenat 2lines are the loop, one entry per attempt, withcode=exited, status=1/FAILUREbetween them.Note what the journal does not say: it does not name the bad setting. systemd reports that the process exited; the reason lives in MySQL's own error output, which is what
--validate-configshowed you two steps ago. That is why the validator is the faster path.Restoring the backup and validating returns
exit=0, and the server starts.bash Example session sudo journalctl -u mysql -n 8 --no-pagerAug 27 12:32:25 db-a01 systemd[1]: mysql.service: Scheduled restart job, restart counter is at 1.Aug 27 12:32:25 db-a01 systemd[1]: Starting mysql.service - MySQL Community Server...Aug 27 12:32:26 db-a01 systemd[1]: mysql.service: Main process exited, code=exited, status=1/FAILUREAug 27 12:32:26 db-a01 systemd[1]: mysql.service: Failed with result 'exit-code'.Aug 27 12:32:26 db-a01 systemd[1]: Failed to start mysql.service - MySQL Community Server.Aug 27 12:32:26 db-a01 systemd[1]: mysql.service: Consumed 224ms CPU time over 399ms wall clock time, 245.2M memory peak.Aug 27 12:32:26 db-a01 systemd[1]: mysql.service: Scheduled restart job, restart counter is at 2.Aug 27 12:32:26 db-a01 systemd[1]: Starting mysql.service - MySQL Community Server...sudo cp /tmp/mysqld.cnf.bak /etc/mysql/mysql.conf.d/mysqld.cnfsudo mysqld --validate-config ; echo "exit=$?"exit=0systemctl is-active mysqlactiveExpected resultRestart counters climbing, then a clean validate and
active.Success conditionThe server is back, and you know which tool would have caught it first.
Troubleshooting
ERROR 2002 ... (2)naming/var/run/mysqld/mysqld.sock.Why: The server is stopped. The socket and its directory only exist while it runs.
Fix:
systemctl is-active mysql. If it is inactive, start it; if it isactivating, you are in a restart loop and the config is the place to look.systemctl restartfails and the service will not stay up.Why: Almost always a configuration error introduced since the last successful start - which may have been weeks ago.
Fix:
sudo mysqld --validate-config. It names the setting; the journal only reports that the process exited.is-activesaysactivatingand never settles.Why: The unit's
Restart=policy is retrying a start that keeps failing.Fix:
sudo systemctl stop mysqlto break the loop before you debug, so you are not fighting a process that respawns while you edit.Config changes appear to have no effect.
Why: Either the file is not one the server reads, or the setting needs a restart.
Fix:
sudo mysqld --validate-configparses the same files the server would - if your typo is not reported, the server is not reading that file either.
Official sources
- MySQL 8.4 Reference Manual - mysql_secure_installation
- MySQL 8.4 Reference Manual - The Password Validation Component
- MySQL 8.4 Reference Manual - mysql, the MySQL Command-Line Client
- MySQL 8.4 Reference Manual - Connecting to the MySQL Server
- MySQL 8.4 Reference Manual - Server System Variables (bind_address)