Shell Script To Backup MySql Database Server

by Vivek Gite on April 9, 2008 · 45 comments · [ vivek@nixcraft.com ]

#!/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):
# http://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

4000+ howtos and counting! If you enjoyed this article, join 45000+ others and get free email updates!

Thiago July 3, 2008

It`s very good

thanks

Reply

Stephen Reese August 23, 2008

Great script! I really like the addition of the which command.

Reply

ron May 15, 2010

this looks super cool, however can anyone explain me the meaning of

MYSQL=”$(which mysql)”
MYSQLDUMP=”$(which mysqldump)”
CHOWN=”$(which chown)”
CHMOD=”$(which chmod)”
GZIP=”$(which gzip)”

what does the which command do ? do we have to write tht

Reply

marties June 17, 2010

it gives the full path of the executable

which mysql
/usr/bin/mysql

Reply

ajax December 7, 2008

all, you are done great server works,

thx

Reply

DVD March 20, 2009

Nice script.

Reply

Gilnei Moraes April 22, 2009

Just my one cent:
run rsync daemon using the backup directory just to be sure you are playing safe. Is worthless to backup MySQL not having a copy in remote location in case of a server crash.

Reply

fRank May 15, 2009
#!/bin/bash
NOW=`date +"%Y-%m"`;
BACKUPDIR="location/of/your/backup/dir/$NOW";
### Server Setup ###
#* MySQL login user name *#
MUSER="user";
#* MySQL login PASSWORD name *#
MPASS="pass";
#* MySQL login HOST name *#
MHOST="your-mysql-ip";
MPORT="your-mysql-port";
# DO NOT BACKUP these databases
IGNOREDB="
information_schema
mysql
test
"
#* MySQL binaries *#
MYSQL=`which mysql`;
MYSQLDUMP=`which mysqldump`;
GZIP=`which gzip`;
# assuming that /nas is mounted via /etc/fstab
if [ ! -d $BACKUPDIR ]; then
  mkdir -p $BACKUPDIR
else
 :
fi
# get all database listing
DBS="$(mysql -u $MUSER -p$MPASS -h $MHOST -P $MPORT -Bse 'show databases')"
# SET DATE AND TIME FOR THE FILE
NOW=`date +"d%dh%Hm%Ms%S"`; # day-hour-minute-sec format
# start to dump database one by one
for db in $DBS
do
        DUMP="yes";
        if [ "$IGNOREDB" != "" ]; then
                for i in $IGNOREDB # Store all value of $IGNOREDB ON i
                do
                        if [ "$db" == "$i" ]; then # If result of $DBS(db) is equal to $IGNOREDB(i) then
                                DUMP="NO";         # SET value of DUMP to "no"
                                #echo "$i database is being ignored!";
                        fi
                done
        fi
        if [ "$DUMP" == "yes" ]; then # If value of DUMP is "yes" then backup database
                FILE="$BACKUPDIR/$NOW-$db.gz";
                echo "BACKING UP $db";
                $MYSQLDUMP --add-drop-database --opt --lock-all-tables -u $MUSER -p$MPASS -h $MHOST -P $MPORT $db | gzip > $FILE
        fi
done

Reply

Brian Nettles July 16, 2009

Incredible!!!!!!!

I have wasted hours trying to do this in perl. One small copy and paste from your site and all of the mysql databases are now being automatically backed up. Thank you so much. You are worth your weight in gold.

Reply

No Brains!! September 9, 2009

Forgive the ignorance but would you have to stop the mySQL service before running this script?

Reply

Vivek Gite September 11, 2009
sukhbir September 29, 2009

this script is very good.

Can anybody having a script to extract database from MYSQLDUMP.

Regards,

Reply

Hunner October 21, 2009

`mysql -u $user -p < backup.dump` will take a dump file and put it back into the DB.

Reply

Deven J February 4, 2010

Undoubtedly, very simple and useful.

Reply

Zeb Evans February 27, 2010

Just a note that will hopefully help others. I’m just starting to learn shell scripting all my other ones have been using phpcli so take this with a grain of salt. I was getting a bunch of these errors.

==: unexpected operator

I had to change these lines and use the single = comparison instead of ==

[ "$db" = "$i" ] && skipdb=1 || :
done
fi

if [ "$skipdb" = "-1" ] ; then

Reply

Trev April 13, 2010

I would think that changing the operator to = would be assigning the “$i” to “$db”

From my knowledge of bash scripting, or the use of bourne shell commands, it is necessary for the use of == for comparisons as well as the spaces around the subscript operators.

Did changing those to = instead of == allow it to run properly?

Reply

Avin March 30, 2010

Nice Post.. I have use this post as you say and It work exactly as I want. but Is it possible to copy backup directory to other server for security If this server is totally crash? Only daily folder has to copy to other server.

Reply

shreyas April 27, 2010

if i need to backup each database in seperate file and want to know whether the databse dump was succesful or not.

could anyone please help with that

Reply

Terry April 29, 2010

Thank you for the handy script.

At least on our Fedora 10 installation, the gzip binary looks for an env var GZIP and uses it as a default argument list if it’s set.

So this
$GZIP -9
is equivalent to this (for our binaries)
/bin/gzip /bin/gzip -9

Since I wasn’t running the script as root, this manifested itself as a somewhat misleading permissions error that took a while to track down since I mistook the /bin/gzip.gz as a reference to a helper binary (like fsck.ext2, for instance):
gzip: /bin/gzip.gz: Permission denied

Could I request that something besides GZIP be used (e.g. GZIPBIN, GZ)?

Thanks!

Reply

Paul d'Aoust July 8, 2010

Thanks so much for taking the time to put up this script; you’re a real life-saver. I realised today (after a big scare with fsck) that I have no facility for backing up my databases on my development machine! I shall be adding this forthwith.

Reply

Gaurav Talwar July 13, 2010

Excellent script .. Thanks mate

Reply

Chris August 23, 2010

For some reason when I tried this it seemed to work — it created the .gz files in my backup directory. But when I tried an experiment of dropping one of the databases and then using the backed-up .gz file to restore from (via cpanel utility), it created an empty database with no tables in it. Not sure why :-(

Reply

Josh September 20, 2010

I have this exact same problem. Does anyone have any ideas about this?

Reply

Vivek Gite September 21, 2010

If your file name is db2.11_02_35am.gz, then use the following commands to reinstall the database:

gunzip db2.11_02_35am.gz
ls -l db2*
mysql -u root -p -e 'create database db2;'
mysql -u root -p db2 < db2.11_02_35am

Reply

tim September 16, 2010

This script is a lifesaver, thank you.

I do have a quick question, for the IGGY, do you put the databases you do not want backed up just separated by commas?

Reply

Vivek Gite September 19, 2010

No, just separated by white space:

IGGY="test db2 db4"

Reply

Martin W November 9, 2010

F##ing Great! Thanks a lot for the good work!

Reply

Rodrigo November 29, 2010

Does it output some information if something goes wrong? i´m trying to write to a logfile, just wondering it outputs success or failure results? Sorry, i just lack the skills to tell if it does so.

TIA,
Rodrigo

Reply

Eduardo November 30, 2010

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

thanks

Reply

Huw June 15, 2011

mutt -a /home/website/sql_dump.zip -s “Sql Backup” youremail@email.com

Reply

Leave a Comment

You can use these HTML tags and attributes for UNIX commands or shell scripts: <strong> <em> <ol> <li> <u> <ul> <blockquote> <pre> <a href="" title="">
What is 9 + 10 ?
Please leave these two fields as-is:
Are you a human being? Solve the simple math so we know that you are a human and not a script.



Tagged as: , , , , , , , , , , , , , , ,