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

动手实现回闪小工具

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

相关推荐
CaffeinePro18 分钟前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax1 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH1 小时前
Koa和Express的区别
后端
MariaH1 小时前
Koa框架的使用
后端
luckdewei2 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某3 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy3 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom4 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github
用户1474853079748 小时前
CodeX使用Skill生成游戏美术和音乐资源,一分钟入门
后端
Melody1238 小时前
用 abort 中断 AI 流式请求,我之前做错了
后端