作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

数据库是一个系统(应用)最重要的资产之一,所以我们的数据库将从以下几个数据库来进行介绍。
MySQL(本章节)
PostgreSQL
MongoDB
Redis
Etcd
我们前面使用备份+Binlog恢复数据,这个只是作为兜底来使用。而且我们前面已经搭建过主从,可以直接把从节点升级为主节点来提供服务,但是我们还可能出现在主从正常的情况下,因为误删除或者其他原因需找回删除或者更新的数据,今天这个小节我们就来介绍方法。
1.删除(更新的数据)在备份里面
如果是这样的情况,相对比较简单,因为只需要把备份数据导入到一个新的数据库里面,然后从里面提取我们需要的数据,再更新到源数据库即可恢复。
2.删除(更新的数据)在Binlog里面
这个时候的数据属于刚更新的数据,还未有备份,只能从Binlog数据进行恢复。下面我们将通过手工删除数据,然后再通过Binlog进行恢复,这里只是演示,所有数据相对简单。
1.环境准备
已经开通Binlog的主从集群插入新数据,确保需要删除的数据再Binlog里面。
mysql> select * from test_data where id=8466900;
+---------+----------------+---------------------+---------------+
| id | value | created_at | random_number |
+---------+----------------+---------------------+---------------+
| 8466900 | Test value 123 | 2025-10-09 22:32:43 | 327 |
+---------+----------------+---------------------+---------------+
1 row in set (0.00 sec)
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000012 | 43070 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
2.删除指定数据
mysql> delete from test_data where id=8466900;
Query OK, 1 row affected (0.05 sec)
mysql> select * from test_data where id=8466900;
Empty set (0.00 sec)
3.从binglog解析数据
# 解析binlog文件,搜索DELETE操作,具体以现场环境为准
mysqlbinlog --no-defaults \
--base64-output=decode-rows -v \
/path/to/backup/mysql-bin.000012 > /tmp/binlog_analysis.txt
4.分析解析的数据
# at 43271
#251009 22:39:35 server id 1 end_log_pos 43334 CRC32 0x9b0d6a88 Delete_rows: table id 111 flags: STMT_END_F
### DELETE FROM `test_db`.`test_data`
### WHERE
### @1=8466900
### @2='Test value 123'
### @3=1760020363
### @4=327
# at 43334
#251009 22:39:35 server id 1 end_log_pos 43365 CRC32 0x0caaa45b Xid = 465
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
# at 43271 - 事务开始位置
end_log_pos 43365 - 事务结束位置
@1, @2, @3 @4- 被删除的完整数据(在 ROW 格式下)
注意:这里的数据是无法显示数据类型的,所以我们转换成INSERT语句需要考虑数据类型。
5.转换成INSET语句
INSERT INTO test_data (id, value, created_at, random_number)
VALUES (8466900, 'Test value 123', FROM_UNIXTIME(1760020363), 327);
6.插入数据
mysql> INSERT INTO test_data (id, value, created_at, random_number)
-> VALUES (8466900, 'Test value 123', FROM_UNIXTIME(1760020363), 327);
Query OK, 1 row affected (0.05 sec)
mysql> select * from test_data where id=8466900;
+---------+----------------+---------------------+---------------+
| id | value | created_at | random_number |
+---------+----------------+---------------------+---------------+
| 8466900 | Test value 123 | 2025-10-09 22:32:43 | 327 |
+---------+----------------+---------------------+---------------+
1 row in set (0.01 sec)
到这里我们删除的数据就通过Binlog完成数据恢复,当然这里只涉及到单表,而且是MYSQL自带的工具,还可以使用其他开源工具具有更多的功能。
运维小路
一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!
关注微信公众号《运维小路》获取更多内容。

被折叠的 条评论
为什么被折叠?



