Shell script issue: cron job script to Restart MySQL server when it stops accidentally

37,973

Solution 1

I suspect that you setup the cron job to execute this script in your crontab file, and not in the root crontab file. This is not correct because if you don't run service mysql status as root, the mysql service will not be recognized.

So, modify the script as follow:

#!/bin/bash
if [[ ! "$(/usr/sbin/service mysql status)" =~ "start/running" ]]
then
    /usr/sbin/service mysql start
fi

Be sure that is executable:

chmod +x /path/to/script

Then add a new entry in the root crontab as follow:

  • Edit root crontab file using:

    sudo crontab -e
    
  • And add the following line to the file:

    */1 * * * * /path/to/script
    
  • Note: I have set the cron job for every minute, but you can change as you wish or as you think is better. See http://en.wikipedia.org/wiki/Cron in this sense.

Solution 2

Radu's answer nearly worked. I had to set the path to make it work:

#!/bin/bash
PATH=/usr/sbin:/usr/bin:/sbin:/bin
if [[ ! "$(service mysql status)" =~ "start/running" ]]
then
    service mysql start
fi

Solution 3

Radu's answer works - but this script works as well

#!/bin/bash
if [[ $(pgrep mysql | wc -l) = 0 ]];
then
    sudo service mysql start;
fi

Solution 4

Restart

With systemd you can setup your service to Restart on certain conditions:

systemctl cat mysql.service | grep Restart     # Check current status

Probably you wish to move from on-abort to on-failure

sudo EDITOR=nano systemctl edit mysql.service

Other useful commands:

sudo systemctl daemon-reload  # Reload systemd manager configuration. `systemctl edit` automatically does this for you.
systemctl cat mysql.service   # unit configuration
systemd-delta                 # Check the whole system changes

OOMScoreAdjust

On the same place, you may also want to adjust systemd OOMScoreAdjust:

Sets the adjustment value for the Linux kernel's Out-Of-Memory (OOM) killer score for executed processes. Takes an integer between -1000 (to disable OOM killing of processes of this unit) and 1000 (to make killing of processes of this unit under memory pressure very likely).

# Useful options not previously available in [mysqld_safe]

# Kernels like killing mysqld when out of memory because its big.
# Lets temper that preference a little.
# OOMScoreAdjust=-600

Read also this excellent answer.


You can also reduce the memory usage of MySQL/MariaDB by tuning some options like max_connections, innodb_buffer_pool_size and innodb_buffer_pool_instances (probably on /etc/mysql/mariadb.conf.d/50-server.cnf).

Share:
37,973

Related videos on Youtube

Straw Hat
Author by

Straw Hat

Updated on September 18, 2022

Comments

  • Straw Hat
    Straw Hat over 1 year

    I have this script, I am using it to setup CRON job to execute this script, so it can check if MySQL service is running; if not then it restart the MySQL service:

    #!/bin/bash
    service mysql status| grep 'mysql start/running' > /dev/null 2>&1
    if [ $? != 0 ]
    then
        sudo service mysql restart
    fi
    

    I have setup cron job as.

    sudo crontab -e
    

    and then added,

    */1 * * * * /home/ubuntu/mysql-check.sh
    

    Problem is that it restart MySQL on every cron job execution.. even if server is running it restart the MySQL service what is correction in the script to do that.

    • Alexej Magura
      Alexej Magura about 10 years
      why do you have a `\` in front of your shebang? If it's there to keep it from looking like a comment, then it's unnecessary. Shebangs are treated special like by Bash, as in they don't need to be escaped because they aren't comments in the sense that a comment is a piece of code that is not evaluated at all.
    • Alexej Magura
      Alexej Magura about 10 years
      Also, avoid using [ ... ] or test <TEST> in Bash. They're deprecated syntax. Use [[ ... ]] instead. Only use [ ... ] and/or test <TEST> when [[ ... ]] is not available.
    • Straw Hat
      Straw Hat about 10 years
      this is first shell script I tried by using some available scripts, I just modified it. don't know much about syntax. problem is still there mysql restarts on every CRON job execution @AlexejMagura
    • Alexej Magura
      Alexej Magura about 10 years
      Try something like this: if ! (service mysql status | grep 'mysql start/running' &>/dev/null); then sudo service mysql restart; fi What this does, is it starts up a subshell, wherein service mysql status | grep 'mysql start/running' &> /dev/null gets run, the return (exit) status of said subshell then gets passed to the if-statement, which then checks to see if it is non-zero, and if it is not non-zero then it runs the then block.
    • Flint
      Flint about 10 years
      Doesn't mysql write its process pid to pid file? If it does you could use that as another way to check your mysql status
    • raj
      raj over 2 years
      Quite a long time ago, MySQL installation came with the default script called safe_mysqld or something like this (I don't remember details anymore) that was used to start the service. This script itself was monitoring the service and restarting it if it happens to crash. Is it no more the case?
  • Straw Hat
    Straw Hat about 10 years
    I setup it as crontab, I guess problem is with the script, i'll try above script
  • Radu Rădeanu
    Radu Rădeanu about 10 years
    @Flint That's true also... Sorry, I'm still drinking my morning coffee. :)
  • Radu Rădeanu
    Radu Rădeanu about 10 years
    @D_Vaibhavツ Now should be everything OK. So, try now, as root.
  • Straw Hat
    Straw Hat about 10 years
    I have added crontab as */1 * * * * /home/ubuntu/mysql-check.sh
  • Radu Rădeanu
    Radu Rădeanu over 9 years
    In fact I have set my PATH in the crontab file. Anyway, in your case you need to use PATH=/usr/sbin:$PATH or use the full path for service as I edited my answer.
  • emeraldjava
    emeraldjava over 8 years
    I had to add @donkzilla PATH value to my crontab in order for it to work.
  • Alin C
    Alin C about 6 years
    I checked the pgrep mysql and I got 0 for mysql being stopped and 2 for running. Therefor I set the condition asif [[ $(pgrep mysql | wc -l) = 0 ]]; and it worked for me.
  • JxAxMxIxN
    JxAxMxIxN about 6 years
    probably better your way... I'll make the change.
  • Bira
    Bira over 5 years
    I added echo "MySQL restarted" | mail -s "vvaaccc.com MySQL" [email protected] to get notified each time restart the mysql, each time I run the bash file it is sending the mail, so I feel if condition is not checking well where there mysql is running or not, so it is restarting the service each time.
  • Bira
    Bira over 5 years
    #!/bin/bash TMP=mysqladmin -u root -pPassword status 2>&1 | head -n 1 | cut -f1 -d: case ${TMP} in Uptime) echo "MySQL is running." echo "You are good" ;; *) service mysql restart # the following sends an email for notification, change email address if needed. echo "MySQL restarted" | mail -s "your-site-name.com MySQL" [email protected] ;; esac
  • omega1
    omega1 about 5 years
    I had to change "start/running" to "active (running)" and then it worked
  • mahfuz
    mahfuz about 5 years
    This script works with /bin/bash(it does not work without bash). */1 * * * * /bin/bash /root/mysql-check.sh