`
丁林.tb
  • 浏览: 797158 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

MySQL闪回方案讨论及实现

阅读更多

Oracle有一个闪回(flashback)功能,能够用户恢复误操作的数据。本文讨论MySQL中支持闪回的方案。

 

1、 闪回的目标

    即使为了数据安全,我们搭建了主从。但实时主从备份只能防止硬件问题,比如主库的硬盘损坏。但对于误操作,则无能为力。比如在主库误删一张表,或者一个update语句没有指定where条件,导致全表被更新。当操作被同步到从库上后,则主从都“回天无力”。

    线上或者测试环境经常出现的误操作总是让DBA同学那么闹心。

    闪回的目的是要让数据库在commit之后,还能恢复到之前的某个状态,整库或指定的表。

    这里我们讨论用binlog来实现闪回的方案。

 

2、 无米无炊一

    恢复到之前的某个状态,是需要数据的。这数据可以是 a) 回滚步骤 或者 b) 操作之前的数据状态原文。
    但我们知道,若使用statement,并没有上述需要的数据。试想binlog中记录了一句update t set f1=3 where id=3。怎么恢复呢?

    因此,我们的第一个“米”,就是binlog必须是row based的。在row base下,binlog同时记录了更新前后的整行记录。

   a)         单个语句的闪回

    有了row base的binlog后,我们来分析一下怎么实现闪回。平时的DML无非三种操作,增删改,先说三种操作的日志格式。

     一个语句分成两个event (实际上不止,其他可以忽略), 一个table_map event 和 一个Rows_log_event。Table_map event是一样的,主要看Rows_log_event。
    每个Rows_log_event中包含event_type, 可选值为WRITE_ROWS_EVENT、UPDATE_ROWS_EVENT、DELETE_ROWS_EVENT。从宏名字就能看出用途。

    对于insert和delete,event中包含了插入/删除的记录的所有字段的值(太爽了。。)
    对于update操作,event中依次记录旧行, 新行的值。

    因此我们看到,这些信息足够让我们对单个操作实现“逆操作”。

  i. 对于insert操作,只需要把event_type改成DELETE_ROWS_EVENT;对于delete操作,改成WRITE_ROWS_EVENT
  ii.  对于update操作,只需要把event中的旧行和新行值对调即可。

 

b)        binlog的闪回

   
我们只需要把binlog文件反向执行,每个操作都执行逆操作即可。当然也不是所有的event都反转。Table_map event必须还是在Rows_log_event每个操作之前。目前的方案是用mysqlbinlog工具,增加一个flashback参数,输出结果为一个新的binlog文件――姑且叫做flashbacklog,这个flashbacklog顺序执行,可制定某张表和执行到哪个pos,来实现数据库的闪回。 

 

3、 无米无炊二

    上面我们说了DML的闪回方案。但对于DDL却无能为力,对于大多数的ddl,即使是row base格式,binlog中仍只记录语句本身。对于删表操作,只记录一个语句drop table t。仅凭这句话,无法还原表的数据。

    虽然可以将一个drop table语句转换成先delete再删表,性能却会降低很多。这里我们用上面说道的另外一种可用数据:“操作前数据备份”。

    按顺序我们先讨论怎么保存数据,再讨论怎么闪回。

 

保存数据
    先说DDL的分类。有一类DDL,是不需要重建表的,比如加非聚簇索引。这类操作其实不会丢数据,也是在原表上直接操作,对于我们“以恢复数据为目的”的闪回,是可以先忽略的。 另外一类,则是会影响到表数据的操作。比如

    a)  Drop/truncate table
    这两个操作直接把表数据清空。

    b)   Alter table add、drop、change column

这类操作的执行过程是,1) 按照新的表定义建立一个临时表tmpa,2) 将原表数据拷贝到临时表,3)将原始表改名tmpb,4)将tmpa改名为原表名,5)将tmpb删除


    我们分析上面的两个操作,都有一个“删除数据”的过程。


    因此我们的保存数据方法就是:在删除的动作开始之前,把表数据备份起来,然后留一个空表,在空表上执行“删除”操作。


    用一个库 #bak_database存放这些历史数据。

 

 闪回
    有了数据以后,我们就要想一个比较统一的方法来闪回。上面我们说了对于DML操作,可以通过反向执行所有逆操作来实现,对于语句里面的DDL,只能直接跳过。原因是一个DDL不一定有直接的逆操作。

    因此我们的方案中要构造这种逆操作。Event_type增加一种FLASHBACK_EVENT。这类操作形式与Query_Event相同,都是简单的SQL语句,只是包含了将数据恢复的操作。

举例:

 a)   对于altert table t add column 操作。

    我们在操作的过程中将临时表tmpb,不删除,而是保存到 #bak_database.#bak_table_xxxxx (后缀用于去重),在我的patch中用当前的时刻(微秒)。

    对于这个语句,我们生成两条FLASHBACK_EVENT,分别是 alter table `#bak_database`.`#bak_table_xxxxx` rename to `my_db`.`my_tbl`; 和 drop table  `my_db`.`my_tbl`;

    这里的my_db和my_tbl分别为原来的库名和表名。

    所以mysqlbinlog工具怎么处理FLASHBACK_EVENT这类event呢,直接执行就行了。(注意这两个event也是反向执行的,所以在恢复的时候是先删除`my_db`.`my_tbl`,再从#bak_database恢复回来)

b)       对于drop table操作

    由于实际操作会把这个表删,只需要一个
alter table `#bak_database`.`#bak_table_xxxxx` rename to `my_db`.`my_tbl`; 即可。

 

4、 演示

初始状态我们库中只有一个表 test.tb,两行

CREATE TABLE `tb` (
`c` int(11) NOT NULL DEFAULT ’0′,
 `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;mysql> select * from tb;
+——+——+
| c    | d    |
+——+——+
|    1 |   10 |
|    2 |   20 |
+——+——+


 模拟一个DML和一个DDL

insert into tb values(3,30);
alter table tb drop column d;  


 这两个操作后在binlog文件中生成的结果如下

 

说明:

    将mysqlbinloig中的其他信息去掉,其中红色框中为insert语句产生的binlog,在flashback工具中会被转化为delete操作。

    两个蓝色框中的即为我们生成的FLASHBACK_EVENT。除了event_type与普通的query_event不同,还将库名+表名放在语句的前面,目的是为了flashback工具执行按表闪回的时候可以直接识别表名,不需要解析binlog语句。

     紫色框中就是那个真正的DDL操作,在flashback工具中被忽略。

    所以上面的binlog被flashback工具解析后的结果是两个DDL语句和一个delete操作,能够恢复到表的初始状态。

 

   备份表:

 

 

   5、 小结

    这里讨论了MySQL闪回的一种方案.

增加一种新的event_type, 不会影响原来mysqlbinlog工具的使用;
备份即将删除的表,没有增加额外的操作,不会对正常操作性能造成影响(当然需要更多的存储空间)。

实际上我们上面还留了一个“空挡”没有讨论,在方案完成后补充。


    涉及到MySQL server本身和mysqlbinlog这个工具两部分的修改,MySQL工具部分由@plinux同学实现。(其实如果不恢复DDL,可以只使用这个工具).  server部分的改动可以只部署slave,这样slave同时担负备份和闪回准备的功能。

    Patch和工具在完成测试后发布出来,敬请期待。

0
0
分享到:
评论
1 楼 babaoqi 2012-07-27  
2个疑问
1、DML
    binlog改为row base后,如果update操作较多,则binlog文件大小增长也会变成压力

2、DLL
    a)  Drop/truncate table。这个的备份感觉很好,也没太大压力

    b)   Alter table add、drop、change column
          “ 在删除的动作开始之前,把表数据备份起来,然后留一个空表,在空表上执行“删除”操作。”
          在表备份时,如何知道“5)将tmpb删除。”临时表tmpb的名称怎么获取

       

相关推荐

    MySQL Flashback闪回功能详解.docx

    MySQL Flashback 闪回功能详解 MySQL Flashback 是 ...MySQL Flashback 闪回功能可以快速恢复由于误操作丢失的数据,是 DBA 的一种重要解决方案。但是,需要正确地使用 flashback 工具,避免出现数据不一致等问题。

    cpp-MyFlash美团点评的开源MySQL闪回工具

    MyFlash的核心设计目标是快速和高效地实现MySQL的数据闪回。它通过记录和重放SQL日志来实现这一功能。在MySQL中,通常使用二进制日志(Binary Log)来记录数据库的更改,而MyFlash则利用这些日志来跟踪和恢复数据...

    mysql5.6 闪回插件

    mysql 针对MYSQL delete、update、insert语句误操作(如update忘记加where条件) 利用淘宝的彭立勋开发出的一个flashback插件进行恢复,之前的插件版本只针对MySQL-5.5.18, 无法用于目前主流的5.6版本的。后来...

    02-闪回在MySQL中的实现和改进-万里数据库-唐洁(20220115)1

    MySQL 中的闪回实现方案可以分为 DDL闪回实现方案和 DML 闪回实现方案。 * DDL 闪回实现方案:使用 binlog 文件来记录数据的变更信息,通过 binlog 文件来实现闪回。 * DML 闪回实现方案:使用undo表空间来记录数据...

    mysql高可用方案实战

    - MMM (MySQL Master-Master)是一种基于Perl脚本实现的MySQL主主同步方案。 - **6.2 方案优缺点** - **优点**:部署简便,适用于快速搭建高可用环境。 - **缺点**:功能相对单一,对于复杂环境的支持不足。 - **...

    mysql闪回实战.docx

    MySQL的binlog(二进制日志)记录了所有对数据库的改变操作,包括INSERT、UPDATE、DELETE等,这使得我们可以根据binlog来实现数据的闪回,即撤销错误的操作,将数据库状态恢复到某个历史时刻。 一、闪回原理 闪回的...

    mysql分布式数据库mycat方案

    MySQL分布式数据库MyCAT方案 MySQL分布式数据库MyCAT方案是基于 MySQL 数据库管理系统和 MyCAT 分布式数据库中间件的实践方案。该方案的主要目的是为了解决传统 MySQL 数据库的单点故障和性能瓶颈问题,提高数据库...

    mysql集群方案对比

    - 原理:MySQL 5.7及更高版本中的官方解决方案,实现多主复制,支持强一致性。 - 优点:官方支持,易于配置,提供冲突解决策略。 - 缺点:相比其他方案,可能存在更高的延迟,对网络条件要求较高。 7. **InnoDB ...

    MySQL-集群最佳解决方案

    MySQL集群最佳解决方案的知识点主要包括MySQL的高可用性解决方案、MySQL复制技术、MySQL集群技术和第三方合作伙伴提供的解决方案。下面将详细阐述这些知识点。 1. MySQL的高可用性解决方案 高可用性(High ...

    MySQL高可用解决方案_社区 .pdf

    在版本5.7.17及以后,MySQL加入了全新的群组复制(MGR)功能,为高可用性解决方案提供了更为强大和灵活的选择。群组复制不仅提高了数据安全性,还支持自动故障转移和跨地域复制,使得数据库的可扩展性和容灾能力大大...

    MySQL binlog闪回工具

    它基于MySQL的二进制日志(Binary Log,简称binlog)功能,能够帮助用户在发生错误或者数据丢失的情况下,通过binlog回溯到任意一个历史状态,实现数据的“闪回”。这里我们将详细探讨MySQL binlog闪回工具的工作...

    MySQL高可用方案大全

    Lvs+Keepalived+MySQL 单点写入主主同步高可用方案 Lvs+Keepalived+MySQL 单点写入读负载均衡主主同步高可用方案 Heartbeat高可用MySQL主主同步方案 Heartbeat+DRBD+MySQL高可用方案 MMM高可用MySQL方案

    MySQL千万数据解决方案

    方案一:优化现有mysql数据库。优点:不影响现有业务,源程序不需要修改代码,成本最低。缺点:有优化瓶颈,数据量过亿就玩完了。 方案二:升级数据库类型,换一种100%兼容mysql的数据库。优点:不影响现有业务,源...

    mysql数据库优化方案(值得学习)

    简单描述数据库优化方案,以及数据库一些常用的操作,包括一些简单的查询语句,函数使用,合适学习mysql的读者。 简单描述数据库优化方案,以及数据库一些常用的操作,包括一些简单的查询语句,函数使用,合适学习...

    实战体验几种MysqlCluster 方案.docx

    MySQL Cluster 的架构及实现原理主要由三种类型的服务组成: 1. NDB Management Server:管理服务器主要用于管理 cluster 中的其他类型节点(Data Node 和 SQL Node),通过它可以配置 Node 信息,启动和停止 Node...

    mysql+heartbeat+共享存储实施方案(mysql高可用集群).doc

    【MySQL+Heartbeat+共享存储实施方案】是一种实现MySQL高可用集群的方法,旨在确保数据库服务的稳定性和连续性。该方案采用HA(High Availability)双机热备软件Heartbeat,配合共享存储来实现实时的数据同步和故障...

Global site tag (gtag.js) - Google Analytics