【BUG 记录】史诗级 BUG - MYSQL 删库删表却没有备份如何恢复数据

【BUG 记录】史诗级 BUG - MYSQL 删库删表却没有备份如何恢复数据

  • 1. 问题描述
  • 2. 解决方案(binlog)
    • 2.1 构造测试环境
    • 2.2 查看 MySQL 环境是否开启 binlog
    • 2.3 查看所有的 binlog 日志记录
    • 2.4 查看当前正在使用的是哪一个 binlog 文件
    • 2.5 查看此时的 binlog 日志记录
    • 2.6 删除记录(这里模拟删除表操作)
    • 2.7 mysqlbinlog 恢复数据
    • 2.8 binlog2sql 数据回滚
  • 3. binlog2sql 详细介绍
    • 3.1 概念
    • 3.2 安装 binlog2sql
    • 3.3 更改mysql配置文件
    • 3.4 运行脚本获取数据库里的内容
    • 3.5 删除数据
    • 3.6 回滚数据

在这里插入图片描述

1. 问题描述


  在实际开发过程中,不小心把测试环境的三张业务表(usercomanyuser_dept_rel)数据删除了,并且当时没有备份这三张表的数据,导致测试环境瘫痪,其中最关键的user表给删了,导致很多测试账号登录不上系统,搞了一下午,最终通过binlog日志 恢复了数据。在此记录一下当时的解决过程。

环境:Python 3.11
mysql:8.0+

2. 解决方案(binlog)

2.1 构造测试环境


  1. 库(test

  2. 建表(usercompanyuser_dept_rel),面下测试中主要使用user表来演示

    create table user(id int AUTO_INCREMENT primary key,name varchar(50),phone varchar(50)
    );insert into user(id,name,phone) value(1,"zhangsan",17756566565);
    insert into user(id,name,phone) value(2,"lisi",17712345687);
    insert into user(id,name,phone) value(3,"wangwu",17756562333);
    insert into user(id,name,phone) value(4,"zhaoliu",17756564444);create table company(id int AUTO_INCREMENT primary key,name varchar(50),code varchar(50)
    );insert into company(id,name,code) value(1,"测试公司1","ceshigongsi1");
    insert into company(id,name,code) value(2,"测试公司2","ceshigongsi2");
    insert into company(id,name,code) value(3,"测试公司3","ceshigongsi3");
    insert into company(id,name,code) value(4,"测试公司4","ceshigongsi4");create table user_dept_rel(id int AUTO_INCREMENT primary key,user_id int,dept_id int
    );insert into user_dept_rel(id,user_id,dept_id) value(1,111,1001);
    insert into user_dept_rel(id,user_id,dept_id) value(2,222,1002);
    insert into user_dept_rel(id,user_id,dept_id) value(3,333,1003);
    insert into user_dept_rel(id,user_id,dept_id) value(4,444,1004);
    
  3. 查看数据
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

2.2 查看 MySQL 环境是否开启 binlog


  通过命令查看是否开启 binlog 记录功能(该功能,默认是开启的)

show variables like '%log_bin%';

在这里插入图片描述

2.3 查看所有的 binlog 日志记录


  1. 命令
    show binary logs;
    
  2. 结果
    在这里插入图片描述

2.4 查看当前正在使用的是哪一个 binlog 文件


  1. 命令
    -- 查看当前的 binlog 文件
    show master status;
    
  2. 结果
    在这里插入图片描述
    当使用的是MYSQL-bin.000042这个日志文件,在前面 binlog 日志文件路径 (我的是D:\Settings\MySQL\DATA\Data )下查看
    在这里插入图片描述

2.5 查看此时的 binlog 日志记录


  1. 命令

    show binlog events in 'MYSQL-bin.000042';
    
  2. 结果

    在这里插入图片描述

2.6 删除记录(这里模拟删除表操作)


  1. 删除
    delete from test.user;
    delete from test.company;
    delete from test.user_dept_rel;
    
  2. 查看日志
    在这里插入图片描述
    可以看到我们三个删除事件,注意binlog 中每个事件都有一个 begincommit,我们后面进行恢复或回滚的时候开始和结束的 pos 都是取的事件整体的开始点和结束点。比如上面第一个删除事件的开始点(Pos)其实是7868,结束点(End_log_pos)则是8167

2.7 mysqlbinlog 恢复数据


注意: 这里是恢复数据,不是回滚数据

  • 恢复的本质:将原有的插入语句再执行一遍
  • 回滚的本质:回退到删除之前的状态

  mysqlbinlogmysql自带的命令,一般是在mysql安装目录下的bin目录里。因为我们是恢复数据,所以要找到已经删除语句的对应写入事件,将该事件再重新执行一遍即可

  1. 通过命令确认插入语句的事件位置

    show binlog events in 'MYSQL-bin.000042';
    

    在这里插入图片描述
    确定了 user 表的插入事件起始位置是3677 ,结果位置是4819

  2. 使用 mysqlbinlog 命令恢复

    D:\Settings\MySQL\DATA\Data>mysqlbinlog.exe --start-position=3677 --stop-position=4819 mysql-bin.000042 | mysql -uroot -p123456
    

    常用参数解释
    D:\Settings\MySQL\DATA\Data> : mysqlbinlog 的路径,就上面通过语句查出来的日志路径
    --start-position:起始位置
    --stop-position:结束位置
    --start-datetime:起始日期
    --stop-datetime:结束日期
    mysql-bin.000042:日志文件

  3. 查看结果
    在这里插入图片描述

    • 查看表:在这里插入图片描述
      可以看到数据已经回来了

    • 查看 binlog 日志:
      在这里插入图片描述
      可以看出,日志中也多了四条写入事件。这里只恢复了user表,companyuser_dept 同理

注意如果说找不到 insert 语句了,或者insert 语句 在很久之前执行的,找不到,我们可以通过在日志中找出它的 delete 语句,然后手动将 delete from 语句转换成 insert 语句(可以写一个python 脚本),重新执行一下就可以了。(我当时就是这么干的)

小结

  • mysqlbinlog命令只是用于恢复,不能用于回滚。如果数据进行update操作,则很难通过该命令恢复。所以该命令比较适用一些数据迁移,数据同步的场景。

  • mysqlbinlog 运行过程中如果出现unknown variable 'default-character-set=utf8mb4'异常,可以再该命令后加--no-defaults参数解决:mysqlbinlog --no-defaults

2.8 binlog2sql 数据回滚


  binlog2sql是一个第三方的工具,binlog2sql回滚的原理是生成要回滚事件对应的sql语句,我们最后只需要拷贝该语句实现即可。

3. binlog2sql 详细介绍

3.1 概念


  binlog2sql是一个用于解析二进制日志的开源工具。它具有从二进制日志中提取原始 SQL 语句的功能。它具有从二进制日志生成回滚 SQL 以进行时间点恢复的功能。

3.2 安装 binlog2sql


前提条件:安装这个工具,需要电脑具备python环境,如果没有还请自行安装python 3.11 (这块我的python版本是3.11)

cd D:\Workspace\PyCharm\
git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
pip install -r requirements.txt

3.3 更改mysql配置文件


  在 my.ini 中添加,找到log-bin="MYSQL-bin",然后在下一行添加

log-bin
server_id = 1
binlog_format = row
binlog_row_image = full

在这里插入图片描述

~修改完之后重启 mysql 服务

3.4 运行脚本获取数据库里的内容


D:\Workspace\PyCharm\binlog2sql>cd binlog2sql
D:\Workspace\PyCharm\binlog2sql\binlog2sql>python binlog2sql.py -uroot -p123456 -P3306 -d test -t user --start-file=D:\Settings\MySQL\DATA\Data\  --stop-file=MYSQL-bin.000042
Traceback (most recent call last):File "D:\Workspace\PyCharm\binlog2sql\binlog2sql\binlog2sql.py", line 145, in <module>binlog2sql = Binlog2sql(connection_settings=conn_setting, start_file=args.start_file, start_pos=args.start_pos,^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Workspace\PyCharm\binlog2sql\binlog2sql\binlog2sql.py", line 46, in __init__self.connection = pymysql.connect(**self.conn_setting)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Settings\Python\Python311\Lib\site-packages\pymysql\__init__.py", line 90, in Connectreturn Connection(*args, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Settings\Python\Python311\Lib\site-packages\pymysql\connections.py", line 706, in __init__self.connect()File "D:\Settings\Python\Python311\Lib\site-packages\pymysql\connections.py", line 931, in connectself._get_server_information()File "D:\Settings\Python\Python311\Lib\site-packages\pymysql\connections.py", line 1269, in _get_server_informationself.server_charset = charset_by_id(lang).name^^^^^^^^^^^^^^^^^^^File "D:\Settings\Python\Python311\Lib\site-packages\pymysql\charset.py", line 38, in by_idreturn self._by_id[id]~~~~~~~~~~~^^^^
KeyError: 255

  如果出现以上报错,更新PyMySQL 即可解决,mysql8的版本问题,安装对应的binlog2sql工具版本

pip uninstall PyMySQL
pip install PyMySQL==0.9.3

再次运行

D:\Workspace\PyCharm\binlog2sql\binlog2sql>python binlog2sql.py -uroot -p123456 -P3306 -d test -t user --start-file=MYSQL-bin.000042  --stop-file=MYSQL-bin.000042
D:\Settings\Python\Python311\Lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 1")result = self._query(query)
USE b'test';
create table t1 (title varchar(100) default null,price int not null) engine=innodb;
USE b'test';
create table user(id int AUTO_INCREMENT primary key,name varchar(50),phone varchar(50)
);
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (1, 'zhangsan', '17756566565'); #start 3598 end 3874 time 2024-02-26 10:55:04
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (2, 'lisi', '17712345687'); #start 3905 end 4177 time 2024-02-26 10:55:04
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (3, 'wangwu', '17756562333'); #start 4208 end 4482 time 2024-02-26 10:55:04
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (4, 'zhaoliu', '17756564444'); #start 4513 end 4788 time 2024-02-26 10:55:04
USE b'test';
create table company(id int AUTO_INCREMENT primary key,name varchar(50),code varchar(50)
);
USE b'test';
create table user_dept_rel(id int AUTO_INCREMENT primary key,user_id int,dept_id int
);
DELETE FROM `test`.`user` WHERE `id`=1 AND `name`='zhangsan' AND `phone`='17756566565' LIMIT 1; #start 7789 end 8136 time 2024-02-26 11:39:35
DELETE FROM `test`.`user` WHERE `id`=2 AND `name`='lisi' AND `phone`='17712345687' LIMIT 1; #start 7789 end 8136 time 2024-02-26 11:39:35
DELETE FROM `test`.`user` WHERE `id`=3 AND `name`='wangwu' AND `phone`='17756562333' LIMIT 1; #start 7789 end 8136 time 2024-02-26 11:39:35
DELETE FROM `test`.`user` WHERE `id`=4 AND `name`='zhaoliu' AND `phone`='17756564444' LIMIT 1; #start 7789 end 8136 time 2024-02-26 11:39:35
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (1, 'zhangsan', '17756566565'); #start 9210 end 9497 time 2024-02-26 10:55:04
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (2, 'lisi', '17712345687'); #start 9528 end 9807 time 2024-02-26 10:55:04
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (3, 'wangwu', '17756562333'); #start 9838 end 10119 time 2024-02-26 10:55:04
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (4, 'zhaoliu', '17756564444'); #start 10150 end 10432 time 2024-02-26 10:55:04

从以上内容能看出来我们刚才所执行的语句,该命令只是将二进制文件解析成我们可读的sql文件。

常用参数解释

-h 主机
-P 端口 
-u 用户名
-p 密码
-d 指定库名
-t 指定表--start-file   起始解析文件,只需文件名,无需全路径
--start-datetime 起始解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。
--stop-datetime 终止解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。--only-dml 只解析dml,忽略ddl。可选。默认False。
--sql-type 只解析指定类型,支持INSERT, UPDATE, DELETE。多个类型用空格隔开,如--sql-type INSERT DELETE。可选。默认为增删改都解析。用了此参数但没填任何类型,则三者都不解析。

其他参数大家可以自己网上搜索

3.5 删除数据


  由于我们刚才重启了mysql服务,所以当前的binlog日志文件变了
在这里插入图片描述
  现在日志文件是MYSQL-bin.000044

  我们删除数据(这块只删除user表)

delete from user;

  查看日志文件,会多一条delete事件

在这里插入图片描述

3.6 回滚数据


  添加参数 --flashback,生成rollback语句

# 这是没有--flashback 的执行结果,将delete from 语句打印出来
D:\Settings\Python\Python311\Lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 1")result = self._query(query)
DELETE FROM `test`.`user` WHERE `id`=1 AND `name`='zhangsan' AND `phone`='17756566565' LIMIT 1; #start 4 end 504 time 2024-02-26 14:22:35
DELETE FROM `test`.`user` WHERE `id`=2 AND `name`='lisi' AND `phone`='17712345687' LIMIT 1; #start 4 end 504 time 2024-02-26 14:22:35
DELETE FROM `test`.`user` WHERE `id`=3 AND `name`='wangwu' AND `phone`='17756562333' LIMIT 1; #start 4 end 504 time 2024-02-26 14:22:35
DELETE FROM `test`.`user` WHERE `id`=4 AND `name`='zhaoliu' AND `phone`='17756564444' LIMIT 1; #start 4 end 504 time 2024-02-26 14:22:35# 这是添加--flashback 的执行结果,将delete from 语句转换成了insert into 语句 打印出来
D:\Workspace\PyCharm\binlog2sql\binlog2sql>python binlog2sql.py -uroot -p123456 -P3306 -d test -t user --start-file=MYSQL-bin.000044 --flashback
D:\Settings\Python\Python311\Lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 1")result = self._query(query)
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (4, 'zhaoliu', '17756564444'); #start 4 end 504 time 2024-02-26 14:22:35
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (3, 'wangwu', '17756562333'); #start 4 end 504 time 2024-02-26 14:22:35
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (2, 'lisi', '17712345687'); #start 4 end 504 time 2024-02-26 14:22:35
INSERT INTO `test`.`user`(`id`, `name`, `phone`) VALUES (1, 'zhangsan', '17756566565'); #start 4 end 504 time 2024-02-26 14:22:35

  我们复制insert into 语句执行就可以了!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2814663.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

springboot整合websocket,入门学习

websocket 1.简介2.常见的消息推送方式2.1轮询方式2.1.1短轮询2.1.2长轮询 2.2 SSE(server-sent event):服务器发送事件2.3 websocket 3.原理解析4.websocket API4.1客户端&#xff08;浏览器&#xff09;API4.2服务端API 5.实现1.流程分析2.消息格式3.代码实现 1.简介 websoc…

如何用好应用权限,保护隐私数据?银河麒麟桌面操作系统V10 SP1 2303 update2新功能解析

为您介绍银河麒麟桌面操作系统V10 SP1 2303 update2隐私设置和权限管理功能&#xff0c;为您的个人数据安全保驾护航。 说到个人数据隐私&#xff0c;在科技重塑生活本质的数字世界&#xff0c;个人信息遭受持续威胁。2018年&#xff0c;某国际知名社交平台因安全系统漏洞而遭…

OpenAI划时代大模型——文本生成视频模型Sora作品欣赏(八)

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…

docker 容器修改端口和目录映射

容器修改端口映射 一般在运行容器时&#xff0c;我们都会通过参数 -p&#xff08;使用大写的-P参数则会随机选择宿主机的一个端口进行映射&#xff09;来指定宿主机和容器端口的映射&#xff0c;例如 docker run -it -d --name [container-name] -p 8088:80 [image-name]这里…

数据结构:循环队列

一、队列的概念 操作受限的线性表&#xff0c;允许在队列的一端执行入队操作&#xff0c;另一端执行出队操作 先进先出(FIFO) 1.顺序队列 物理结构连续&#xff0c;依赖于数组实现 队列中有一个队头指针和队尾指针&#xff0c;队头指针保存每次要出队的元素&#xff0c;队…

网站三合一缩略图片介绍展示源码

网站三合一缩略图片介绍展示源码&#xff0c;PHP源码&#xff0c;运行需要php环境支持&#xff0c;效果截图如下 蓝奏云下载&#xff1a;https://wfr.lanzout.com/ihY8y1pgim6j

Springboot+vue的考务报名平台(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的考务报名平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的考务报名平台&#xff0c;采用M&#xff08;model&#xff0…

新加坡服务器托管:开启全球化发展之门

新加坡作为一个小国家&#xff0c;却在全球范围内享有极高的声誉。新加坡作为亚洲的科技中心&#xff0c;拥有先进的通信基础设施和成熟的机房托管市场。除了其独特的地理位置和发达的经济体系外&#xff0c;新加坡还以其开放的商业环境和便利的托管服务吸引着越来越多的国际公…

Python手册(Machine Learning)--LightGBM

Overview LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一种高效的 Gradient Boosting 算法&#xff0c; 主要用于解决GBDT在海量数据中遇到的问题&#xff0c;以便更好更快的用于工业实践中。 数据结构说明lightgbm.DatasetLightGBM数据集lightgbm.Bo…

【前端素材】推荐优质后台管理系统Salreo平台模板(附源码)

一、需求分析 当我们从多个层次来详细分析后台管理系统时&#xff0c;可以将其功能和定义进一步细分&#xff0c;以便更好地理解其在不同方面的作用和实际运作。 1. 结构层次 在结构层次上&#xff0c;后台管理系统可以分为以下几个部分&#xff1a; a. 辅助功能模块&#…

项目分享|基于ELF 1开发板的车牌识别系统

该项目选用ElfBoard ELF 1开发板作为核心硬件平台&#xff0c;利用USB接口连接的摄像头捕捉并识别车牌信息。一旦车牌成功识别&#xff0c;系统会触发绿灯指示&#xff0c;并将识别所得的车牌号码实时传输至手机APP。车牌识别技术方面&#xff0c;借助了百度提供的OCR&#xff…

Java+SpringBoot+Vue+MySQL:狱内罪犯危险性评估系统全栈开发

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

postman访问k8s api

第一种方式&#xff1a; kubectl -n kubesphere-system get sa kubesphere -oyaml apiVersion: v1 kind: ServiceAccount metadata:annotations:meta.helm.sh/release-name: ks-coremeta.helm.sh/release-namespace: kubesphere-systemcreationTimestamp: "2023-07-24T07…

vue2后台管理系统demo,包含增删查改、模糊搜索、分页

因一直敲小程序&#xff0c;vue不熟练&#xff0c;自己练手项目&#xff0c;就包含增删查改以及模糊搜索分页 一、页面简单但功能齐全 二、数据是mock模拟 三、启动步骤 1、 json-server --watch data.json 启动mock数据 2、npm i 下载依赖 3、npm run serve 四、github地址…

最新IE跳转Edge浏览器解决办法(2024.2.26)

最新IE跳转Edge浏览器解决办法&#xff08;2024.2.26&#xff09; 1. IE跳转原因1.1. 原先解决办法1.2. 最新解决办法1.3. 最后 1. IE跳转原因 关于IE跳转问题是由于在2023年2月14日&#xff0c;微软正式告别IE浏览器&#xff0c;导致很多使用Windows10系统的电脑在打开IE浏览…

PHP请求示例获取淘宝商品详情数据API接口(按关键词搜索商品列表)

请求示例&#xff0c;API接口接入Anzexi58 item_get-获得淘宝商品详情 taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥WeChat18305163218api_nameString是API接口名称&#xff08;包…

存储卡0字节危机:原因解析与数据拯救之道

存储卡0字节现象揭秘 在数字时代&#xff0c;存储卡作为我们存储重要数据的主要工具之一&#xff0c;一旦遭遇“0字节”的困境&#xff0c;无疑是一场数据灾难。所谓存储卡0字节&#xff0c;即存储卡的文件系统显示容量为0&#xff0c;所有文件仿佛凭空消失&#xff0c;用户无…

Ubuntu服务器fail2ban的使用

作用&#xff1a;限制ssh远程登录&#xff0c;防止被人爆破服务器&#xff0c;封禁登录ip 使用lastb命令可查看到登录失败的用户及ip&#xff0c;无时无刻的不在爆破服务器 目录 一、安装fail2ban 二&#xff0c;配置fail2ban封禁ip的规则 1&#xff0c;进入目录并创建ssh…

在TMP中计算书名号《》高度的问题

1&#xff09;在TMP中计算书名号《》高度的问题 2&#xff09;FMOD设置中关于Virtual Channel Count&Real Channel Count的参数疑问 3&#xff09;Unity 2021.3.18f1 ParticleSystemTrailGeometryJob粒子拖尾系统崩溃 4&#xff09;XLua打包Lua文件粒度问题 这是第375篇UWA…

Simulink搭建一阶低通数字滤波器(设定X(n)为非0起始值)

一、一阶低通数字滤波器原理 一阶滤波&#xff0c;亦称一阶惯性滤波或一阶低通滤波。其数学表达式如下&#xff1a; 其中&#xff1a;α代表滤波系数&#xff1b;X(n)表示本次采样值&#xff1b;Y(n-1) 为上次滤波输出值&#xff1b;Y(n) 为本次滤波输出值。一阶低通滤波方法通…