【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://www.rhkb.cn/news/267095.html

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

相关文章

Redis 之六:Redis 的哨兵模式(Sentinel)

Redis 哨兵&#xff08;Sentinel&#xff09;模式是一种高可用性解决方案&#xff0c;用于监控和自动故障转移的集群系统。 在 Redis Sentinel 架构中&#xff0c;哨兵是一组运行在特殊模式下的 Redis 进程&#xff0c;它们可以监控一个或多个主从复制结构中的 Redis 主服务器以…

第十五天-爬虫项目实战

目录 1.介绍 2.代码 1.main.py 2.PageSider.py 3.DetailSpider.py 4.DataParse.py 5.Constant.py 6.HanderRequest.py 1.介绍 1. 使用多线程爬取网站 2.爬取数据后保存至excel 3.爬取网站(仅做测试)网创类项目爬取&#xff1a;https://www.maomp.com/ 4..实现效果 …

修改docker默认存储位置【高版本的docker】

一、修改docker默认存储位置 1、停服务 systemctl stop docker 2、修改/etc/docker/daemon.json添加新的dcoker路径 如"data-root": "/mnt/hdd1/docker" 3、保存后重启服务&#xff1a;systemctl restart docker 二、其他服务的命令 systemctl disab…

基于centos的linux上docker安装,及mysql、redis等应用在docker容器中的安装

Docker环境安装 安装yum-utils&#xff1a; yum install ‐y yum‐utils device‐mapper‐persistent‐data lvm2为yum源添加docker仓库位置&#xff1a; yum‐config‐manager ‐‐add‐repo https://download.docker.com/linux/centos/docker‐ce.repo如果上面执行命令后…

hippy 调试demo运行联调-mac环境准备篇

适用对于终端编译环境不熟悉的人看&#xff0c;仅mac端 hippy 调试文档官网地址 前提&#xff1a;请使用node16 联调预览效果图&#xff1a; 编译iOS Demo环境准备 未跑通&#xff0c;待补充 编译Android Demo环境准备 1、正常安装Android Studio 2、下载Android NDK&a…

群控代理IP搭建教程:打造一流的网络爬虫

目录 前言 一、什么是群控代理IP&#xff1f; 二、搭建群控代理IP的步骤 1. 获取代理IP资源 2. 配置代理IP池 3. 选择代理IP策略 4. 编写代理IP设置代码 5. 异常处理 三、总结 前言 群控代理IP是一种常用于网络爬虫的技术&#xff0c;通过使用多个代理IP实现并发请求…

力扣SQL50 产品销售分析 I 查询

Problem: 1068. 产品销售分析 I 思路 left join on&#xff1a;左连接 Code select p.product_name, s.year, s.price from Sales s left join Product p on s.product_id p.product_id

力扣SQL50 无效的推文 查询

Problem: 1683. 无效的推文 思路 &#x1f468;‍&#x1f3eb; 参考 char_length(str)&#xff1a;计算 str 的字符长度length(str)&#xff1a;计算 str 的字节长度 Code select tweet_id from Tweets where char_length(content) > 15;

【Vue】更换浏览器默认 logo

更换浏览器默认logo为自定义图片 一. 浏览器默认 logo二. 替换为自定义logo三. 步骤3.1 转换大小3.1.1 查看图片尺寸3.1.2 修改尺寸&#xff08;为32px 32px&#xff09; 3.2 替换成功 一. 浏览器默认 logo 二. 替换为自定义logo 三. 步骤 3.1 转换大小 将自定义 logo 转为323…

二叉搜索树在线OJ题讲解

二叉树创建字符串 我们首先进行题目的解读&#xff1a; 大概意思就是用&#xff08;&#xff09;把每个节点的值给括起来&#xff0c;然后再经过一系列的省略的来得到最后的结果 大家仔细观察题目给出的列子就可以发现&#xff0c;其实这个题目可以大致分为三种情况&#xff1…

贝叶斯定理与条件独立假设:朴素贝叶斯分类方法深度解读

今天给大家分享的是朴素贝叶斯算法&#xff0c;这个算法在实际使用中不是很多&#xff0c;因为现在很多算法已经发展的很好&#xff0c;性能上也比朴素贝叶斯算法的好很多&#xff0c;因此在实际中我们其实看到在实际应用中朴素贝叶斯算法的使用已经比较少&#xff0c;即使出现…

高级语言期末2008级A卷(计算机学院)

1.编bool型函数&#xff0c;判断二维空间中的某点是否优于另一点。优于关系定义为&#xff1a;在二维空间中&#xff0c;某点&#xff08;A1&#xff0c;A2&#xff09;优于&#xff08;B1&#xff0c;B2&#xff09;&#xff0c;当且仅当A1>B1,A2>B2 #include <stdi…

【C++进阶】哈希(万字详解)—— 学习篇(上)

&#x1f387;C学习历程&#xff1a;入门 博客主页&#xff1a;一起去看日落吗持续分享博主的C学习历程博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 也许你现在做的事情&#xff0c;暂时看不到成果&#xff0c;但不要忘记&…

Tomcat部署Web服务器及基础功能配置

前言 Tomcat作为一款网站服务器&#xff0c;目前市面上Java程序使用的比较多&#xff0c;作为运维工人&#xff0c;有必要了解一款如何去运行Java环境的网站服务。 目录 一、Java相关介绍 1. Java历史 2. Java跨平台服务 3. Java实现动态网页功能 3.1 servelt 3.2 jsp …

python统计分析——广义线性模型的评估

参考资料&#xff1a;用python动手学统计学 残差是表现数据与模型不契合的程度的重要指标。 1、导入库 # 导入库 # 用于数值计算的库 import numpy as np import pandas as pd import scipy as sp from scipy import stats # 导入绘图的库 import matplotlib.pyplot as plt i…

AcWing 466. 回文日期

先贴个题目&#xff1a; 以及原题链接&#xff1a;466. 回文日期 - AcWing题库https://www.acwing.com/problem/content/468/ 这题乍一看有点恶心&#xff0c;如果枚举日期还要判断合法性&#xff0c;然后每个日期再判断是不是回文&#xff0c;即麻烦&#xff0c;时间复杂度又高…

day07_分类管理EasyExcel品牌管理

文章目录 1 分类管理1.1 菜单添加1.2 表结构介绍1.3 页面制作1.4 列表查询1.4.1 需求分析1.4.2 后端接口CategoryCategoryControllerCategoryServiceCategoryMapperCategoryMapper.xml 1.4.3 前端对接category.jscategory.vue 2 EasyExcel2.1 数据导入导出意义2.2 EasyExcel简介…

本地maven库缓存导入私库

为了加速编译代码&#xff0c;想将本地maven缓存导入内网私库使用。 脚本网上搜的 #!/bin/bash # copy and run this script to the root of the repository directory containing files # this script attempts to exclude uploading itself explicitly so the script name …

物体检测-系列教程19:YOLOV5 源码解析9 (Focus模块、Model类构造函数)

&#x1f60e;&#x1f60e;&#x1f60e;物体检测-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 13、Focus模块 13.1 基本流程 原始输入图像的格式为&#xff1a;tensor: float32[1,3,64…

Unity(第十八部)物理力学,碰撞,触发、关节和材质

1、重力 刚体组件 英文中文描述RigidBody刚体组件physics->rigidbody &#xff0c;刚体组件使一个物体有了质量&#xff0c;重力等。&#xff0c;use gravity 勾选后&#xff0c;物体才会受到重力&#xff0c;会自动下落&#xff0c;取消勾选就不会。&#xff0c;&#xf…