binlog 是什么:一次误删数据的恢复过程
发布时间:2026-07-09 16:08       
更新时间:2026-07-09 23:05
binlog 全称 binary log,二进制日志,把数据库里每一次数据变更按顺序记下来。它平时安静地躺在磁盘上,价值在出事那天显现:误删的数据,靠它找回来。
## 一、三种格式
ROW 记录每行数据改成了什么,信息最全,体积也大,是 8.0 的默认值;STATEMENT 只记 SQL 语句本身,省空间,但遇到 now()、uuid() 这类函数时重放结果可能不一致;MIXED 在两者之间自动切换。生产库建议 ROW,主从复制和数据恢复都更可靠。格式由 binlog_format 指定,修改需要重启,新库在建成当天就定成 ROW。线上用的什么格式,SHOW VARIABLES LIKE 'binlog_format' 一看便知。
## 二、先确认它开着
```
SHOW VARIABLES LIKE 'log_bin';
SHOW BINARY LOGS;
```
log_bin 为 ON 才有得恢复,第二条命令列出所有 binlog 文件。很多人是出事后才发现 binlog 没开,这项检查应该放在建库当天。binlog 占用随写入量增长,保留期调长之前先算一遍磁盘空间账。
## 三、一次误删的恢复过程
场景:上午有人对 orders 表执行了不带条件的 DELETE,删掉一上午的数据。前提是昨晚有全量备份、binlog 连续,两个条件缺一个,方案就要换。
第一步止血:业务切只读或直接停写,防止新写入把现场搅乱。第二步定位:用 mysqlbinlog 找到那条 DELETE 的时间和位置:
```
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000108 | less
```
第三步重放:昨晚全量恢复到临时实例,再重放 binlog,停点卡在误操作之前:
```
mysqlbinlog --start-position=1000 --stop-position=98000 mysql-bin.000108 | mysql -uroot -p tempdb
```
--stop-position 落在 DELETE 语句之前,被删的数据就完整回来了。如果误删之后又有正常写入,重放就要把这些操作也考虑进来,逐段卡点,这也是为什么要第一时间停写。第四步核对:行数和关键字段抽查无误后,把这张表从临时实例导回生产。
## 四、备份和 binlog 是一套
binlog 重放必须有全量备份打底:备份定基线,binlog 补增量。备份周期越短,需要重放的日志越少,恢复越快。备份文件和 binlog 分开存放,同一块盘上一锅端的事故并不少见。
binlog 保留期用 binlog_expire_logs_seconds 控制,至少要盖住一个完整备份周期,别让日志比备份先过期。