暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL闪回功能

374

熟悉Oracle的朋友知道,如果在Oracle中误删除了数据,特定场景下可以通过闪回,进行数据的恢复,操作上是比较直观的,而且有很多粒度,例如闪回查询、闪回表、闪回事务、闪回数据库。

MySQL中同样支持闪回,但是和Oracle略有区别,通过这篇文章技术分享 | 浅谈MySQL闪回的实现》,了解一下MySQL数据库闪回功能。

1、闪回实现原理

闪回的业务价值是,在DBA执行错误的数据提交操作之后,还能把数据恢复还原到之前某个时刻的状态,最大程度地挽回损失。

MySQL中,binlog文件主要用于主从同步二进制数据日志。当主服务器数据发生变更时,会把变动明细持久化到binlog文件中,此时从服务器通过拉取并解析binlog文件,实现数据的同步。正是由于binlog文件中记录了数据变更的信息,因此MySQL的闪回是基于binlog文件来实现的。

说的更准确一点,如果要在MySQL中实现闪回,则必须要求binlog文件日志格式是binlog_format=row
,并且binlog_row_image=full
。通过指定binlog文件的日志格式,就能在binlog中完整记录数据变化的轨迹和具体的操作行为(增删改)的前后差异。

基于上述前提,我们可以解析并处理binlog文件中的事件,然后反序遍历。同时对增删改进行反转逆操作,即插入映射成删除、删除映射成插入、更新交换新旧数据区间。最后输出对应数据回滚的binlog文件,将其再次导入mysql,即完成对增删改数据的回滚还原。

2、binlog文件格式初探

binlog是一个二进制文件,具体存放的路径,可以通过在mysql的客户端执行:show variables like '%datadir%'
,这个SQL语句来查看。这时结合上面的路径信息,在终端中可以输入,

    #  binlog文件存放路径
    cd /home/mysql-server/bld_debug/install_debug/data/
    #  binlog.000006指要查看的binlog文件名
    hexdump -C binlog.000006|more。

结果示例如下,

    00000000  fe 62 69 6e ad 10 15 61  0f 01 00 00 00 79 00 00  |.bin...a.....y..|
    00000010  00 7d 00 00 00 00 00 04  00 38 2e 30 2e 32 35 2d  |.}.......8.0.25-|
    00000020  31 35 2d 64 65 62 75 67  00 00 00 00 00 00 00 00  |15-debug........|
    00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00000040  00 00 00 00 00 00 00 00  00 00 00 ad 10 15 61 13  |..............a.|
    00000050  00 0d 00 08 00 00 00 00  04 00 04 00 00 00 61 00  |..............a.|
    00000060  04 1a 08 00 00 00 08 08  08 02 00 00 00 0a 0a 0a  |................|
    00000070  2a 2a 00 12 34 00 0a 28  01 ea d7 cf 01 ad 10 15  |**..4..(........|
    00000080  61 23 01 00 00 00 1f 00  00 00 9c 00 00 00 80 00  |a#..............|
    ......

前面的4个字节fe 62 69 6e是魔数,标识文件类型是binlog。后面的二进制数据则表示事件,binlog中记录的事件类型主要有,

  • FORMAT_DESCRIPTION_EVENT
    :该事件描述了binlog文件的版本信息和MySQL服务器版本信息,以及文件中涉及到所有事件的类型。它是binlog文件中的第一个事件,并且有且只有一个。
  • TABLE_MAP_EVENT
    :该事件记录了将要发生更新的表结构信息,比如表字段的类型,表字段长度以及是否可空等。
  • WRITE_ROWS_EVENT
    /UPDATE_ROWS_EVENT
    /DELETE_ROWS_EVENT
    :分别表示插入、更新和删除事件,必须配合TABLE_MAP_EVENT
    来进行解析,通常我们将上述三个事件统称为ROWS_EVENT
    事件。

  • binlog文件的内容就是由头4个字节的魔数标识叠加若干事件要素组成的。更多binlog文件的信息可以参考官方文档:https://dev.mysql.com/doc/internals/en/binary-log.html

3、闪回实现过程

  • 步骤1:解析binlog文件中的事件。特别将ROWS_EVENT
    TABLE_MAP_EVENT
    提取出来,放入待处理队列。

  • 步骤2:循环遍历队列元素,将ROWS_EVENT
    和它就近的TABLE_MAP_EVENT
    进行关联绑定,同时反转DML操作。即判断事件类型如果是插入事件WRITE_ROWS_EVENT
    用删除事件DELETE_ROWS_EVENT
    进行替换;判断如果是删除事件DELETE_ROWS_EVENT
    用插入事件WRITE_ROWS_EVENT
    替换;如果是更新事件UPDATE_ROWS_EVENT
    则交换对调更新操作前后的新旧数据镜像分区。
  • 步骤3:逆序遍历队列元素,同时生成新的回滚binlog日志文件。
  • 步骤4:把回滚的binlog文件通过mysql客户端导入到数据库中。


直观感觉MySQL的闪回操作性上,还是有些复杂,存在一些门槛。


如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,




近期更新的文章:
MySQL 8.0对count(*)的优化
大同两日游攻略和避坑实用帖
tcpdump抓包神器介绍
了解应对三伏天的策略
MySQL的coredump堆栈信息的采集流程
MySQL中timestamp时区转换导致CPU %sy高的场景

近期的热文:
推荐一篇Oracle RAC Cache Fusion的经典论文
"红警"游戏开源代码带给我们的震撼

文章分类和索引:
公众号1200篇文章分类和索引

文章转载自bisal的个人杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论