动手实现一个mysql数据闪回小工具(一)

前言

开发一个自动数据库升级工具,实现一键回滚数据误操作或者升级回滚

基于mysql的binlog日志原理,动手实现了一个数据库升级小工具;可以通过执行binlog文件分析指定时间节点的日志,然后对应生成相应的dml回滚语句,最后执行回滚语句达到数据库快速回滚或者闪回功能。

解析binlog功能是通过开源项目-binlog2sql实现的,链接如下: danfengcao/binlog2sql: Parse MySQL binlog to SQL you want (github.com)

最后实现的效果如下:

场景

我们业务上有一个自动升级的场景,需要测试人员在升级的时候执行开发维护的脚本,长期以来都是手工执行,并且在升级失败后,还需要回滚,这样很不优雅

探究原理

我们知道,事务有原子性,只要一个事物没有提交,我们就能通过rollback进行回滚,那么rollback底层的原理是什么呢?那怎么回滚一个或者多个已经提交的事务数据?

能想到的就是通过日志来回滚的,我们先从mysql的日志入手,mysql是我固定使用的一个关系型数据库,它有undo-log,redo-log,bin-log,relay-log等等

事物回滚-Undo log

在dml操作的时候,会生成对应的回滚操作语句记录在undo log中。

当事物中某条语句执行失败的时候,mysql就会执行undo log中的回滚语句,将数据库中的数据回滚到事物执行前的样子。(怎么找到对应的undo log执行点的呢)--错误,并不会生成对应的回滚语句;

而是通过一种类似COW(copyonwrite写时复制技术)先复制原有表的数据到undolog,然后将原来数据的roll_ptr指针指向这个undolog记录,然后再回滚的时候用undolog中的记录覆盖原来表中的数据,就达到回滚的效果,但是如果多表和多数据量操作呢?

如果是insert操作,那么roll_ptr指向的就是null,那么回滚的时候就会用null覆盖原来的数据。

但是undo log在事物提交后会被清除?所以说undo log是实物回滚的原理,但是怎么实现数据回滚或者叫恢复呢?

故障恢复- Redo log

Redo log是数据库一种数据恢复日志,数据库在写入缓存前先会写到redo-log中,如果写入成功,就会给客户端响应写入成功,然后数据库再写入到缓存中,然后再刷新到磁盘上。

特点:

  1. Redo log是顺序写,将记录追加到文件的尾部。
  2. Redo 日志的磁盘文件个数,默认为2个,mysql通过来回写这两个文件的形式记录Redo-log日志,用两个日志文件组成一个环形,循环写
  3. 是InnoDB专享的
  4. 记录的是变更后的数据,主要实现故障情况下的数据恢复

由于Redo log是循环写,如果用redo log来实现数据回闪,那么数据会不全,并且redo log记录的是变更后的数据,回滚dml获取不到,所以不可行。

数据闪回- Bin log

那么相比Redo log,bin log一般记录了全量的修改日志,而且也是追加写的形式,如果我们不主动去删除磁盘的日志文件,并且磁盘的控件还足够,一般bin log日志文件都会在本地,所以在我们需要回闪数据的时候,有两种方式:

  1. 分析需要回退时间节点后的本地bin log, 根据对应的dml语句逆向生成回滚dml语句,然后执行,即可实现闪回。
  2. 复制bin log文件,然后拷贝出来一份,然后打开拷贝出来的文件,删除掉需要回滚时间节点后的bin log,然后再利用mysqlbinlog工具导出对应bin log文件的sql脚本,然后本地执行该脚本,即可实现闪回。

Bin log特点

  1. Bin log是所有引擎通用的
  2. Bin log也是追加写,但是只要磁盘空间足够,就会不断创建新的bin log磁盘文件写入。
  3. Bin log能记录变更的sql语句(选择row模式)
  4. Bin log用于数据灾备、同步

动手实现回闪小工具

工具还在完善中,目前实现如下:

相关推荐
吃饱了得干活13 分钟前
限界上下文之后:微服务怎么拆、上下文怎么聊?
java·后端·架构
星火102420 分钟前
【Groovy翻译-进阶篇】运行时元编程与编译时元编程(上)
后端·groovy
wear工程师23 分钟前
MySQL 索引条件下推是什么?Using index condition 并不是覆盖索引
sql·mysql
CHHH_HHH25 分钟前
【Linux系统篇】深入解析Linux文件系统:从磁盘寻址到软硬链接
linux·服务器·开发语言·后端·ubuntu
星火102431 分钟前
【Groovy翻译-进阶篇】运行时元编程与编译时元编程(下)
后端·groovy
用户1069117941032 分钟前
SpringSercuirty整合jwt
后端
岁月如歌778639 分钟前
一次讲透 Redis 缓存击穿、穿透、雪崩,从原理到实战解决方案
java·后端·架构
IT_陈寒1 小时前
Vue的v-for为啥把我的渲染顺序搞乱套了?
前端·人工智能·后端
用户106911794101 小时前
SpringSecuirty自定义接口或者资源权限
后端
方便面不加香菜1 小时前
MySQL 复合查询
数据库·mysql