参考http://www.rsnapshot.org/howto/1.2/rsnapshot-HOWTO.en.html 4.3.9。备份脚本
如果创建新数据库,我需要动态备份所有 mysql 数据库。有没有一种理想的方法可以用最少的代码在 bash 中做到这一点?
我需要登录mysql并获取所有数据库吗?
似乎您想要一个 bash 脚本在 MySQL 中创建的动态数据库上运行备份。您可以在根目录的 my.cnf 中或在 # [Define Variables] 下的 bash 脚本中添加 mysql root 用户帐户信息。
您将需要使用 chmod bash 脚本
$sudo chmod +x backupmysql.sh
这将允许您使用以下命令运行脚本。
$sudo ./backupmysql.sh
您可以随意命名脚本。在本例中,我将其命名为 backupmysql.sh。
这是 bash 脚本:
#!/bin/bash
# [ Define Variables ]
HOST=`hostname -s`
syslogtag=MySQL-Backup
DEST=/var/dba/backup/
DBS="$(mysql -u root -Bse 'show databases' | egrep -v '^Database$|hold$' | grep -v 'performance_schema\|information_schema')"
DATE=$(date +'%F')
#[ Individually dump all databases with date stamps ]
for db in ${DBS[@]};
do
GZ_FILENAME=$HOST-$db-$DATE.sql.gz
mysqldump -u root --quote-names --opt --single-transaction --quick $db > $DEST$HOST-$db-$DATE.sql
ERR=$?
if [ $ERR != 0 ]; then
NOTIFY_MESSAGE="Error: $ERR, while backing up database: $db"
logger -i -t ${syslogtag} "MySQL Database Backup FAILED; Database: $db"
else
NOTIFY_MESSAGE="Successfully backed up database: $db "
logger -i -t ${syslogtag} "MySQL Database Backup Successful; Database: $db"
fi
echo $NOTIFY_MESSAGE
done
如果你有大文件需要备份,你可以替换 bash 脚本中 mysqldump 的语句来使用 gzip 压缩文件。
mysqldump -u root --quote-names --opt --single-transaction --quick $db | gzip -cf > $DEST$HOST-$db-$DATE.sql.gz
您可以使用 gunzip 解压缩文件。
该mysqldump
命令具有一次--all-databases
备份每个数据库的选项。
唯一的缺点是你必须一起恢复它们,你没有挑选和选择的奢侈。
请记住,数据库通常在您的 MySQL 数据目录中有一个关联的目录,因此您始终可以遍历这些目录以找出存在哪些数据库。
对于 mysql 本地系统进程,我使用:
#!/bin/bash
DEFAULTSFILE=/etc/my.cnf.d/.backups.cnf
BACKUPDIR=/root/db_backups
SAVEIFS=$IFS
# get list of dbs with field name (Database)
DBLIST=$(mysql -e "show databases" | cut -d ' ' -f 2 | grep -v Database)
IFS=$'\n'
DBLIST=($DBLIST)
# create backups directory if it doesn't exist
[ -d $BACKUPDIR ] || mkdir -p $BACKUPDIR
# make a single dump file for all databases in case entire server needs to be restored:
echo "Dumping all databases..."
mysqldump --defaults-file=$DEFAULTSFILE --all-databases > $BACKUP_DIR/$(date +%Y%m%d).all.sql
echo "Done dumping all databases."
# backup each database into it's own file to facilitate discrete restoration:
for (( i=0; i<${#DBLIST[@]}; i++ ))
do
echo "starting dump of ${DBLIST[$i]}..."
mysqldump --defaults-file=$DEFAULTSFILE ${DBLIST[$i]} --skip-lock-tables > $BACKUPDIR/$(date +%Y%m%d).${DBLIST[$i]}.sql
echo "done dumping ${DBLIST[$i]}."
done
IFS=$SAVEIFS
# gzip the sql files in-place to save space
gzip -f $BACKUPDIR/*.sql
# delete sql files older than 7 days
find $BACKUPDIR -type f -mtime +7 -name '*.gz' -execdir rm -- '{}' \;
对于 docker,情况略有不同:
#!/bin/bash
DEFAULTSFILE=/etc/my.cnf.d/.backups.cnf
BACKUPDIR=/root/db_backups
SAVEIFS=$IFS
# get list of dbs with field name (Database) and information_schema excluded. information_schema hangs during dumps
DBLIST=$(docker exec mysql mysql --defaults-file=/etc/my.cnf.d/.backups.cnf -e "show databases" | cut -d ' ' -f 2 | grep -v Database)
IFS=$'\n'
DBLIST=($DBLIST)
# create backups directory if it doesn't exist
[ -d $BACKUPDIR ] || mkdir -p $BACKUPDIR
# backup each database into it's own file to facilitate discrete restoration:
for (( i=0; i<${#DBLIST[@]}; i++ ))
do
echo "starting dump of ${DBLIST[$i]}..."
docker exec mysql mysqldump --defaults-file=$DEFAULTSFILE ${DBLIST[$i]} --skip-lock-tables > $BACKUPDIR/$(date +%Y%m%d).${DBLIST[$i]}.sql
echo "done dumping ${DBLIST[$i]}."
done
IFS=$SAVEIFS
# gzip the sql files in-place to save space
gzip -f $BACKUPDIR/*.sql
# delete sql files older than 7 days
find $BACKUPDIR -type f -mtime +7 -name '*.gz' -execdir rm -- '{}' \;
我无法让 --all-databases 为 docker 工作。反正我不喜欢多合一备份...
我把这些直接扔到root的crontab中,它们工作正常......