动手实现一个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用于数据灾备、同步

动手实现回闪小工具

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

相关推荐
这孩子叫逆2 小时前
6. 什么是MySQL的事务?如何在Java中使用Connection接口管理事务?
数据库·mysql
罗政2 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
拾光师3 小时前
spring获取当前request
java·后端·spring
掘根4 小时前
【网络】高级IO——poll版本TCP服务器
网络·数据库·sql·网络协议·tcp/ip·mysql·网络安全
Java小白笔记5 小时前
关于使用Mybatis-Plus 自动填充功能失效问题
spring boot·后端·mybatis
Bear on Toilet5 小时前
初写MySQL四张表:(3/4)
数据库·mysql
无妄啊______5 小时前
mysql笔记9(子查询)
数据库·笔记·mysql
Looooking5 小时前
MySQL 中常用函数使用
数据库·mysql
island13146 小时前
从 InnoDB 到 Memory:MySQL 存储引擎的多样性
数据库·学习·mysql
ZZDICT6 小时前
MySQL 子查询
数据库·mysql