当前位置: 首页 > 科技观察

MySQL误用后如何快速恢复数据

时间:2023-03-20 10:19:52 科技观察

基本上每个和数据库打交道的程序员(当然也可能是你的同事)都会遇到一个问题,MySQL误用后如何快速回滚?比如删除一个表,忘记加限制,整个表就没了。如果这还是线上环境的核心业务数据,那这件事就闹大了。误操作后,快速回滚数据非常重要。传统方案采用全量备份重建实例,然后采用增量binlog备份恢复到误操作前的状态。然后跳过误操作的SQL,继续应用binlog。这种方法费时费力,不值得推荐。使用binlog2sql快速闪退首先确保你的MySQL服务器开启了binlog,设置如下参数:[mysqld]server-id=1log_bin=/var/log/mysql/mysql-bin.logmax_binlog_size=1000Mbinlog-format=rowIfnot如果开启了binlog,并且没有预先生成回滚SQL,那么想要快速恢复数据确实是不可能的。对于存储重要业务数据的MySQL,强烈建议开启binlog。然后,安装开源工具binlog2sql。binlog2sql是一款简单易用的binlog分析工具,其中一个功能就是利用binlog进行闪回。gitclonehttps://github.com/danfengcao/binlog2sql.gitpipinstall-rrequirements.txt然后,我们就可以生成回滚SQL了。背景:test库的tbl表整表数据被误删,需要紧急回滚。测试库tbl表原始数据测试库tbl表原始数据mysql>select*fromtbl;+----+--------+---------------------+|id|name|addtime|+----+------+------------------+|1|小赵|2016-12-1000:04:33||2|小倩|2016-12-1000:04:48||3|小孙|2016-12-1000:04:51||4|小李|2016-12-1000:04:56|+----+--------+---------------------+4rowsinset(0.00sec)mysql>deletefromtbl;QueryOK,4rowsaffected(0.00sec)tbl表清空mysql>select*fromtbl;Emptyset(0.00sec)恢复数据步骤:登录mysql,查看当前binlog文件mysql>showmasterlogs;+---------------+------------+|Log_name|File_size|+-------------------+------------+|mysql-bin.000046|12262268||mysql-bin.000047|3583|+------------------+------------+***binlog文件为mysql-bin.000047,然后我们定位到误操作SQL的binlog位置$pythonbinlog2sql/binlog2sql.py-h127。0.0。1-p3306-uadmin-p'admin'-dtest-ttbl--start-file='mysql-bin.000047'输出:从`test`.`tbl`中删除,其中`addtime`='2016-12-1000:04:33'AND`id`=1AND`name`='小赵'LIMIT1;#start3346end3556DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-1000:04:48'AND`id`=2AND`name`='小钱'LIMIT1;#start3346end3556DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-1000:04:51'AND`id`=3AND`name`='小孙'LIMIT1;#start3346end3556DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-1000:04:56'AND`id`=4AND`name`='小李'LIMIT1;#start3346end3556生成回滚sql,查看回滚sql是否正确$pythonbinlog2sql/binlog2sql.py-h127.0.0.1-P3306-uadmin-p'admin'-dtest-ttbl--start-file='mysql-bin.000047'--start-pos=3346--end-pos=3556-B输出:INSERTINTO`test`.`tbl`(`addtime`,`id`,`name`)VALUES('2016-12-1000:04:56',4,'小李');#start3346end3556INSERTINTO`test`.`tbl`(`addtime`,`id`,`name`)VALUES('2016-12-1000:04:51',3,'小孙');#start3346end3556INSERTINTO`test`.`tbl`(`addtime`,`id`,`name`)VALUES('2016-12-1000:04:48',2,'小钱');#start3346end3556INSERTINTO`test`.`tbl`(`addtime`,`id`,`name`)VALUES('2016-12-1000:04:33',1,'小赵');#start3346end3556确认回滚sql正确,执行回滚语句,登录mysql确认,数据回滚成功。$pythonbinlog2sql.py-h127.0.0.1-P3306-uadmin-p'admin'-dtest-ttbl--start-file='mysql-bin.000047'--start-pos=3346--end-pos=3556-B|mysql-h127.0.0.1-P3306-uadmin-p'admin'mysql>select*fromtbl;+----+--------+---------------------+|id|name|addtime|+----+--------+-------------------+|1|小赵|2016-12-1000:04:33||2|小倩|2016-12-1000:04:48||3|小孙|2016-12-1000:04:51||4|小李|2016-12-1000:04:56|+----+--------+---------------------+至此,你再也不用担心被解雇了。常见问题有人会问,如何快速回滚我的DDL误操作?例如,我放下了一张大桌子。这很难做到。因为即使是行模式,DDL操作也不会把每一行数据的变化都记录到binlog中,所以DDL无法通过binlog进行回滚。要实现DDL回滚,必须在执行DDL之前备份旧数据。确实有人通过修改mysqlserver的源码实现了DDL的快速回滚。找到了阿里的xiaobinlin,提交了补丁。但据我所知,国内很少有互联网公司应用这个功能。究其原因,我觉得主要是懒得折腾,没必要搞这个低频功能,次要的原因是会加一些额外的存储。因此,如果DDL被误操作,只能通过备份来恢复。如果公司连备份都用不了,真的建议买飞机票。你在干什么?mysql除了binlog2sql还有其他回滚工具吗?当然有。阿里彭立勋给mysqlbinlog增加了flashback的特性。这应该是mysql最早的闪回功能了。Peng解决了DML回滚,并讲解了使用binlog进行DML闪回的设计思路。DDL回滚特性也是阿里团队提出并实现的。这两个功能是有创新的,之后出现的闪退工具基本上都是对以上两个的模仿。另外,去哪儿开源的Inception是一套MySQL自动化运维工具,比较重,支持DML回滚,不是从binlog,而是从备份,也支持DDL回滚表结构。数据无法回滚~还有一种方法叫slave延迟备份,就是设置一个不增加业务流量的slave,故意延迟一段时间。这实际上是在传统方法的基础上去掉了实例恢复的步骤。这种方式会额外消耗一台机器,不推荐使用。如果有遗漏mysql回滚相关的优秀工具和优秀文章,请告诉我~我的邮箱danfengcao.info@gmail.com