使用 MyFlash 实现 MySQL 数据闪回

简介

MySQL中的Binlog(Binary Log)数据闪回,也称为Point-in-Time Recovery (PITR),是一种强大的数据库恢复技术。它基于MySQL的二进制日志系统,允许用户在发生错误或需要回滚事务后,将数据库状态恢复到指定的过去某个时间点,而不仅仅是最近的一次提交。

  1. Binlog记录:当MySQL执行写操作时,会将这些操作记录在二进制日志中,包括SQL语句、更新前后的数据等。这些记录按时间顺序存储,形成一个完整的历史记录链。

  2. 闪回操作:如果需要恢复到某个时间点,管理员可以定位到那个时间点的日志位置,然后使用相应的工具(如mysqlbinlog或商业备份工具)读取和应用那些日志条目,使数据库回到那个时间点的状态。

  3. 特殊类型:MySQL 8.0及更高版本引入了ROW格式的二进制日志,使得闪回操作更加高效,可以直接根据行级别的修改来恢复数据,而不仅仅是整个事务。

Github

MyFlash 限制

  1. 仅支持 5.65.7 版本
  2. binlog 格式必须为 row,且 binlog_row_image=full
  3. 只能回滚DML(增、删、改

MySQL 准备

注: 本章 MySQL 是采用 Docker 部署,容器内是 不带mysqlbinlog 的,可以从已安装 MySQL 的Linux服务器上拷贝 mysqlbinlog 文件。

开启 binlog

[mysqld]
# binlog功能
log_bin=/var/lib/mysql/mysql-bin
# binlog 文件格式
binlog_format=ROW
# 表无论有没有主键约束或者唯一约束binlog都会记录所有前后镜像
binlog_row_image=FULL
# binlog 文件保留时间7天(默认0天)
expire_logs_days=7
# binlog 单个文件的最大值大小(默认1G)
max_binlog_size=512m
# 开启 binlog 后需要创建 function 或 procedure 时要开启
log_bin_trust_function_creators=1
# 服务id,以区分主库和备库
server-id=1
-- 显示是否开启 binlog
show variables like 'log_bin%';
-- 显示 binlog 文件格式
show variables like 'binlog_format%';
-- 显示 binlog 文件保留时间
show variables like 'expire_logs_days%';
-- 显示 binlog 单个文件的最大值大小
show variables like 'max_binlog_size%';
-- 显示 binlog 事件
show binlog events;
-- 显示全部 binlog 文件列表
show binary logs;
show master logs;
-- 显示最新 binlog 文件编号以及最后一个操作事件结束点(Position)值
show master status;
-- 结束当前 binlog 文件并生成新的 binlog 文件
flush logs;
-- 重置 binlog 文件(清空全部 biglog 文件)
reset master;

注: binlog 默认存放在 /var/lib/mysql/ 数据库文件目录。

mysqlbinlog

  • 查看 Linux 环境下 mysqlbinlog 目录
# /usr/bin/mysqlbinlog
whereis mysqlbinlog
  • 将 mysqlbinlog 文件复制到容器内的 /usr/bin 目录
docker cp mysqlbinlog mysql:/usr/bin
# 进入容器内
docker exec -it mysql /bin/bash
# 在容器内为 mysqlbinlog 添加权限
chmod +x /usr/bin/mysqlbinlog
  • 使用 mysqlbinlog 生成 sql 文件
# 进入容器内执行
mysqlbinlog --no-defaults \
--base64-output=DECODE-ROWS \
-v /var/lib/mysql/mysql-bin.000001 >/tmp/binlog_000001.sql

在这里插入图片描述

# 进入容器内执行
mysqlbinlog --no-defaults \
--base64-output=DECODE-ROWS \
--database=db_name \
--start-datetime='2024-06-20 00:00:00' \
--stop-datetime='2024-06-20 17:00:00' \
-v /var/lib/mysql/mysql-bin.000001 >/tmp/binlog_000001.sql

安装 MyFlash

注: 文章 MyFlash 是在 Linux 宿主机上安装。

  • 安装依赖
# 安装 git gcc glib-2.0
yum install -y git gcc glib2 libgnomeui-devel
# 验证是否安装成功
pkg-config --modversion glib-2.0
  • 安装MyFlash
# 下载源码
git clone https://github.com/Meituan-Dianping/MyFlash.git
# 或者国内镜像
git clone https://gitee.com/wufengsheng/MyFlash.git
cd MyFlash
# 动态编译链接安装
gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
  • 配置环境变量
vim /etc/profile
# 在文件末尾添加
alias flashback=~/MyFlash/binary/flashback
source /etc/profile
  • 验证是否安装成功
cd ~/MyFlash/binary
./flashback --help

flashback 选项

选项说明
–databaseNamesdatabaseName to apply. if multiple, seperate by comma(,)
–tableNamestableName to apply. if multiple, seperate by comma(,)
–tableNames-filetableName to apply. if multiple, seperate by comma(,)
–start-positionstart position
–stop-positionstop position
–start-datetimestart time (format %Y-%m-%d %H:%M:%S)
–stop-datetimestop time (format %Y-%m-%d %H:%M:%S)
–sqlTypessql type to filter . support INSERT, UPDATE ,DELETE. if multiple, seperate by comma(,)
–maxSplitSizemax file size after split, the uint is M
–binlogFileNamesbinlog files to process. if multiple, seperate by comma(,)
–outBinlogFileNameBaseoutput binlog file name base
–logLevellog level, available option is debug,warning,error
–include-gtidsgtids to process. if multiple, seperate by comma(,)
–include-gtids-filegtids to process. if multiple, seperate by comma(,)
–exclude-gtidsgtids to skip. if multiple, seperate by comma(,)
–exclude-gtids-filegtids to skip. if multiple, seperate by comma(,)

生成回滚文件

# 进入MyFlash的bin目录
cd ~/MyFlash/binary
# 生成回滚文件,执行后生成 binlog_output_base.flashback 文件
./flashback --sqlTypes='INSERT' \
--databaseNames=db_name \
--tableNames=table_name \
--start-datetime='2024-06-20 18:23:00' \
--binlogFileNames=/var/lib/mysql/mysql-bin.000001 \
--outBinlogFileNameBase=/var/lib/mysql/binlog_output_base

执行回滚操作

# 在binlog_output_base.flashback所在目录下执行以下命令
mysqlbinlog --no-defaults binlog_output_base.flashback | mysql -h 127.0.0.1 -uroot -p
# 或
mysqlbinlog --no-defaults binlog_output_base.flashback | mysql -uroot -p
# 输入数据库密码

操作示例

注: 容器内 /var/lib/mysql/ 映射到宿主机目录 /u01/mysql/data/

注: 例子中我们在时间 2024-06-21 09:39:00时,操作 DELETE 删除 lkmdbs 库中的 app_version 表中的数据,现在想恢复被删除的数据。

# 生成回滚文件
./flashback --sqlTypes='DELETE' \
--databaseNames=lkmdbs \
--tableNames=app_version \
--start-datetime='2024-06-21 09:38:00' \
--binlogFileNames=/u01/mysql/data/mysql-bin.000001 \
--outBinlogFileNameBase=/u01/mysql/data/binlog_000001
# 进入 mysql 容器
docker exec -it mysql /bin/bash
# 执行回滚操作,需要输入数据库 root 密码
mysqlbinlog --no-defaults binlog_000001.flashback | mysql -uroot -p

在这里插入图片描述

  • 回滚操作

在这里插入图片描述

注: 输入数据库 root 密码回车,没有报错说明回滚成功;数据库 lkmdbs 中的 app_version 表中被删除数据已回滚至2024-06-21 09:38:00时间点。

  • 如果想回滚整个库到某个时间点,可以参考以下脚本。

注意: 要根据数据库当前最新 binlog 文件编号恢复

# 生成回滚文件
./flashback --sqlTypes='INSERT,UPDATE,DELETE' \
--databaseNames=lkmdbs \
--start-datetime='2024-06-21 09:38:00' \
--binlogFileNames=/u01/mysql/data/mysql-bin.000001 \
--outBinlogFileNameBase=/u01/mysql/data/binlog_000001

Docker 部署 MySQL 数据库

  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逢生博客

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值