写在前面:

在日常的 MySQL 数据库运维工作中,数据备份与恢复是一项至关重要的任务。为应对各种意外情况(如误删除、硬件故障、勒索病毒等),我们通常采用「全量 + 增量」的备份策略来保障数据安全。

本篇文章将围绕一种经典且实用的备份与恢复方案展开:使用 mysqldump 实现全量备份,结合 binlog(二进制日志)实现增量备份,并在实际场景中完成精准的数据恢复。

1. 实现过程

1. 修改配置文件

[mysql]
socket=/tmp/mysql.sock
[mysqld]
bind-address=0.0.0.0
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
## 服务唯一标识
server-id=10  
## 开启以 mysql_bin 为开头的binlog日志 比如mysql_binxxxxx001
log-bin=mysql_bin

2. 重启数据库

3. 查看配置文件是否生效

mysql> show variables like '%log_bin%';
---  
log_bin = ON   ## 标识开启了binlog日志
log_bin_basename  =  /data/3306/data/mysql_bin  ## binlog日志的位置
log_bin_index =  /data/3306/data/mysql_bin.index ## binlog 日志索引,可以查看logbin日志写在哪个文件中了

上面我们确认开启了binlog日志,下面我们讲模拟现场故障恢复

假设:某公司每天凌晨开启mysqldump 全量备份,平时开始增量备份,某员工白天操作修改了部分数据,同时不小心删除了数据,IT人员不小心删除了数据库,我们该怎么做出故障恢复呢?

4. 模拟开启mysqldump 全量备份

mysqldump -uroot -p --single-transaction --master-data=2 --flush-logs  -B backup > backup.sql

参数说明:

  • single-transaction:等价于在备份的时候给数据库的数据拍了照,备份的时候数据库可以继续更新

  • master-data=2:备份数据后,会在备份后的文件记录位置点信息

  • flush-logs:重新生成binlog日志

这里解释一下flush-logs的意义,这样我们在备份完后第二天的所有操作都会记录在新的日志上了,这样容易方便排查问题

5. 模拟操作

--- 原始数据
mysql> select * from act_id_user limit 5;
+-----+------+--------+-------+--------+------+-------------+
| ID_ | REV_ | FIRST_ | LAST_ | EMAIL_ | PWD_ | PICTURE_ID_ |
+-----+------+--------+-------+--------+------+-------------+
| 101 |    1 | 小王   |       |        |      | NULL        |
| 102 |    1 | 小张   |       |        |      | NULL        |
| 103 |    1 | 小邢   |       |        |      | NULL        |
| 104 |    1 | 小蔡   |       |        |      | NULL        |
| 105 |    1 | 小陈   |       |        |      | NULL        |
+-----+------+--------+-------+--------+------+-------------+
5 rows in set (0.00 sec)

--- 修改数据将104 改为小李
mysql> update act_id_user set FIRST_='小李' where ID_=104;

--- 将105 误数据删除
mysql> delete from act_id_user where ID_105;

--- 现在的数据
mysql> select * from act_id_user limit 5;
+-----+------+-----------+-------+--------+------+-------------+
| ID_ | REV_ | FIRST_    | LAST_ | EMAIL_ | PWD_ | PICTURE_ID_ |
+-----+------+-----------+-------+--------+------+-------------+
| 101 |    1 | 小王      |       |        |      | NULL        |
| 102 |    1 | 小张      |       |        |      | NULL        |
| 103 |    1 | 小邢      |       |        |      | NULL        |
| 104 |    1 | 小李      |       |        |      | NULL        |
| 106 |    1 | 舒銀小    |       |        |      | NULL        |
+-----+------+-----------+-------+--------+------+-------------+
5 rows in set (0.00 sec)
--- 突然误删除数据库
mysql> drop database backup;
Query OK, 23 rows affected (0.39 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

6. 恢复过程

--- 先切割日志,方便后续查询
mysqladmin -uroot -p flush-logs

--- 用全量备份恢复
## 创建被误删的数据库
mysql> create database backup;
mysql> source backup.sql;
## 这时候我们会发现只是恢复了备份后的数据,没有恢复操作后的数据

--- 用binlog日志恢复差异数据
## 查看所有binlog,并找到自己需要的binlog,其实就是刚切割binlog
mysql> show binary logs; 

--- 找到误操作后根据position恢复
mysqlbinlog --start-position=156  --stop-position=750  mysql_bin.000009 | mysql -uroot -p1

--- 查看数据后发现数据恢复
--- 或者可以根据大致时间来我们要恢复删除后的数据
mysqlbinlog --start-datetime="2025-07-16 15:49:44" --stop-datetime="2025-07-16 15:50:54"  mysql_bin.000009 | mysql -uroot -p1