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

一、前言

在平时工作中,小伙伴们有没有手抖误执行过没有带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更应该认真去检查,以免出错,防患于未然。

相关推荐
倚栏听风雨1 分钟前
【ES避坑指南】明明存的是 "CodingAddress",为什么 term 查询死活查不到?彻底搞懂 text 和 keyword
后端
程序员爱钓鱼3 分钟前
Go 操作 Windows COM 自动化实战:深入解析 go-ole
后端·go·排序算法
回家路上绕了弯17 分钟前
深入解析Agent Subagent架构:原理、协同逻辑与实战落地指南
分布式·后端
子玖31 分钟前
实现微信扫码注册登录-基于参数二维码
后端·微信·go
IT_陈寒34 分钟前
JavaScript代码效率提升50%?这5个优化技巧你必须知道!
前端·人工智能·后端
IT_陈寒36 分钟前
Java开发必知的5个性能优化黑科技,提升50%效率不是梦!
前端·人工智能·后端
东风t西瓜1 小时前
飞书项目与多维表格双向同步
后端
狼爷1 小时前
Go 没有 override?别硬套继承!用接口+嵌入,写更清爽的“覆盖”逻辑
java·go
初次攀爬者1 小时前
Kafka的Rebalance基础介绍
后端·kafka
ServBay1 小时前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php