记录mysql误操作 删除或者修改数据后如何回滚

线上数据库中的数据不像测试数据库那样,需要严谨的使用,如果因为误操作导致数据失真,是比较严重的线上事件

以下举例如何通过mysql binlog日志回滚不太大量的数据

1.我们需要查看mysql是否开启了binlog日志,如下图就是已经开启状态,如果为OFF就无法通过本方法恢复数据了

#查看MySQL的日志情况(是否开启等)
show variables like 'log_bin%';

MySQL 查询回表次数 mysql查看回滚记录_MySQL 查询回表次数

2.我们需要找到当前mysql记录的binlog文件,并去定位误操作的pos或者时间段

#找到当前mysql记录的binlog文件 把文件名传入下方
show master status;

#查看binlog,定位误操作的pos或者时间段
show binlog events in 'binlog.000001';

#以上命令可以在navicat上执行

在此我通过以下更新语句来模拟故障

UPDATE spatial_data_source_copy1 set name = 'testupdate'

进入部署该mysql的docker容器中采用mysqlbinlog 的方式查找语句定位

以下命令需要进入mysql容器执行(本机部署则无须进入容器)
#找到mysql日志文件位置
cd /var/lib/mysql

#检索 
mysqlbinlog binlog.000001 | grep -7a  "resource"

#我这边采用误操作的库名(resource)为检索条件,也可以检索表名,操作类型等

MySQL 查询回表次数 mysql查看回滚记录_数据_02

我们发现该条误操作update语句对应的pos为17847-22082之间

3.回滚

回滚可以通过时间段或者pos位置进行回滚,我们需要选择该操作之前的节点进行回滚,如果选择17847-22082则回滚不会生效

所以我们将选择13474-17649之间进行回滚

#起始位置
--start-position
#结束位置
--stop-position
//回滚
 mysqlbinlog  -d 库名 --start-position=13474 --stop-position=17649  binlog.000001|mysql -uroot -p密码 库名
 
 或者
mysqlbinlog -d 库名 --start-position=13474 --stop-position=17649  binlog.000001 > ./update.sql

#进入mysql 
use 库
#执行生成的sql文件
source update.sql

#清空日志文件语句 谨慎使用!!
RESET MASTER;
#用来生成一个新的日志文件
flush logs;

当然我们也可以通过时间来进行回滚,根据上图日志中的时间进行回滚

mysqlbinlog  --no-defaults  -d 库名 --start-datetime='2022-03-23 7:10:55' --stop-datetime='2022-03-23 7:16:11'  binlog.000001|mysql -uroot -p密码 库名

#起始时间点
--start-datetime            
#结束时间点
--stop-datetime

回滚前数据:

MySQL 查询回表次数 mysql查看回滚记录_MySQL 查询回表次数_03

回滚后数据:

MySQL 查询回表次数 mysql查看回滚记录_数据_04

至此数据回滚就结束了