首页 > 数据库 > MySQL > 正文

MySQL闪回(flashback)原理与实战

2024-07-24 12:52:51
字体:
来源:转载
供稿:网友

DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚。传统恢复方法是利用备份重搭实例,再应用去除错误sql后的binlog来恢复数据。此法费时费力,甚至需要停机维护,并不适合快速回滚。也有团队利用LVM快照来缩短恢复时间,但快照的缺点是会影响mysql的性能。

MySQL闪回(flashback)利用binlog直接进行回滚,能快速恢复且不用停机。本文将介绍闪回原理,给出笔者的实战经验,并对现存的闪回工具作比较。

开胃菜

某天,小明因种种原因,误删了大批线上用户表的数据。他急忙找到公司DBA请求帮助,“客服电话已被打爆,大量用户投诉无法登陆,领导非常恼火。请问多久能恢复数据?”DBA一脸懵逼,沉默十秒后,伸出一根手指。“你的意思是一分钟就能恢复?太好了。”小明终于有些放松,露出了一丝笑容。“不,我们中有个人将会离开公司。”DBA沉痛的说道。

勿让悲剧发生,尽早将此文转给公司DBA。

闪回原理

binlog概述

MySQL binlog以event的形式,记录了MySQL server从启用binlog以来所有的变更信息,能够帮助重现这之间的所有变化。MySQL引入binlog主要有两个目的:一是为了主从复制;二是某些备份还原操作后需要重新应用binlog。

有三种可选的binlog格式,各有优缺点:

    statement:基于SQL语句的模式,binlog数据量小,但是某些语句和函数在复制过程可能导致数据不一致甚至出错; row:基于行的模式,记录的是行的完整变化。很安全,但是binlog会比其他两种模式大很多; mixed:混合模式,根据语句来选用是statement还是row模式;

    利用binlog闪回,需要将binlog格式设置为row。row模式下,一条使用innodb的insert会产生如下格式的binlog:

    # at 1129#161225 23:15:38 server id 3773306082 end_log_pos 1197 Query thread_id=1903021 exec_time=0 error_code=0SET TIMESTAMP=1482678938/*!*/;BEGIN/*!*/;# at 1197#161225 23:15:38 server id 3773306082 end_log_pos 1245 Table_map: `test`.`user` mapped to number 290# at 1245#161225 23:15:38 server id 3773306082 end_log_pos 1352 Write_rows: table id 290 flags: STMT_END_FBINLOG 'muJfWBPiFOjgMAAAAN0EAAAAACIBAAAAAAEABHRlc3QABHVzZXIAAwMPEQMeAAACmuJfWB7iFOjgawAAAEgFAAAAACIBAAAAAAEAAgAD//gBAAAABuWwj+i1tVhK1hH4AgAAAAblsI/pkrFYStYg+AMAAAAG5bCP5a2ZWE/onPgEAAAABuWwj+adjlhNeAD4BQAAAAJ0dFhRYJM='/*!*/;# at 1352#161225 23:15:38 server id 3773306082 end_log_pos 1379 Xid = 5327954COMMIT/*!*/;

    闪回原理

    既然binlog以event形式记录了所有的变更信息,那么我们把需要回滚的event,从后往前回滚回去即可。

    对于单个event的回滚,我们以表test.user来演示原理

    mysql> show create table test.user/G*************************** 1. row *************************** Table: userCreate Table: CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
    发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表