mysql增量备份与恢复

  • 使用mysqldump进行完全备份,会有数据重复,而且数据较大时间过长。
  • 增量备份可根据需求恢复

mysql二进制对备份的意义

  • 二进制日志文件保存了数据库操作(sql语句)
  • 当日志文件达到max——binlog——size所设置的大小或者接收到flush-log命令重新创建新的日志文件
vim /etc/my.cnf
max_binlog_size = 1024000  #最大为1M
log-bin=myslq-bin  #打开日志
#需重启

mysql增量备份

  • 人为sql语句损失,数据库故障丢失
  • mysqlbinlog [--no-defaults] 增量备份文件 | mysql -u -p #二进制文件完全恢复
  • mysqlbinlog [--no-defaults] --stop-datatime='年-月-日 小时:分钟:秒' 二进制文件 | mysql -u -p #更具实践需求恢复二进制文件
  • mysqlbinlog [--no-defaults] --start-datatime='年-月-日 小时:分钟:秒' 二进制文件 | mysql -u -p #从某时间点到时间结尾恢复
  • mysqlbinlog [--no-defaults] --start-datatime='年-月-日 小时:分钟:秒' --stop-datatime='年-月-日 小时:分钟:秒' 二进制文件 | mysql -u -p #从某时间到某时间点恢复
  • mysqlbinlog --stop-position='操作 id' 二进制日志 | mysql -u -p #位置
    mysqlbinlog --start-position='操作 id' 二进制日志 | mysql -u -p

制定企业备份策略的思路

  • 在半夜三点合适的时间根据公司数据大小来备份
  • 数据大的话一周完全备份一次,小的话一天一次

实验

mysql -uroot -p
create databases client;
use client;
#首先保证能实用汉语:my.cnf中设置character_set_server=utf8
create table user_info(身份证 char(20)not unll,姓名 cahr(20)not unll,性别 cahr(2),用户id号 cahr(10)not null,资费 int(10));
insert into user_info values('000000006','张三','男','018','15');
insert into user_info values('000000007','李四','男','029','16');
insert into user_info values('000000008','whml','男','020','17');
select * from user_info;

#第一次完全备份
mkdir /mysql_bak  #创建目录
mysqldump -uroot -p123123 client user_info > /mysql_bak/client_user_info-$(date +%F).sql  #将库保存在目录
mysqldump -uroot -p123123 --databases client > /mysql_bak/client-$(date +%F).sql  #将库中的表保存在目录下
[root@localhost ~]# ls /mysql_bak/
client-2021-10-13.sql  client_user_info-2021-10-13.sql

#进行一次日志回滚(生成新的日志文件)
mysqladmin -uroot -p123123 flush-logs

#继续录入新的数据
insert into user_info values('000000009','wml','男','2007','26');
insert into user_info values('000000010','mhm','女','1909','13');

#进行增量备份
cp /var/lib/mysql/mysql-bin.000002 /mysql_bak/  #保存日志文件

#模拟删除
mysql -uroot -p123123 -e 'drop table client.use_info;'
mysql -uroot -p123123 -e 'select * from client.user_info'

#恢复完全备份
mysql -uroot -p123123 client < /mysql_bak/client-2021-10-13.sql
mysql -uroot -p123123 -e 'select * from client.user_info'  #此时里面就有我们前面的三个数据

#恢复增量备份
mysqlbinlog --no-defaults /root/mysql_bak/mysql-bin.000002  | mysql -uroot -p123123  #此时里面就有我们一直到最后的数据

#基于时间点的增量备份
mysql -uroot -p123123 client < /mysql_bak/client-2021-10-13.sql  #先进行完全恢复
mysqlbinlog --no-defaults --stop-datatime='2021-10-13 15:10:13' /mysql_bak/mysqk-bin.000002 | grep -uroot -p123123  #此时一直恢复到此时间的数据

#跳过某个时间的sql语句
mysql -uroot -p123123 client < /mysql_bak/client-2021-10-13.sql  #先进行完全恢复
mysqlbinlog --no-defaults --start-datatime='2021-10-13 15:10:13' /mysql_bak/mysqk-bin.000002 | grep -uroot -p123123  

#基于位置的恢复
mysql -uroot -p123123 client < /mysql_bak/client-2021-10-13.sql  #先进行完全恢复
mysqlbinlog --no-defaults --stop-position='774' /mysql_bak/mysql-bin.000002 | mysql -uroot -p123123  #一直恢复到此位置

#使用脚本完全备份
chmod +x /opt/mysql_bak_wanbei.sh  #给脚本增加执行权限
#给其周期计划执行脚本

定期重新更新日志脚本

完全备份脚本
#!/bin/bash
# MySQL数据库完全备份脚本
# 设置登录变量
MY_USER="root"
MY_PASS="123123"
MY_HOST="localhost"
MY_CONN="-u$MY_USER -p$MY_PASS -h$MY_HOST"
# 设置备份的数据库(或表)
MY_DB="client"
# 定义备份路径、工具、时间、文件名
BF_DIR="/mysql_bak/wanbei"
BF_CMD="/usr/bin/mysqldump"
BF_TIME=$(date +%Y%m%d-%H%M)
NAME="$MY_DB-$BF_TIME"
# 备份为.sql脚本,然后打包压缩(打包后删除原文件)
[ -d $BF_DIR ] || mkdir -p $BF_DIR
cd $BF_DIR
$BF_CMD $MY_CONN --databases $MY_DB > $NAME.sql
/bin/tar zcf $NAME.tar.gz $NAME.sql --remove &>/dev/null
增量备份脚本
#!/bin/bash
# MySQL数据库增量备份脚本
# 设置登录变量
MY_USER="root"
MY_PASS="123123"
MY_HOST="localhost"
MY_CONN="-u$MY_USER -p$MY_PASS -h$MY_HOST"
# 定义备份路径、工具、二进制日志前缀、二进制日志存放路径
BF_TIME="$(date +%Y%m%d)"
BF_DIR="/mysql_bak/zengbei/$BF_TIME"
CMD="/usr/bin/mysqladmin"
QZ="mysql-bin"
LOG_DIR="/var/lib/mysql"
# 拷贝二进制日志
[ -d $BF_DIR ] || mkdir -p $BF_DIR
$CMD $MY_CONN flush-logs
/bin/cp -p $(ls $LOG_DIR/$QZ.* |awk -v RS="" '{print $(NF-2)}') $BF_DIR
智能恢复备份脚本(客户机上)
#!/bin/bash
# 恢复MySQL数据库数据脚本
# 设置变量
MY_USER="admin"
MY_PASS="123123"
MY_HOST="192.168.200.100"  #数据库
BF_DIR="backup"
mkdir .aaa
ls $BF_DIR |column -t > .aaa/db_list
awk -F'-' '{print $2}' .aaa/db_list > .aaa/dt.txt
read -p "请指定要恢复数据库的日期(YYYYMMDD):" dt
if [ $dt -ge 20211001 ] && [ $dt -le 20211031 ];then
	grep "$dt" .aaa/dt.txt &>/dev/null
	if [ $? -ne 0 ];then
		echo "很抱歉,您恢复数据库的备份日期不再备份日期范围内"
	else
		echo "搜索到的可恢复数据库如下:"
		awk -F'-' /$dt/'{print NR,$1}' .aaa/db_list
		read -p "请选择您要恢复数据库的编号: " nb
		nm=$(awk -F'-' /$dt/'{print NR,$1}' .aaa/db_list |grep "$nb" |awk '{print $2}')
		echo "现在开始恢复数据库:$nm到$dt"
		cd $BF_DIR
		onm=$(ls |grep "$nm-$dt")
		mkdir .bbb
		tar xf $onm -C .bbb
		mysql -u$MY_USER -p$MY_PASS -h$MY_HOST $nm < .bbb/*
		echo "$nm已经恢复到$dt"
                rm -rf .bbb
		cd - &>/dev/null
		rm -rf .aaa
        fi
else
echo "很抱歉,您恢复数据库的备份日期不再备份日期范围内"
fi