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

动手实现回闪小工具

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

相关推荐
砍材农夫5 分钟前
TCP和UDP区别
后端
千寻girling38 分钟前
一份不可多得的 《 Django 》 零基础入门教程
后端·python·面试
千寻girling44 分钟前
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站 | 《Web框架》
人工智能·后端·算法
贾铭1 小时前
如何实现一个网页版的剪映(三)使用fabric.js绘制时间轴
前端·后端
xiaoye20181 小时前
Spring 自定义 Redis 超时:TTL、TTI 与 Pipeline 实战
后端
程序员爱钓鱼4 小时前
GoHTML解析利器:github.com/PuerkitoBio/goquery实战指南
后端·google·go
golang学习记4 小时前
从“大泥球“到模块化单体:Spring Modulith + IntelliJ IDEA 拯救你的代码
后端·intellij idea
颜酱4 小时前
一步步实现字符串计算器:从「转整数」到「带括号与优化」
javascript·后端·算法
离开地球表面_994 小时前
金三银四程序员跳槽指南:从简历到面试再到 Offer 的全流程准备
前端·后端·面试
UrbanJazzerati4 小时前
Scrapling入门指南:零基础也能学会的网页抓取神器
后端·面试