Shell Script To Backup MySql Database Server

#!/bin/bash
# Shell script to backup MySql database 
# To backup Nysql databases file to /backup dir and later pick up by your 
# script. You can skip few databases from backup too.
# For more info please see (Installation info):
# https://www.cyberciti.biz/nixcraft/vivek/blogger/2005/01/mysql-backup-script.html 
# Last updated: Aug - 2005
# --------------------------------------------------------------------
# This is a free shell script under GNU GPL version 2.0 or above
# Copyright (C) 2004, 2005 nixCraft project
# Feedback/comment/suggestions : http://cyberciti.biz/fb/
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
 
MyUSER="SET-MYSQL-USER-NAME"     # USERNAME
MyPASS="SET-PASSWORD"       # PASSWORD 
MyHOST="localhost"          # Hostname
 
# Linux bin paths, change this if it can not be autodetected via which command
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
CHOWN="$(which chown)"
CHMOD="$(which chmod)"
GZIP="$(which gzip)"
 
# Backup Dest directory, change this if you have someother location
DEST="/backup"
 
# Main directory where backup will be stored
MBD="$DEST/mysql"
 
# Get hostname
HOST="$(hostname)"
 
# Get data in dd-mm-yyyy format
NOW="$(date +"%d-%m-%Y")"
 
# File to store current backup file
FILE=""
# Store list of databases 
DBS=""
 
# DO NOT BACKUP these databases
IGGY="test"
 
[ ! -d $MBD ] && mkdir -p $MBD || :
 
# Only root can access it!
$CHOWN 0.0 -R $DEST
$CHMOD 0600 $DEST
 
# Get all database list first
DBS="$($MYSQL -u $MyUSER -h $MyHOST -p$MyPASS -Bse 'show databases')"
 
for db in $DBS
do
    skipdb=-1
    if [ "$IGGY" != "" ];
    then
	for i in $IGGY
	do
	    [ "$db" == "$i" ] && skipdb=1 || :
	done
    fi
 
    if [ "$skipdb" == "-1" ] ; then
	FILE="$MBD/$db.$HOST.$NOW.gz"
	# do all inone job in pipe,
	# connect to mysql using mysqldump for select mysql database
	# and pipe it out to gz file in backup dir :)
        $MYSQLDUMP -u $MyUSER -h $MyHOST -p$MyPASS $db | $GZIP -9 > $FILE
    fi
done

Save the script and run it as a cron job:
@daily /path/to/yourmysql.sh

Get the latest tutorials on SysAdmin, Linux/Unix, Open Source, and DevOps topics:
CategoryList of Unix and Linux commands
File Management cat
Firewall Alpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilities dig host ip nmap
OpenVPN CentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Manager apk apt
Processes Management bg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searching grep whereis which
User Information groups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPN CentOS 8 Debian 10 Firewall Ubuntu 20.04
55 comments… add one
  • Fachrian Noor May 13, 2013 @ 0:07

    Can you help my problem ?

    in line 55 = DBS=”$($MYSQL -u $MyUSER -h $MyHOST -p$MyPASS -Bse ‘show databases’)”

    when i try to execute, this syntax has a problem, can anyone help to fix it ?

  • Daniel Clarks Dec 5, 2012 @ 21:18

    great!

  • Pedro Braconnot Nov 23, 2012 @ 1:02

    I mean TWO dashes, sorry it did with me again – – .
    Wordpress changes a lot of code stuff…
    two – to one —

  • Pedro Braconnot Nov 23, 2012 @ 0:51

    Using Narendra Gollapilli’s prune lines in Ubuntu Server 11.04, had to change from “rmdir” to:
    rm -rf $RDIR;
    First day so I did not test the seven days cicle, other than that it is working. Also have to replace html left and right “” for “.
    About Niftyapple’s –skip-lock-tables note that html on this page replaced — for –.
    The correct is –skip-lock-tables
    Thanks!

  • Peter Nov 9, 2012 @ 14:08

    Nice little script, handy and quick to use.

    Ashok: Try to delete one of the equal signs on the actual rows you are having problems with.

  • Niftyapple Oct 17, 2012 @ 17:14

    Here is a few tips for things that I ran into.

    First off, root doesnt have access to locked tables, so this is what I did to fix that.

    Edit this line:
    $MYSQLDUMP -u $MyUSER -h $MyHOST -p$MyPASS $db | $GZIP -9 > $FILE

    To:
    $MYSQLDUMP –skip-lock-tables -u $MyUSER -h $MyHOST -p$MyPASS $db | $GZIP -9 > $FILE

    By adding the –skip-lock-tables, the command will ignore the locktable feedback and continue on what it can actually do.

    Secondly, I also was recieving an error like “\r’: command not found”. This is caused from the way DOS(windows) writes a return key. This can be fixed by the following 2 commands:

    apt-get install dos2unix #if it is not installed already
    dos2unix /path/to/file.sh

    I hope this helps someone.
    Enjoy

  • Arvind Aug 18, 2012 @ 6:54

    you can do so by modifying

    IGGY=””

    DBS=””
    or
    DBS=”$($MYSQL -u $MyUSER -h $MyHOST -p$MyPASS -Bse ‘show databases’ |grep )”
    as it will return a list of your databases only which contain the given text.

    It works for my without any error as i saved this as .sh file

  • mccoy Jul 23, 2012 @ 20:34

    hi,

    instead of # DO NOT BACKUP these databases,
    how can i do it as they other way around? (selecting specific database).

    i am very new to linux. please help. thanks alot!

  • Narendra Gollapilli Apr 18, 2012 @ 11:50

    The above lines i have mentioned for backup rotation for 7 days i.e removing data older than 7 days.

  • Narendra Gollapilli Apr 18, 2012 @ 11:49

    You can the below lines before creating directory for today’s backup.

    RDIR=”$DEST/mysql/$(date -d “7 day ago” +”%d%m%Y”)”
    RDIR=
    if [ -d $RDIR ];
    then
    rmdir $RDIR;
    echo “Removing MySQL backup of date $(date -d “7 day ago” +”%d%m%Y”)”
    fi
    Thanks,
    Narendra Gollapilli

  • Ashok Apr 12, 2012 @ 5:25

    I am facing error during run the script

    [: 64: =-1: unexpected operator

  • Ashok Kumar Apr 11, 2012 @ 17:56

    I want to use this mysql backup script with incremental an weekly full backup.

    Can you i use this for this purpose and also facing error during the run this script.

    Error:- [: 70: -1: unexpected operator

    Please help

  • james o Nov 11, 2011 @ 18:20

    thanks! works like a charm! do you rotate or, delete old backups?

  • paul Nov 3, 2011 @ 19:34

    Vivek

    I am new to MYSQL. I saw your script. Please help me understand what you are doing
    in
    MyUSER=”SET-MYSQL-USER-NAME” # USERNAME
    MyPASS=”SET-PASSWORD” # PASSWORD
    MyHOST=”localhost” # Hostname
    eg: variable MyUSER will contain SET-MYSQL-USER-NAME, but i have not see this being used as mysqldump anywhere.

    is INFORMATION_SCHEMA backed up in your script ? Is this useful to backup?

    -all-databases will dump ALL databases, is there any advantage for backing up
    each database?

    Thank You

    paull

    • TurboPT Dec 1, 2011 @ 18:18

      Q1: …but i have not see this being used as mysqldump anywhere.
      A1: see the last if condition.

      Q2a: is INFORMATION_SCHEMA backed up in your script ?
      Q2b: Is this useful to backup?
      A2a: …if it appears in the show databases result, and it is not set to be skipped in the script, then yes.
      A2b: could be. The point is data recovery. Preview that database to see what you could potentially lose if not.

      Q3: …any advantage for backing up each database?
      A3: this is merely an example that you can tailor to your need(s). Having them separately could be advantageous when not “all databases” need to be restored.

  • Conrado Oct 31, 2011 @ 14:17

    Hi,

    I try this script in Ubuntu 10.04 and works great. When I move to centos 5.6 I get the following error:

    No such file or Directory /usr/bin/mysql

    I try the line: DBS=”$($MYSQL -u $MyUSER -h $MyHOST -p$MyPASS -Bse ‘show databases’)” manually and its works great. Any ideas?

    Thanks

    • Conrado Oct 31, 2011 @ 14:18

      Sorry. Mispelld centos 5.4

  • Lucas Oct 6, 2011 @ 7:42

    You dont need to add any databases to the “file” or “dbs” variables. Those empty values just initialize the variable. If you want to skip databases, use a standard list, no commas etc.
    Example:

    IGGY="test thisdatabase thatdatabase herdata mydata"
  • Bangon Kali Jul 5, 2011 @ 14:29

    Thanks dude! :D

  • swapnil Jul 4, 2011 @ 4:45

    # File to store current backup file
    FILE=””
    # Store list of databases
    DBS=””

    # DO NOT BACKUP these databases
    IGGY=”test”

    Hey I want some help on above.
    What shall i add in file?
    And can I add multiple dbs in DBS and IGGY ?If so? then how?gimme one example.
    THanks

    • Ryan Sep 28, 2011 @ 20:09

      You can enter databases separated with a space here that you don’t want to backup.

      Example:
      IGGY=”test test2 test3”

  • sadique Jan 10, 2011 @ 10:19

    Hi Vivek, thanks for such a good script.
    in this script you are creating one file for one db. Can I create one file for each table of a db.
    File name would be like dbname-filename-date … etc….

    Thanks in advance..

  • Eduardo Nov 30, 2010 @ 1:11

    Is possible send mysql database to e-mail with daily cron?

    thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.