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

news/发布时间2024/6/17 2:34:09

【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://www.bcls.cn/nKNd/9256.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

轻量级模型,重量级性能,TinyLlama、LiteLlama小模型火起来了,针对特定领域较小的语言模型是否与较大的模型同样有效?

轻量级模型&#xff0c;重量级性能&#xff0c;TinyLlama、LiteLlama小模型火起来了&#xff0c;针对特定领域较小的语言模型是否与较大的模型同样有效? 当大家都在研究大模型&#xff08;LLM&#xff09;参数规模达到百亿甚至千亿级别的同时&#xff0c;小巧且兼具高性能的小…

06 vim工具

目录 概念模式基本操作配置 1. 概念 vim是一个历史悠久的,多模式的编辑器&#xff0c;是vi的升级版。和ide不同&#xff0c;编辑器仅能编写文本&#xff0c;不能运行代码&#xff0c;现阶段的代码编译的各个过程会分开按步骤执行 2. 模式 vim有很多种模式&#xff0c;想要编…

【学习总结】什么是DoS和DDoS

[Q&A] 什么是DoS DoS 是 “Denial of Service”&#xff08;拒绝服务&#xff09;的缩写&#xff0c;它是一种网络攻击方式&#xff0c;其目的是使目标计算机或网络资源无法为合法用户提供正常的服务。通过向目标系统发送大量请求、消耗其带宽、处理器或内存等资源&#…

使用空闲电脑免费搭建一个私人的网盘

如果你也有一台空闲电脑&#xff0c;可以使用它来搭建一个私人的网盘。 这里使用的是飞梦云网盘&#xff1b; 服务端&#xff1a;下载 服务器文件使用hash校验进行储存&#xff0c;实现重复上传的文件秒传功能。 Fuse4Ui&#xff08;虚拟分区工具&#xff09;&#xff1a;下…

高性能API云原生网关 APISIX安装与配置指南

Apache APISIX是Apache软件基金会下的顶级项目&#xff0c;由API7.ai开发并捐赠。它是一个高性能的云原生API网关&#xff0c;具有动态、实时等特点。 APISIX网关可作为所有业务的流量入口&#xff0c;为用户提供了丰富的功能&#xff0c;包括动态路由、动态上游、动态证书、A…

18 SpringMVC实战

18 SpringMVC实战 1. 课程介绍2. Spring Task定时任务1. 课程介绍 2. Spring Task定时任务 package com.imooc.reader.task

BlackWidow靶场

kali&#xff1a;192.168.223.128 主机发现 nmap -sP 192.168.223.0/24 目标IP:192.168.223.153 端口扫描 nmap -sV -p- -A 192.168.223.153 22/tcp open ssh OpenSSH 7.9p1 Debian 10deb10u2 (protocol 2.0) 80/tcp open http Apache httpd 2.4.38 ((Deb…

Window系统禅道BUG管理系统安装配置并实现公网远程访问

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

[NPUCTF2020]ezinclude ---不会编程的崽

做完这题&#xff0c;又get到一个新的知识点。上界面 源代码里有线索 secret是秘密值&#xff0c;name与pass应该是可以控制的变量。抓个包看看 发送与请求有hash值&#xff0c;没猜错应该是用来验证的。拿去爆破了&#xff0c;啥也没爆破出来。先传参 右边的hash值改变了。猜想…

小苯的IDE括号问题(CD) -----牛客小白月赛87(双链表)

C题&#xff1a;C-小苯的IDE括号问题&#xff08;easy&#xff09;_牛客小白月赛87 (nowcoder.com) D题&#xff1a; D-小苯的IDE括号问题&#xff08;hard&#xff09;_牛客小白月赛87 (nowcoder.com) C题代码&#xff1a; #include<bits/stdc.h>using namespace std…

百度云AI

百度云AI概述 Face腾讯优图科大讯飞 百度人脸识别基于深度学习的人脸识别方案&#xff0c;准确识别图片中的人脸信息&#xff0c;提供如下功能&#xff1a; 人脸检测&#xff1a;精准定位图中人脸&#xff0c;获得眼、口、鼻等72个关键点位置&#xff0c;分析性别、年龄、表…

武器大师——操作符详解(上)

目录 一、操作符的分类 二、二进制和进制转换 2.1.二进制与十进制的互相转化 2.1.1 二进制转十进制 2.1.2 十进制转二进制 ​编辑 2.2.二进制转8进制和16进制 2.2.1 转8进制 2.2.2 转16进制 三、原码、反码、补码 四、移位操作符 4.1.左移操作符&#xff08;<…

#LLM入门|Prompt#2.2_ AI 应用开发的范式_Language_Models,the_Chat_Format_and_Tokens

在本章中&#xff0c;我们将和您分享大型语言模型&#xff08;LLM&#xff09;的工作原理、训练方式以及分词器&#xff08;tokenizer&#xff09;等细节对 LLM 输出的影响。 我们还将介绍 LLM 的提问范式&#xff08;chat format&#xff09;&#xff0c;这是一种指定系统消息…

F2图例封装 - Bar

基于vue3 和 F2 3.5.0 <template><div :style"{minHeight: ${height}px,width: 100% }" ref"container"><canvas v-show"showChart" :id"chartId" class"chart-canval"></canvas><empty-box v-…

容器镜像详解

1. 镜像组成 一个标准的OCI容器镜像由index, manifest, config, image layers这几个部分组成。 以docker镜像为例&#xff0c;下载的镜像文件保存在/var/lib/docker/目录下面 image/overlay2子目录下面保存着镜像相关的一些元数据 在下面的介绍主要以nginx:latest镜像为例子…

智能SQL生成:后端技术与LLM的完美结合

文章目录 引言一、什么是大模型二、为什么选择LLM三、开发技术说明四、系统架构说明五、编码实战1. Maven2. 讯飞大模型配置类3. LLM相关的封装4. 编写LLM的service5. 编写controller6. 运行测试 六、总结 引言 本篇文章主要是关于实现一个类似Chat2DB的根据自然语言生成SQL的…

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

面试题 为什么使用消息队列&#xff1f; 消息队列有什么优点和缺点&#xff1f; Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别&#xff0c;以及适合哪些场景&#xff1f; 面试官心理分析 其实面试官主要是想看看&#xff1a; 第一&#xff0c;你知不知道你们系统里为…

【MySQL】MySQL数据管理——DDL数据操作语言(数据表)

目录 创建数据表语法列类型字段属性SQL示例创建学生表 查看表和查看表的定义表类型设置表的类型 面试题&#xff1a;MyISAM和InnoDB的区别设置表的字符集删除表语法示例 修改表修改表名语法示例 添加字段语法示例 修改字段语法示例 删除字段语法示例 数据完整性实体完整性域完整…

2024国际元宇宙博览会:阿里元境以元宇宙数字内容助力文旅数字化发展

2月26日&#xff0c;MES2024国际元宇宙博览会在深圳会展中心正式开幕&#xff0c;大会以“向3D出发&#xff0c;元宇宙来袭&#xff0c;电竞娱乐正当时”为主题&#xff0c;聚焦元宇宙产业链&#xff0c;以“汇聚企业创新&#xff0c;助力产业重构&#xff0c;推动行业发展”为…

k8s 进阶实战笔记 | NFS 动态存储类的部署与使用

文章目录 NFS 动态存储类的部署与使用演示环境说明NFS subdir external provisioner准备 NFS 服务器手动部署 NFS Subdir External Provisioner部署 StorageClass验证使用更多信息 NFS 动态存储类的部署与使用 演示环境说明 演示环境信息&#xff1a;单机K3s 1.28.2 操作系统…
推荐文章