数据误删了咋办?别怕,今天来教你如何恢复数据

一、前言

在平时工作中,小伙伴们有没有手抖误执行过没有带where条件的delete语句或者update语句?这种语句会导致大量的数据被删除或者更新,这个时候小伙伴们会不会很慌,不知道怎么办?今天就来教你如何恢复数据。

二、数据安全策略

为了保证数据库中数据的安全性,我们公司的DBA(数据库管理员)一般会对数据库做下面这两个操作:

  • 定期对数据库进行备份:这个操作可能是一天一次,也可能是一周一次。
  • 开启binlog日志:这个binlog日志非常有用,比如主库和从库之间数据的同步,就是通过这个日志来实现的,我们也可以拿这个日志来做数据恢复。
sql 复制代码
SHOW VARIABLES LIKE 'log_bin';

我们可以通过上面的命令查看是否开启binlog日志,ON代表已经开启。

三、数据恢复案例演示

(声明:该案例是在windows系统上完成的)

准备测试数据

sql 复制代码
create table sys_post
(
    id          bigint auto_increment comment '岗位ID'
        primary key,
    post_code   varchar(64)                            not null comment '岗位编码',
    name        varchar(50)  default ''                not null comment '岗位名称',
    description varchar(255) default ''                not null comment '描述',
    status      tinyint(1)   default 1                 not null comment '状态(1正常 0停用)',
    create_time timestamp    default *CURRENT_TIMESTAMP* not null on update *CURRENT_TIMESTAMP*,
    update_time timestamp                              null on update *CURRENT_TIMESTAMP*,
    is_deleted  tinyint      default 0                 not null comment '删除标记(0:可用 1:已删除)'
)
    comment '岗位信息表' charset = utf8mb3;
INSERT INTO sys_post (id, post_code, name, description, status, create_time, update_time, is_deleted) VALUES (5, 'dsz', '董事长', '1', 1, '2022-05-24 10:33:53', null, 0);
INSERT INTO sys_post (id, post_code, name, description, status, create_time, update_time, is_deleted) VALUES (6, 'zjl', '总经理', '2', 1, '2022-05-24 10:34:08', null, 0);
INSERT INTO sys_post (id, post_code, name, description, status, create_time, update_time, is_deleted) VALUES (7, 'wz', '网咨', '', 1, '2022-05-27 08:56:41', '2022-05-27 08:56:41', 1);
INSERT INTO sys_post (id, post_code, name, description, status, create_time, update_time, is_deleted) VALUES (8, 'yyzj', '运营总监', '', 1, '2022-06-08 17:14:21', null, 0);

备份数据

因为我们的DBA会定期备份数据,所以我们这一步是模拟数据备份这个动作的,通过mysqldump命令进行数据备份。

sql 复制代码
mysqldump --single-transaction --flush-logs --source-data=2 --routines --opt -uroot -p guigu-auth > backup.sql

(注意:该命令是在操作系统的terminal终端执行的(非MySQL客户端),其中guigu-auth为测试库的名字)

验证备份文件:执行成功后,检查生成的backup.sql文件是否包含完整的数据库结构和数据,部分截图如下:

下面对上述命令的参数做一下说明:

--single-transaction:表示在备份过程中,使用单个事务来确保数据的一致性。

--flush-logs:表示在备份过程中,刷新日志文件,以便在备份完成后,日志文件中的内容不会影响到备份数据。

--source-data=2:表示在备份过程中,将主服务器的二进制日志位置信息也备份到文件中。这个参数比较重要,用于在恢复数据时找到位置信息。老版本叫做master-data

--routines:表示在备份过程中,备份存储过程和函数。

--opt:表示使用优化过的备份方式,以提高备份速度和减少备份文件的大小。

将测试表的数据删除

我们将表数据删除一下,方便后边做数据恢复的验证

sql 复制代码
delete from sys_post;

将sys_post表数据给清空了。

数据恢复

数据恢复的原理就是以定期备份文件为全量基础,加上binlog的增量数据,从而恢复数据到任何一秒。

我们首先需要从上面步骤中生成的备份文件中找到最后的binlog写入位置。

从上图可以得知,备份文件一直包含了**-bin.000184的157这个位置,也就是说增量恢复只需要从157这个位置开始即可。接着我们执行以下命令:

sql 复制代码
mysqlbinlog --no-defaults -vv "C:\ProgramData\MySQL\MySQL Server 8.1\Data\CC-bin.000184"

(注意:也是在windows的terminal终端执行)

从上图结果可以看到,这条删除命令对应的binlog执行的位置是从560到591。从157到560的这中间的数据就是增量的数据,将这些数据整理成增量sql:

sql 复制代码
mysqlbinlog  --no-defaults --start-position=157 --stop-position=560 "C:\ProgramData\MySQL\MySQL Server 8.1\Data\CC-bin.000184" > backup_inc.sql

执行完成后,服务器上已经有backup.sql和backup_inc.sql这两个文件。

参数解释:

  • --start-position=157‌:指定从二进制日志文件的157字节偏移量开始解析。
  • --stop-position=560‌:设定解析终止于560字节偏移量,与起始位置共同划定精确的操作范围。

接着我们通过执行脚本的方式,去执行一下backup.sql和backup_inc.sql这两个文件,执行完成后,再去查询数据:

发现数据已经恢复回来了。

总结

数据恢复是一个很值得我们认真去学习的技能,但是大家在日常工作中,对于需要执行的sql更应该认真去检查,以免出错,防患于未然。

相关推荐
zjjuejin2 小时前
Maven 最佳实践与性能优化
java·后端·maven
Mr.45672 小时前
Spring Boot 全局鉴权认证简单实现方案
spring boot·后端
泉城老铁2 小时前
Spring Boot和Vue.js项目中实现文件压缩下载功能
前端·spring boot·后端
卷Java3 小时前
WXML 编译错误修复总结
xml·java·前端·微信小程序·uni-app·webview
Yilena3 小时前
跟进 JDK25:将虚拟线程安全引入生产的权衡与实战
java·开发语言·虚拟线程·结构化并发·jdk25
_extraordinary_3 小时前
Java HTTP协议(二)--- HTTPS,Tomcat
java·http·https
钟离墨笺3 小时前
Go语言-->切片注意点及理解
java·开发语言·golang
麦麦鸡腿堡3 小时前
Java的数组查找
java·开发语言