一、前言

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

二、数据安全策略

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

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

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

三、数据恢复案例演示

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

准备测试数据

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命令进行数据备份。

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

image-20250926091246371.png

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

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

image-20250926092149918.png

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

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

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

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

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

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

将测试表的数据删除

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

delete from sys_post;

将sys_post表数据给清空了。

数据恢复

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

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

image-20250926094824021.png

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

mysqlbinlog --no-defaults -vv "C:ProgramDataMySQLMySQL Server 8.1DataCC-bin.000184"

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

image-20250926095703486.png

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

image-20250926100238393.png

mysqlbinlog  --no-defaults --start-position=157 --stop-position=560 "C:ProgramDataMySQLMySQL Server 8.1DataCC-bin.000184" > backup_inc.sql

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

参数解释:

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

image-20250926101601659.png

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

image-20250926100654797.png

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

总结

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

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]