DBA 圈流传一句话:没删过库的人生不完整。但删了能找回来,才是真本事。误删数据的救命稻草就是 binlog——它记录了每一行数据的变更,既能用来恢复,也能反查哪条语句闯的祸。前提是提前开了 log-bin,没开的话神仙难救,所以第一件事去检查配置。
SHOW VARIABLES LIKE 'log_bin'; -- 值为ON才有救
SHOW BINARY LOGS; -- 看有哪些日志文件
SHOW BINLOG EVENTS IN 'mysql-bin.000124' LIMIT 20; -- 快速浏览内容
误删场景分两种。第一种:DELETE 误删了部分行。思路是从 binlog 里把删除前的旧值反解出来。用 mysqlbinlog 工具导出可读格式:
# 先确定误删语句的时间范围,导出这段
mysqlbinlog --no-defaults \
--start-datetime='2026-08-26 09:00:00' \
--stop-datetime='2026-08-26 09:30:00' \
--database=site_db \
/var/lib/mysql/mysql-bin.000124 > /tmp/binlog_误删.sql
# ROW格式下能看到被删的完整行
grep -B2 -A2 '### DELETE FROM' /tmp/binlog_误删.sql | head -40
ROW 格式的 binlog 里,DELETE 事件的 WHERE 部分就是被删掉的那行数据原值,把它改写成 INSERT 语句重放回去,数据就回来了。量大的话写脚本批量转换,量小手工改几条也快。
第二种更惨:整表 DROP 或 TRUNCATE。binlog 里没有旧值,只能靠备份恢复——从最近一次 mysqldump 恢复全量,再用 binlog 把备份时点到误操作之间的增量重放。这也解释了为什么备份和 binlog 缺一不可:备份是底,binlog 是增量。
# 恢复流程:全量 + 增量
gunzip < site_db_2026-08-25_0300.sql.gz | mysql -uroot -p site_db
mysqlbinlog --start-datetime='2026-08-25 03:00:00' \
--stop-datetime='2026-08-26 09:05:00' \
mysql-bin.00012[3-4] | mysql -uroot -p site_db
两个保命习惯:一,恢复操作先在测试库演练,确认无误再动生产;二,恢复前把当前库再备份一份,防止恢复过程引入新事故。另外线上执行 DELETE 或 UPDATE 前,先把 WHERE 单独跑一遍 SELECT 数行数,这个习惯比任何工具都靠谱。(数据来源:MySQL官方手册)
A5创业网 版权所有