Auto-restart mysql when it dies
I have a rackspace server that I have been renting to run my personal projects upon. Since I am cheap, it has 256Mb of RAM and honestly can't handle alot. Every once in a while, when there is a sharp uptick in traffic, the server decides to start killing processes and it seems that mysqld is a popular one for it to kill. I try to visit my site and am greeted with the message that there was an error establishing the database connection. Inspection of the logs reveals that mysqld was killed due to lack of memory.
Since I am still as poor as I was yesterday and don't want to upgrade my rackspace VM's RAM, is there a way I can tell it to automagically restart mysqld when it dies?
I have a thought to use something like crontab, but alas, I don't know exactly what to do there either. I guess I am product of the "Linux on your desktop" generation since I can do most things on my desktop and laptop (which run Linux almost exclusively), but still lack a lot of server administration skills for Linux.
The server runs CentOS 6.3
Solution 1:
This is not a clean solution, it would obviously be better to avoid the problem in the first place. Anyway, I am not sure how CentOS manages services but I think it uses service
. If so, you can check if the mysql
service is running with
/sbin/service mysql status
This command will exit successfully if mysql
is running and return a non 0 exit status if i is not. You can therefore start the service if it is not running with this command:
/sbin/service mysql status || service mysql start
You can add this line to /etc/crontab
to launch thes command every minute:
* * * * * /sbin/service mysql status || service mysql start
Solution 2:
This is a little disturbing.
mysqld is always restarted by mysqld_safe because there is an infinite loop in the bottom of mysqld_safe
to check for abnormal shutdowns. If the error is too severe, not even mysqld_safe
would not be able to restart mysqld
on subsequent tries.
Given that situation that mysqld_safe
is designed for, it may not be a good idea to force mysqld
to start if mysqld_safe
will reject it anyway.
You need to locate the error log in my.cnf it will be under
[mysqld]
log-error=log-filename
or
[mysqld_safe]
log-error=log-filename
Read the text file (probably by running tail -30 log-filename
) and find the source of the mysqld processing shutting down.
Solution 3:
In a brute force attempt to keep things up and running on a low-memory VPS, I used a modification of terdom's answer to check and restart MySQL.
/sbin/service mysqld status || service mysqld restart
I needed to change mysql
to mysqld
to get it to work. Without it I would get the error, "ERROR! MySQL is running but PID file could not be found
".
On my CentOS 7.2 system, /sbin/service
redirects to /bin/systemctl status
, so the following command is faster to execute.
/bin/systemctl status mysqld.service || /bin/systemctl start mysqld.service
I ended up adding the following line to the system's root crontab. It checks every minute if MySQL is running and redirect stdout to null. Starting the service won't output anything unless something goes wrong, so there's no need to add the null redirect on the last command.
* * * * * /bin/systemctl status mysqld.service > /dev/null || /bin/systemctl start mysqld.service
The double pipe ||
means OR
and will execute the 2nd command if the first command fails somehow. (Returns an exit code greater than zero.)
It's like saying, "Run the 1st command, or, if the 1st command fails somehow, run the 2nd command".
This is unlike the double ampersand &&
which is like saying, "Run the 1st command, and, only if the 1st command was successful, run the 2nd command".
Solution 4:
The following is from jonnyreeves.co.uk :
And the culprit is php-fpm! A quick google found another Wordpress customer suffering from similar symptoms; the advice was to tweak the php-fpm pool configuration (/etc/php-fpm.d/www.conf) and tweak the pm configuration. The main change was to move from pm = dynamic
to pm = ondemand
with a pm.max_children
value of 5
(based on observing ~5% memory usage per worker). After changing the configuration I restarted all services and checked the memory usage.
service php-fpm restart
service nginx restart
service mariadb restart
After restarting the memory usage was dramatically lower.