要求:模仿腾讯云数据库,选择数据库,或者数据库下的表,然后点击回档时间,进行回档操作;
实现:实现思路通过 冷备数据+热备数据 实现数据库回档到固定的时间点,前提要求,数据库固定时间都会进行数据备份;
冷备数据:冷备方式有多种,物理冷备,逻辑冷备;
物理冷备:就是把数据库整个文件拷贝下来,需要的时候直接粘到我们的数据库目录下(只适用于MYISAM数据引擎,并且数据库大版本不同,数据库下目录结构不同),也可以通过第三方软件进行备份;
逻辑备份:使用mysq自带的命令mysqldump命令,进行备份,会导出sql文件,可以跨版本,灵活,如下,将test数据库,导出,back.sql,back前面的是当前时间,
-F表示备份后刷新binlog日志(这里刷新的原因是,冷备数据有了,恢复时就不需要之前的binlog了,重置新的binlog日志),--source-data,表示在备份的sql文件中要记录备份后的binlog日志版本,还有结束位点(很有必要);该命令需要在操作系统中执行,不能进mysql中;
mysqldump -uroot -pzzyy55555 -B -F -R -x --source-data test > $(date +%F%T)back.sql;
热备数据:mysql的binlog日志,该日志mysql8自动开启,show variables like '%log_bin%',mysql数据库中使用该命令可以查看binlog是否开启
binlog日志是以二进制格式存放的,必须使用mysqldump命令查看才能看见,mysql-bin.index,前缀名可能不一样,index结尾的文件,会实时更新,里面记录的是所有二进制文件的名字,并且当二进制文件更新时,它就会更新,默认一个G,超过也会自动更新。
SHOW BINARY LOGS; mysql中使用该命令,可以查看所有的binlog日志,file_size,表示最后一个事件的位点;
SHOW MASTER STATUS;该命令可以查看出当面mysql使用的binlog日志,因为每当数据库重启一次,binlog日志都会自增一个;或者使用flush logs,也可以手动刷新日志,我们恢复备份时手动执行一下该命令,不然恢复记录也会记录进入binlog日志中,不刷新的话,数据库日志会十分混乱;
真正实现:上面介绍了我们需要使用的冷备,热备数据,接下来是具体的恢复方案,参考其它播客,选择的方式如下图,就是需要一个主机用来做备份主机,将数据回档到目标时间后,拿到我们需要的目标库表,进行数据倒灌,最终实现数据回档;
①目标数据库需要定时执行备份,这是备份所有数据库,mysqldump -uroot -pzzyy55555 --all –databases -F -R -x --source-data > $(date +%F%T)back.sql,这个是备份指定数据库:mysqldump -uroot -pzzyy55555 -B -F -R -x --source-data test |gzip >test$(date +%F%T).sql;
备份的sql中,在开头会有这个,我们需要用备份的sql + mysql—bin.000014开始数据回档恢复;
②mysqlbinlog --no-defaults -v "/data/mysql/mysql-bin.000014",这个命令可以用来查看binlog日志,-v表示会转化为伪sql,从中截取了一段,begin开始,commit结束;我们使用mysqlbinlog搭配需要的时间进行数据恢复,大于,小于日志中记录的时间,也没有事,它会自动识别的
③数据恢复,备份的冷备sql,登录进入mysql服务器,source /冷备文件,就可以,binlog数据恢复:使用命令如下:
mysqlbinlog --no-defaults --start-datetime="2023-07-19 08:18:50" --stop-datetime="2023-07-19 14:20:45" /data/mysql/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -pzzyy55555,前面参数就是开始时间(就是我们sql备份文件创建的时间),后面数据就是结束时间(我们需要回档到的目标时间),这里写全路径名是因为需要书写脚本自动执行;最后书写脚本,在java代码中执行脚本,传入参数是新建目的;需要传递两个备份日志的原因,是因为我们要筛选出,两个备份日志中间的binlog,才能更好的筛选哪些日志记录了我们需要 回档到目标时间那天的数据,(ps,就算不筛选也行,因为只要需要回档的时间,所有的日志执行也行);
./bach.sh temp.sql temp2.sql "2023.07.23 15:18:00"
#!/bin/bash #mysqldump -uroot -pzzyy55555 -B -F -R -x --source-data test > $(date +%F%T)back.sql; #$1 冷备日志需要传入 #$2 冷备日志后一天的日志(传入为no 表示没有) #$3 回档目标时间 a=$(cat $1 |grep 'CHANGE MASTER TO MASTER_LOG_FILE') echo $a a=$(echo ${a#*\'}); echo $a a=$(echo ${a%\'*}) echo $a #回滚目标log日志 #冷备日志恢复 /usr/local/mysql/bin/mysql -uroot -pzzyy55555 -e "source /root/$1"; target="$3" #判断是今天回滚,还是今天之前回滚 if [ "$2" == no ]; then echo "使用master进行备份" targetTime=`date "+%F %T" -r $1` #获取备份文件的创建日期 echo "文件创建时间:$targetTime" rm -rf mysql-binlog.txt find /data/mysql/* -newermt "$targetTime" -printf '%f\n' | grep mysql-bin |grep -v mysql-bin.index > mysql-binlog.txt; /usr/local/mysql/bin/mysql -uroot -pzzyy55555 -e "flush logs"; cat mysql-binlog.txt | while read line; do echo ${line} echo $targetTime echo $target /usr/local/mysql/bin/mysqlbinlog --no-defaults --start-datetime="$targetTime" --stop-datetime="$target" /data/mysql/${line} | /usr/local/mysql/bin/mysql -uroot -pzzyy55555 done else b=$(cat $2 |grep 'CHANGE MASTER TO MASTER_LOG_FILE') echo $b b=$(echo ${b#*\'}); echo $b b=$(echo ${b%\'*}) echo $b #下一次的log日志 echo "查询两个日志文件的备份" targetTime=`date "+%F %T" -r $1` #获取备份文件的创建日期 echo "开始时间,文件创建时间 $targetTime " targetEndTime=`date "+%F %T" -r $2` targetEndTime=`date -d "$targetTime 10 minute" '+%Y-%m-%d %H:%M:%S' ` echo "结束时间,第二个文件创建时间:$targetEndTime" rm -rf mysql-binlog.txt find /data/mysql/* -newermt "$targetTime" ! -newermt "$targetEndTime" -printf '%f\n' | grep mysql-bin |grep -v mysql-bin.index > mysql-binlog.txt; cat mysql-binlog.txt | while read line; do echo ${line} echo $targetTime echo $target /usr/local/mysql/bin/mysqlbinlog --no-defaults --start-datetime="$targetTime" --stop-datetime="$target" /data/mysql/${line} | /usr/local/mysql/bin/mysql -uroot -pzzyy55555 done fi标签:binlog,--,数据库,echo,mysql,操作,日志,回档,备份 From: https://www.cnblogs.com/zhangzheshuai/p/17574984.html