Skip to content

MySQL 备份与恢复

备份恢复不是 DBA 才需要懂。后端开发至少要知道:数据误删后能不能恢复、能恢复到什么时间点、恢复会不会覆盖新数据。

一句话理解:

备份解决“有一份历史数据”,binlog 解决“从历史时间点之后发生了什么变更”。

为什么需要备份

风险例子
误删delete 条件写错
误更新把大量订单状态改错
表损坏磁盘或文件异常
版本发布事故新代码写入脏数据
灾难恢复机器、机房故障

没有备份时,数据库再强也救不了误操作后的历史数据。

备份类型

类型说明适合
逻辑备份导出 SQL 或文本小库、表级恢复、迁移
物理备份复制数据文件大库、快速恢复
全量备份备份全部数据基线
增量备份备份变化部分降低空间
binlog记录变更事件时间点恢复

恢复流程

mermaid
flowchart TD
    A["选择最近全量备份"] --> B["恢复到临时实例"]
    B --> C["找到误操作时间点"]
    C --> D["回放 binlog 到误操作前"]
    D --> E["校验数据"]
    E --> F["导出需要恢复的数据"]
    F --> G["回写生产或切换实例"]

不要直接在生产库上盲目恢复。更稳的方式是恢复到临时实例,验证后再回补。

mysqldump 示例

导出单库:

bash
mysqldump -h127.0.0.1 -uroot -p \
  --single-transaction \
  --routines \
  --triggers \
  app_db > app_db.sql

参数解释:

参数含义
--single-transaction对 InnoDB 做一致性快照备份,减少锁表
--routines导出存储过程和函数
--triggers导出触发器

恢复:

bash
mysql -h127.0.0.1 -uroot -p app_db < app_db.sql

注意:mysqldump 适合中小数据量。大库恢复可能非常慢。

binlog 时间点恢复

假设每天凌晨 2 点有全量备份,上午 10 点误删数据。

恢复思路:

  1. 用凌晨 2 点备份恢复到临时库。
  2. 用 binlog 回放 2 点到 10 点之前的变更。
  3. 跳过误删语句。
  4. 校验并恢复目标数据。

查看 binlog:

bash
mysqlbinlog --base64-output=decode-rows -vv mysql-bin.000001

按时间导出:

bash
mysqlbinlog \
  --start-datetime="2026-07-05 02:00:00" \
  --stop-datetime="2026-07-05 09:59:59" \
  mysql-bin.000001 > recover.sql

误删恢复注意事项

注意事项说明
先停写或隔离影响避免错误继续扩大
不要直接覆盖生产可能覆盖误操作后产生的新正确数据
先恢复临时实例用于对比和导出
确认误操作时间时间点错误会恢复错数据
保留证据SQL、binlog、影响行数都要记录

商业场景:订单误更新

错误 SQL:

sql
update orders
set status = 9
where created_at >= '2026-07-01';

如果少了业务条件,可能影响大量订单。

处理流程:

  1. 立即停止相关写入任务。
  2. 查 binlog 找到误更新事务。
  3. 从备份恢复临时实例。
  4. 对比生产和临时实例,生成反向修复 SQL。
  5. 小批量回写并校验。

备份策略

数据重要性策略
核心交易库全量备份 + binlog + 异地备份 + 定期演练
普通业务库定期全量 + binlog
临时数据可降低备份频率

备份如果没有演练,就不算真正可用。很多事故不是没有备份,而是恢复时发现备份不可用或恢复时间太长。

面试标准回答

text
MySQL 备份恢复通常结合全量备份和 binlog。全量备份提供某个时间点的数据基线,binlog 记录之后的变更,可以用于时间点恢复。误删数据时,不应该直接覆盖生产库,而是先把最近备份恢复到临时实例,再回放 binlog 到误操作前,校验后导出需要恢复的数据回补生产。mysqldump 是逻辑备份,适合中小库;大库通常更依赖物理备份。备份方案必须定期恢复演练,否则无法保证事故时可用。

关联学习:redo log 与 binlog事务主从复制