由于线上mysql数据量很大,天天进行全备份数据既浪费时间又占用资源,所以打算采用全量备份和增量备份结合的方式进行备份
采用每周日全量备份、周一到周六增量备份的方式
背景是从一台mysql上进行备份,然后还原到另一台mysql上
实际上是从线上数据库备份,再还原到线下数据库上
先从线下找两台机器测试
用191机器模拟线上mysql
在122机器上新装了一个mysql用来还原
全备份
先说一下全备份,在191上
#!/bin/bash
cd /opt/bak/local/mysql/test
date_str=`date +%Y%m%d`
SQL_pwd=‘xxxx‘
mysql -uroot -p$SQL_pwd -e "FLUSH TABLES WITH READ LOCK;" //锁表
/usr/bin/mysqladmin -uroot -p$SQL_pwd flush-logs //第一次刷新,产生一个新的二进制文件B,记录了备份期间数据的变化,二进制文件A记录了全备份前的操作,后面增量还原时不需要文件A
for i in `cat /opt/bak/bin/show_databases.txt` //循环show_databases中的库名,循环备份
do
/usr/bin/mysqldump -u root --password=$SQL_pwd -R -E -e --single-transaction --master-data=2 $i > /opt/bak/local/mysql/test/$i-$date_str.sql //对数据库循环备份到sql文件,以“库名-日期”命名
sleep 30
done
mysql -uroot -p$SQL_pwd -e "UNLOCK TABLES;"
/usr/bin/mysqladmin -uroot -p$SQL_pwd flush-logs //第二次刷新,产生一个二进制文件C
cd /opt/bak/local/mysql/test
zip -rm mysqldb-$date_str.zip *.sql //将sql文件打成zip包
rm -rf `find ./ -mtime +6`
exit 1
全备份流程
全备份还原
122上进行还原
# !/bin/bash
source /etc/profile
DATE=`date ‘+%Y%m%d‘`
scp -p 192.168.1.191:/opt/bak/local/mysql/test/* /opt/log/all_bak/ //从191拷贝全备份zip文件,scp -p不改变文件最后修改时间
cd /opt/log/all_bak/
unzip mysqldb-$DATE.zip -d mysqldb-$DATE //解压到文件夹
path="/opt/log/all_bak/mysqldb-$DATE/*"
for file in $path //循环每个sql文件
do
database=`basename $file | awk -F ‘-‘ ‘{print$1}‘` //从文件名中截取数据库名
for i in $(cat /opt/log/binlog_bak/bin/show_databases.txt) //循环show_databases中的库名
do
if [ "$i" = "$database" ] //如果两个库名相同,则还原这个数据库
then
echo "还原$i=======" >> result.log
mysql -uroot -p666666 $i < $file
echo "还原$i完成" >> result.log
fi
done
done
cd /opt/log/all_bak/
rm -rf `find ./ -mtime +7` //删除7天前的备份
全备份还原流程
设置定时任务
191 crontab -e
#每周日凌晨3点全备份数据库
0 3 * * 0 /bin/sh /opt/bak/bin/testallbak.sh
121 crontab -e
#周日还原全备份
0 5 * * 0 /bin/sh /opt/log/binlog_bak/bin/return_all.sh
增量备份
要想实现增量备份,就要开启binlog功能,在my.cnf文件中找到下面的内容,进行修改
#二进制文件日志
log_bin = /var/log/mysql/mysql-bin.log //日志存放路径
binlog_format = row //日志格式
expire_logs_days = 10 //日志最多保留10天
max_binlog_size = 512M //日志文件最大512M,超过则日志发生滚动
191每天23:59分刷新,将二进制文件以天为单位分开保存,按天来还原
#!/bin/sh
USER=root
PASSWORD="xxxxx"
#只刷新日志即可
/usr/bin/mysqladmin -u$USER -p$PASSWORD flush-logs
增量备份流程
增量还原
122上每天00:00还原前一天的二进制文件
# !/bin/bash
source /etc/profile
DATE=`date ‘+%Y/%m/%d‘ --date="-1 day"`
DATE_YESTODAY=`date ‘+%Y-%m-%d‘ --date="-1 day"`
DATE1=`date "+%Y-%m-%d %H:%M:%S"`
mkdir /opt/log/binlog_bak/mysql_binlog/$DATE //创建前一天的文件夹
cd /opt/log/binlog_bak/mysql_binlog/$DATE
scp -p 192.168.1.191:/var/log/mysql/mysql-bin.* /opt/log/binlog_bak/mysql_binlog/$DATE/ //从191上拷贝所有的二进制文件
week=`date +%w` //得到当天星期几
path="/opt/log/binlog_bak/mysql_binlog/$DATE/*"
#循环所有二进制文件,根据文件最后修改时间判断,留下日期为前一天的
for file in $path
do
modifytime=`stat $file | grep "Modify" | awk -F ‘ ‘ ‘{print $2}‘`
if [ "$modifytime" != "$DATE_YESTODAY" ]
then
rm -rf $file
fi
done
#如果周一则去掉周日凌晨三点第一次刷新产生的日志
if [ $week -eq 1 ]
then
ls -l | grep "mysql-bin" | grep -v index | awk -F ‘ ‘ ‘{print $9}‘ > a.txt //将要循环的二进制文件名输出到a.txt
line=`cat a.txt | wc -l`
n=$(expr $line - 1) //去掉周日凌晨三点第一次刷新产生的日志,也就是上面提到的文件A
tail -$n a.txt > b.txt //剩下的二进制文件名输出到b.txt
#循环数据库
for i in $(cat /opt/log/binlog_bak/bin/show_databases.txt)
do
#循环二进制文件
for line in $(cat /opt/log/binlog_bak/mysql_binlog/$DATE/b.txt)
do
mysqlbinlog /opt/log/binlog_bak/mysql_binlog/$DATE/$line -d $i | mysql -uroot -p666666 //还原数据库
done
done
#不是周日的话正常拷贝还原
else
ls -l | grep "mysql-bin" | grep -v index | awk -F ‘ ‘ ‘{print $9}‘ > a.txt //将要循环的二进制文件名输出到a.txt
#循环数据库
for i in $(cat /opt/log/binlog_bak/bin/show_databases.txt)
do
#循环二进制文件
for line in $(cat /opt/log/binlog_bak/mysql_binlog/$DATE/a.txt)
do
mysqlbinlog /opt/log/binlog_bak/mysql_binlog/$DATE/$line -d $i | mysql -uroot -p666666 //还原数据库
done
done
fi
设置定时任务
191 crontab -e
#周一到周六刷新binlog日志
59 23 * * * /bin/sh /opt/bak/bin/increment.sh
122 crontab -e
#周一到周六还原增量备份
0 0 * * 1-6 /bin/sh /opt/log/binlog_bak/bin/return_increment.sh
原文地址:http://blog.51cto.com/xinsir/2177092
时间: 2024-10-10 20:08:20