全量脚本
#!/bin/bash
# 全备方式,一般在从机上执行,适用于小中型mysql数据库
source /etc/profile # 加载系统环境变量
source ~/.bash_profile # 加载用户环境变量
# 定义全局变量
user="root"
password="12345678"
host="localhost"
port="3306"
db=("zabbix") # 多个数据库备份空格隔开
local="--single-transaction"
mysql_path="/usr/share/mysql"
backup_path="/usr/backup/mysqlbak"
date=$(date +%Y%m%d_%H:%M:%S)
day=30
backup_log="/usr/backup/mysqlbak/backup.log"
# 判断是否存在目录,不存在则创建目录
if [ ! -e $backup_path ];then
mkdir -p $backup_path
fi
# 删除30天以前备份
find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1
echo "start backup: ${db[*]}"
# 备份数据库后压缩
backup_sql(){
dbname=$1
backup_name="${dbname}_${date}.sql"
mysqldump -h $host -P $port -u $user -p$password $lock --default-character-set=utf8 --flush-logs -R $dbname > $backup_path/$backup_name
if [[ $? == 0 ]];then
cd $backup_path
# tar --force-local参数压缩带有冒号的压缩包
tar czvf $backup_name.tar.gz $backup_name --force-local
size=$(du $backup_name.tar.gz -sh | awk '{print $1}')
rm -rf $backup_name
echo "$date backup $dbname($size) successed"
else
cd $backup_path
rm -rf $backup_name
echo "$date backup $dbname failed"
fi
}
# 多个库循环备份
length=${#db[@]} #获取db数组的长度
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "backup done,please check the $backup_log"
du $backup_path/*$date* -sh | awk '{print "filename:" $2 ",size:" $1}'
增量脚本
#!/bin/bash
# 增量备份方式,在从机上执行,适用于中大型mysql数据库
# 对于我这种数据库操作频率比较少的来说,并不会产生特别大的bin-log日志,所以如果要针对某个节点或者某个操作来进行恢复时并不需要花费太多的时间来查找,因此不需要在某个时间点对日志进行分割,所以增量备份对我来说意义不是很大
# 同时数据库配置文件必须开启binlog二进制文件
# 且日志模式必须为ROW或者mixed
source /etc/profile # 加载系统环境变量
source ~/.bash_profile # 加载用户环境变量
# 定义全局变量
backup_path="/usr/backup/mysqlbak_binlog"
mysqlbin_path="/data/mysql"
backup_log="/usr/backup/mysqlbak_binlog/backup.log"
mysqlbinfile="/data/mysql/mysql-bin.index"
date=$(date +%Y%m%d_%H:%M:%S)
day=30
# 刷新新的mysql-bin.0000*文件
mysqladmin -uroot -p12345678 flush-logs
statistics=`cat $mysqlbinfile|wc -l`
num=0
# 判断是否存在目录,不存在则创建目录
if [ ! -e $backup_path ];then
mkdir -p $backup_path
fi
# 删除30天以前备份
find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1
# for循环对比是否存在或是否为最新的文件
echo "start backup..."
for file in `cat $mysqlbinfile`
do
# basename用于截取mysql-bin.0000*文件名,去掉./mysql-bin.0000*前面的./
dbname=`basename $file`
backup_name=`basename $file`_$date
num=`expr $num + 1`
cd $backup_path
# 判断是否刷新二进制文件
if [ $num != $statistics ];then
dest=$backup_path/$dbname*
# 判断文件是否存在,不存在则备份
if [ ! -e $dest ];then
cp $mysqlbin_path/$dbname $backup_path/
# --force-local,压缩文件中带有冒号需要加上--force-local参数
tar czvf $backup_name.tar.gz $dbname --force-local
size=$(du $dbname.tar.gz -sh | awk '{print $1}')
rm -rf $dbname
echo "$dbname backup $dbname($size) successed" >> $backup_log
du $backup_path/* -sh | grep mysql-bin | awk '{print "filename:" $2 ",size:" $1}'
else
echo "$dbname backup $dbname has exited" >> $backup_log
continue
fi
fi
done
echo "backup done,please check the $backup_log"
du $backup_path/* -sh | grep mysql-bin | awk '{print "filename:" $2 ",size:" $1}'
写入排程
每个周日凌晨一点执行数据库全量备份脚本
00 01 * * 0 /opt/scripts/backup-mysql-full.sh > /dev/null 2>&1
周一到周六凌晨一点执行数据库增量备份脚本
00 01 * * 1-6 /opt/scripts/backup-mysql-add.sh > /dev/null 2>&1
相关参数介绍
--single-transaction数据一致性
--lock-all-tables为所有表加读锁(于--single-transaction互斥)
--routinge存储过程与函数、--all-databases备份所有库
--triggers触发器、--events记录事件
--master-data=2在备份文件中记录当前二进制日志的位置,并且为注释的,1是不注释掉在主从复制中才有意义
--flush-logs日志滚动一次
恢复方法
全量恢复方法
create database dbname;
mysql -uroot -p12345678 dbname < /mysqlbak/dbname.sql
增量恢复方法
mysqlbinlog --no-defaults /mysql_bak/mysql-bin.000002 //查看该二进制日志中的内容
mysqlbinlog --no-defaults /mysql_bak/mysql-bin.000002 | mysql -uroot -p12345678 //对该日志中的所有操作进行恢复
--stop-datetime='2019-10-14 14:22:53' //只恢复到该日志中这个时间点之前的操作
--start-datetime='2019-10-14 14:22:53' //只恢复该日志中这个时间点开始到日志结束的所有操作
--stop-position='468' //只恢复该日志中这个位置之前的操作
--start-position='538' //只恢复该日志中这个位置开始到日志结束的所有操作