It's a really good idea to use a least-privilege approach to most system administration tasks, and especially automated ones. This post describes using a "read only" MySQL user to handle backing up MySQL databases.
We use mysqldump to backup our databases on a regular basis, using scripts like this one:
#!/bin/sh
DIR=/backup/mysql/
DATESTAMP=$(date +%Y%m%d)
DB_USER=backup
DB_PASS='readonly'
# remove backups older than $DAYS_KEEP
DAYS_KEEP=30
find ${DIR}* -mtime +$DAYS_KEEP -exec rm -f {} \; 2> /dev/null
# create backups securely
umask 006
# list MySQL databases and dump each
DB_LIST=`mysql -u $DB_USER -p"$DB_PASS" -e'show databases;'`
DB_LIST=${DB_LIST##Database}
for DB in $DB_LIST;
do
FILENAME=${DIR}${DB}-${DATESTAMP}.sql.gz
mysqldump -u $DB_USER -p"$DB_PASS" --opt --flush-logs $DB | gzip > $FILENAME
done
You'll note that this script uses the user 'backup' to do the dumping. This is because our production servers grant potentially dangerous permissions (such as DROP TABLE) on a per-database basis. In order to run an automated backup, however, we need a single user that has just enough permissions to read from all the databases, but not enough to pose a risk to them.
The MySQL permissions required for the script above are SHOW DATABASES, SELECT, LOCK TABLES, and RELOAD. Grant them by entering the mysql command line and issuing these commands (choosing a better password than 'readonly' of course)
GRANT SHOW DATABASES, SELECT, LOCK TABLES, RELOAD ON *.* to backup@localhost IDENTIFIED BY 'readonly'; FLUSH PRIVILEGES;
You can now back up all your databases by way of a single MySQL account that has just enough access to do the job, and not enough to cause significant harm. Which is what least-privilege access is all about.



Comments
Good script, --all-databases flag
Great script, especially the part about least-privilege access.
Thought might also like the mysqldump --all-databases flag though. Then you don't need to list through each one from mysql and makes your script even simpler.
More here:
http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html
--all-databases can complicate things
--all-databases is good insurance against catastrophic server failure, but inconvenient for the far more likely case of user or application errors. In those cases ("Ooops, I deleted all my blog entries by accident!"), you want to be able to restore just the one database.
With the --all-databases option you are forced to reload all of them or do something complicated like restore them to another server from where you can dump and restore the one you want.
Tataly agree, I support !
Tataly agree, I support !
--all-databases split
You can pipe the mysqldump with --all-databases to simple awk script which will write out separate files for each DB, I use this method because we have to do all the DBs at once due to our replication setup
mysqldump -F -A | $awk -v DUMPPATH=${DUMPPATH} '
BEGIN {
# Keep the first little bit of information in a file
# since this holds replication information
outputFile = DUMPPATH "/master_data.sql";
}
/^-- Current Database: / {
# This header marks the start of the next database.
# The fourth token contains `databasename` (with back-quotes)
database = gensub("`","","G",$4);
outputFile = DUMPPATH "/" database ".sql";
}
{
print $0 > outputFile;
}
'
You'll want to include the
You'll want to include the "show view" priv_type in the grant line for the backup user to be sure to get any/all views.
DB_LIST=`mysql -u $DB_USER
DB_LIST=`mysql -u $DB_USER -p"$DB_PASS" -e'show databases;'`
DB_LIST=${DB_LIST##Database}
instead this you can add commandline options -Bs
DB_LIST=`mysql -u $DB_USER -p"$DB_PASS" -Bs -e'show databases;'`
You, sir, are a gentleman.
Thank you for sparing me all the time it would take to track down these options.
php
how is it done with php
MySQL Backup script
beautiful, simple and fast. Thanks for posting!
Add new comment