资讯专栏INFORMATION COLUMN

MySQL误操作数据rollback

IT那活儿 / 2552人阅读
MySQL误操作数据rollback

点击上方“IT那活儿”,关注后了解更多精彩内容!!

 一 

手动rollback


1. 环境背景

  • red hat 7.2

  • MySQL 5.7.17

  • log_bin=ON

  • binlog_format=ROW

2. 测试数据生成

create database test;

use test;

create table rollback(id int,name varchar(50),age int,update_date TIMESTAMP);

alter table rollback add primary key(id), modify id int auto_increment;

insert into rollback(name,age) values(cde,23),(xiaoming,22),(heshui,55),(dashan,33),(kuangfeng,23);

3. 模拟误操作

update rollback set age=11;

#上:update语句未加where条件,导致错误更新全表的数据。

#上:看到误操作之后所有人的年龄都变成了11。这里我使用update_date字段用来记录误操作的时间,用来快速查找binlog的位置。

4. rollback数据

show variables like log_bin_basename;

#上:通过这个参数找到binlog日志位置。

cd /u01/my3306/log/binlog

#上:进入binlog日志目录。

ls -l

#上:查看所有binlog文件最后更新时间。

#上:可以看到binlog.000009这个日志文件的最后更新时间与我们误操作的时间吻合。

5. binlog解析

mysqlbinlog -vv --start-datetime=2019-05-17 00:28:00 --stop-datetime=2019-05-17 00:29:00  binlog.000009

#上:mysqlbinlog用来将binlog日志解析成可以看得懂数据变更信息。需要通过这种解析将误操作之前的数据查找出来。

-vv :表示解析成SQL语句,并且显示字段类型。

--start-datetime:表示误操作开始的时间,与stop-datetime相结合用来定位需要rollback的数据。

#上:解析结果说明:

  • 这是一个update操作。

  • 操作的表名叫rollback。

  • WHERE下面的信息表示,update之前的行记录。

  • SET下面的信息表示,update之后的行记录。

  • ”@1“表示rollback表中的第一个字段,他的值是1。“@2”就是第二个字段,它的值是cde。

  • at 1265表示这个事件在日志当中的开始位置,end_log_pos 1562表示事件在日志当中的结束位置。

binlog解析出来的内容,我们通过以下四点来找到需要回滚的事务。

  • 事务开始时间是否与误操作的时间相吻合。

  • 事务的表名是否与误操作的表名相吻合。

  • 事务与误操作的dml语句是否一样。

  • 比对误操作的数据变更。这里是从23变成11,与我们误操作的数据一致。

6. rollback SQL

确定了误操作之前的数据,我们就需要用这些数据来拼接rollback SQL。让数据变成误操作之前的样子。

begin;

update `test`.`rollback` set 
id=1,name=cde,age=23,update_date=from_unixtime(1558078013)
where id=1 and name=cde and age=11 and 
update_date=from_unixtime(1558078101);

update `test`.`rollback` set 
id=2,name=xiaoming,age=22,update_date=from_unixtime(155807
8013) where id=2 and name=xiaoming and age=11 and 
update_date=from_unixtime(1558078101);

update `test`.`rollback` set 
id=3,name=heshui,age=55,update_date=from_unixtime(15580780
13) where id=3 and name=heshui and age=11 and 
update_date=from_unixtime(1558078101);

update `test`.`rollback` set 
id=4,name=dashan,age=33,update_date=from_unixtime(15580780
13) where id=4 and name=dashan and age=11 and 
update_date=from_unixtime(1558078101);

update `test`.`rollback` set 
id=5,name=kuangfeng,age=23,update_date=from_unixtime(15580
78013) where id=5 and name=kuangfeng and age=11 and 
update_date=from_unixtime(1558078101);

commit;

#上:我们将误操作之前的数据填写到set后面,将误操作之后的数据填写到where后面。进行反向更新达到rollback数据的效果。

#上:当我们执行了rollback SQL之后可以看到数据已经恢复成误操作之前的样子了。

 二 

MyFlash


如果需要rollback 的数据量小可以通过手动拼写rollback SQL的方式实现。但是一旦需要rollback的数据量大就需要借助工具来实现,这里可以使用美团的开源工具MyFlash。

MyFlash 非常适合回滚大量数据,可以将binlog文件转换成rollback binlog。通过执行rollback binlog来达到rollback 误操作数据的目的。

1. 安装

https://github.com/Meituan-Dianping/MyFlash

#上:下载地址

cd /opt/

unzip MyFlash-master.zip

#上:解压

yum install gcc* pkg-config glib2 libgnomeui-devel -y


#上:载依赖包


gcc -w `pkg-config --cflags --libs glib-2.0` 
source/binlogParseGlib.c -o binary/flashback

#上:动态编译

注意:经过我的测试,如果你系统上面有glib2(我的glib2版本:glib2-2.42.2-5)。不用执行yum和gcc也可以正常使用flashback,但是官方文档上面说需要执行gcc。

2. 生成测试数据

use test;create table myflash(id int,name varchar(50),age 
int,update_date TIMESTAMP);

alter table myflash add primary key(id), modify id int 
auto_increment;

insert into myflash(name,age) values(cde,23),
(xiaoming,22),(heshui,55),(dashan,33),
(kuangfeng,23);

3. 模拟误操作

update myflash set age=11;

#上:update语句未加where条件,导致错误更新全表的数据。

4. rollback数据

mysqlbinlog -vv --start-datetime=2019-05-19 22:29:00 --
stop-datetime=2019-05-19 22:31:00 binlog.000010

#上:通过误操作时间来填写start-datetime和stop-datetime来缩小查询binlog的范围,加快速度。

通过binlog文件最近更新时间,来确定误操作事务记录在binlog.000010文件当中。

#上:查看解析出的内容,通过误操作时间,误操作表,以及误操作的数据,这些信息来找到误操作的事务。并记录at 1415和end_log_pos 1711,这两个值。

/opt/MyFlash-master/binary/flashback --
binlogFileNames=/u01/my3306/log/binlog/binlog.000010 --
databaseNames=test --tableNames=myflash --start-
position=1415 --stop-position=1711 --
outBinlogFileNameBase=/u01/my3306/log/binlog/myflash-
binlog.000010

#上:通过以上命令来生成误操作事务的rollback binlog文件。

  • binlogFileNames:指定flashback要读取的binlog文件

  • databaseNames:指定库名之后flashback只会将该库的事务解析到rollback binlog当中

  • tableNames:指定表名之后flashback只会将该表的事务解析到rollback binlog当中

  • start-position:指定binlog文件的偏移量,flashback会从binlog文件的这个位置开始读取内容。

  • stop-position:指定binlog文件的偏移量,flashback读取到binlog文件这个位置的时候停止读取。

  • outBinlogFileNameBase:指定flashback生成的rollback binlog保存到哪里。

mysqlbinlog -vv /u01/my3306/log/binlog/myflash-
binlog.000010.flashback

#上:通过mysqlbinlog解析rollback binlog文件内容

#上:可以看到where和set的数据跟binlog.000010文件中记录的相反。

lashback | mysql -uroot -proot

#上:用mysqlbinlog 将myflash生成的rollback binlog文件解析,并发送mysql客户端执行。

#上:数据已经rollback 到误操作之前。当需要rollback的数据非常多的时候这么做非常快速

冬至,福至,一切都会如约而至。

本 文 原 创 来 源:IT那活儿微信公众号(上海新炬王翦团队)


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129711.html

相关文章

  • MongoDB复制集成员及状态转换

    摘要:大体分为成员的角色及转换成员状态及转换两部分。每个复制集成员在启动后,都先进入状态,然后加载成员的复制集配置,之后进入到状态。选举行为除了受和两个属性影响外,成员的状态也会影响选举,仅有和五种状态的成员允许进行投票操作。 此文已由作者温正湖授权网易云社区发布。 欢迎访问网易云社区,了解更多网易技术产品运营经验。 复制集(Replica Set)是MongoDB核心组件,相比早期版本采用...

    darryrzhong 评论0 收藏0
  • UnexpectedRollbackException解决方案

    摘要:在嵌套事务场景中,内层事务的和外层事务的会在外层事务结束时进行提交或回滚。解决方案如果希望内层事务抛出异常时中断程序执行,直接在外层事务的代码块中抛出如果希望程序正常执行完毕,并且希望外层事务结束时全部提交,需要在内层事务中做异常捕获处理。 前言 最近在项目中发现了一则报错:org.springframework.transaction.UnexpectedRollbackExcept...

    mating 评论0 收藏0
  • python 实现mysql增删查改

    摘要:本地安装配置安装这个数据库管理工具一会我们要手动创建数据库数据表字段当然也可以代码创建增主机名这里是你的地址数据库账号数据库密码端口数据库端口数据库名基本语句初始化一个游标对象数据库操作语句执行该语句关闭游标对象关 ...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<