📖 本篇简介:备份恢复是 DBA 的底线工作,数据安全是生产事故的最后一道防线,也是面试中必问的"实战题"。本篇基于 MySQL 8.0,系统讲解逻辑备份(mysqldump)、物理备份(XtraBackup)、binlog 时间点恢复 PITR、全量+增量备份策略、主从备份、备份验证、误删数据恢复、数据加密、审计、权限最小化、SQL 注入防护等知识点。学完后你能讲清楚"误删一张表怎么恢复""mysqldump 与 XtraBackup 怎么选""PITR 怎么做""生产备份策略怎么定",并能设计一套可靠的备份恢复方案。
目录
- 题目 1:MySQL 备份有哪些方式,逻辑与物理备份区别
- 题目 2:mysqldump 怎么用,关键参数有哪些
- 题目 3:XtraBackup 物理备份原理与优势
- 题目 4:什么是 PITR 时间点恢复,怎么做
- 题目 5:生产备份策略怎么定(全量+增量)
- 题目 6:误删一张表怎么恢复,完整流程
- 题目 7:备份做完怎么验证,为什么要验证
- 题目 8:主从复制能代替备份吗
- 题目 9:binlog 在备份恢复中起什么作用
- 题目 10:mysqldump 导出大表为什么慢,怎么优化
- 题目 11:XtraBackup 增量备份怎么做
- 题目 12:数据误删与恶意删库的应急流程
- 题目 13:MySQL 数据加密有哪些方式
- 题目 14:权限最小化怎么设计,应用账号怎么开权限
- 题目 15:怎么防 SQL 注入
- 题目 16:审计日志(Audit Log)有什么用
- 题目 17:备份数据要存多久,为什么异地备份
- 题目 18:热备、温备、冷备区别
- 题目 19:大表 DDL 前为什么要备份
- 题目 20:常见坑与注意事项
- 速查表:备份恢复速记
- 复习清单
- 练习题
题目 1:MySQL 备份有哪些方式,逻辑与物理备份区别
考点
- 逻辑备份:导出 SQL
- 物理备份:拷数据文件
- 各自优缺点
参考答案
| 维度 | 逻辑备份(mysqldump) | 物理备份(XtraBackup) |
|------|----------------------|------------------------|
| 内容 | SQL 语句 | 数据文件/页 |
| 恢复速度 | 慢(要重放 SQL) | 快(直接拷文件) |
| 备份速度 | 慢 | 快 |
| 跨版本 | 可跨大版本 | 同版本/小版本 |
| 一致性 | --single-transaction | LSN 一致性 |
| 适用 | 小库、迁移 | 大库、快速恢复 |
1. 逻辑备份:mysqldump 导出 CREATE/INSERT 语句,可读性好、跨版本,但恢复慢。
2. 物理备份:XtraBackup 直接拷 InnoDB 数据文件,快但要求同版本。
3. 生产组合:每周物理全量 + 每日 binlog 增量 + 每月逻辑备份。
追问
- 追问:备份大表选哪种?应对:大表物理备份快,恢复也快;mysqldump 导几个 G 要几小时。
- 追问:云数据库怎么备份?应对:云厂商自带物理备份 + binlog,开箱即用。
题目 2:mysqldump 怎么用,关键参数有哪些
考点
- --single-transaction
- --master-data
- --where
- --no-data
参考答案
# 本示例基于 MySQL 8.0
# 一致性导出 InnoDB 全库
mysqldump -uroot -p \
--single-transaction \ # InnoDB 一致性快照,不锁表
--master-data=2 \ # 记录 binlog 位点(注释掉)
--routines --triggers \ # 导出存储过程/触发器
--databases db1 db2 > backup.sql
# 只导出某张表结构
mysqldump -uroot -p --no-data db1 orders > schema.sql
# 导出部分数据
mysqldump -uroot -p --where="create_time>'2026-01-01'" db1 orders > orders_2026.sql
1. --single-transaction:InnoDB 一致性快照,不锁表,生产必加。
2. --master-data=2:记录 binlog 位点,用于 PITR。
3. --routines/--triggers:导出存储过程/触发器,默认不导。
4. --no-data:只导结构。
追问
- 追问:--lock-all-tables 与 --single-transaction 区别?应对:前者全局锁表(MyISAM 用),后者 InnoDB 快照不锁。
- 追问:mysqldump 导出 MyISAM 要锁表吗?应对:要,MyISAM 不支持 MVCC,--lock-tables。
题目 3:XtraBackup 物理备份原理与优势
考点
- 拷贝 InnoDB 页
- redo log 跟踪
- 快、不锁表
参考答案
1. 原理:
- 启动时记录 LSN;
- 拷贝 InnoDB 数据文件;
- 同时后台 copy redo log;
- 拷贝完成后 apply log(前滚),得到一致性备份。
2. 优势:
- 快,不锁表(InnoDB);
- 恢复快,直接拷文件;
- 支持增量备份。
3. 适用:大库(百 GB~TB 级)。
# 全量备份
xtrabackup --backup --user=root --password=xxx --target-dir=/backup/full
# 准备(apply log)
xtrabackup --prepare --target-dir=/backup/full
# 恢复
xtrabackup --copy-back --target-dir=/backup/full --datadir=/var/lib/mysql
追问
- 追问:XtraBackup 锁表吗?应对:备份期间短暂锁 FTWRL(拷 MyISAM/frm 时),InnoDB 部分不锁。
- 追问:XtraBackup 支持 8.0 吗?应对:Percona XtraBackup 8.0+ 支持。
题目 4:什么是 PITR 时间点恢复,怎么做
考点
- Point-In-Time Recovery
- 全量备份 + binlog 重放
- 恢复到指定时间点
参考答案
1. PITR:基于全量备份 + binlog,把数据库恢复到任意时间点(如误删前 1 秒)。
2. 步骤:
- 恢复最近一次全量备份;
- 从全量备份位点开始,重放 binlog 到误操作前。
# 1. 恢复全量备份(以 XtraBackup 为例)
xtrabackup --copy-back --target-dir=/backup/full
# 2. 查看全量备份记录的 binlog 位点
cat /backup/full/xtrabackup_binlog_info
# mysql-bin.000123 456789
# 3. 重放 binlog 到误操作前
mysqlbinlog --start-position=456789 \
--stop-datetime="2026-10-07 14:59:00" \
mysql-bin.000123 mysql-bin.000124 | mysql -uroot -p
追问
- 追问:binlog 没开能 PITR 吗?应对:不能,必须开 binlog 且保留时间够长。
- 追问:误删后立刻做什么?应对:别慌,先记录当前位点,别再写,避免覆盖 binlog。
题目 5:生产备份策略怎么定(全量+增量)
考点
- 全量周期
- 增量靠 binlog
- 保留周期
- 异地备份
参考答案
1. 典型策略:
- 每周:全量物理备份(XtraBackup);
- 每天:binlog 实时备份到异地;
- 每月:逻辑备份归档(mysqldump);
- 保留:全量留 1 个月,binlog 留 7~30 天。
2. 3-2-1 原则:3 份副本、2 种介质、1 份异地。
3. 测试恢复:每季度做一次恢复演练。
追问
- 追问:binlog 保留多久?应对:至少 7 天,大促前延长到 30 天,满足 PITR。
- 追问:备份占多少磁盘?应对:数据量的 20%~30%,单独磁盘,不与数据盘混用。
题目 6:误删一张表怎么恢复,完整流程
考点
- 先别慌
- 找全量备份
- PITR 到删表前
- 导出表回灌
参考答案
1. 第一步:立刻记录当前 binlog 位点,停止业务写入或切只读。
2. 第二步:找最近一次全量备份,恢复到临时库(不要在生产库直接恢复)。
3. 第三步:PITR 重放 binlog 到 DROP TABLE 前一秒。
4. 第四步:从临时库导出这张表。
5. 第五步:把表导回生产库。
6. 第六步:验证数据一致性。
-- 在临时库恢复后导出单表
mysqldump -h127.0.0.1 -P3307 db1 orders > orders_recovered.sql
-- 导回生产
mysql -h生产库 db1 < orders_recovered.sql
追问
- 追问:能只恢复一张表吗?应对:物理备份恢复整库再导单表;逻辑备份直接 source 表部分。
- 追问:误 DELETE 几行怎么办?应对:PITR 到 DELETE 前,或用 binlog 闪回工具(binlog2sql/MyFlash)反解。
题目 7:备份做完怎么验证,为什么要验证
考点
- 备份不验证等于没备份
- 抽样恢复
- 校验值
参考答案
1. 为什么要验证:没验证的备份可能损坏,真要用时才发现恢复不了,生产事故。
2. 验证手段:
- 备份后自动 checksum;
- 每周在临时库恢复一次全量备份;
- 抽样查询关键表行数;
- 恢复演练每季度一次。
3. 自动化:备份脚本跑完自动恢复到临时实例,跑 SQL 检查。
追问
- 追问:备份损坏怎么发现?应对:恢复演练时发现;没演练永远不知道。
- 追问:备份脚本失败告警吗?应对:必须告警,失败立刻人工介入。
题目 8:主从复制能代替备份吗
考点
- 主从复制是实时同步
- 误操作会同步到从库
- 不能代替备份
参考答案
1. 不能代替:
- 主库误 DELETE/DROP,从库同步执行,数据一样丢;
- 主库被恶意删库,从库也跟着删;
- 主从复制是"高可用+读扩展",不是备份。
2. 备份是历史快照,能恢复到过去任意时间点。
3. 生产:主从 + 备份都要有。
追问
- 追问:延迟从库有用吗?应对:有用,延迟 1 小时的从库,误操作后还有 1 小时窗口提升它止血。
- 追问:延迟从库怎么配?应对:
CHANGE REPLICATION SOURCE TO ... MASTER_DELAY=3600;。
题目 9:binlog 在备份恢复中起什么作用
考点
- PITR 基础
- 增量数据
- 闪回工具
参考答案
1. PITR:全量备份之间的增量变更都在 binlog 里,重放 binlog 恢复到任意时间点。
2. 闪回:binlog2sql/MyFlash 把 binlog 反解析成反向 SQL(DELETE 变 INSERT),快速恢复误删。
3. 要求:
- 必须开 binlog(
log_bin=ON); binlog_format=ROW(闪回工具才好用);- 保留足够长。
# binlog2sql 闪回误 DELETE
python binlog2sql.py -h127.0.0.1 -udump -pxxx \
--start-file='mysql-bin.000123' \
--start-datetime='2026-10-07 14:00:00' \
--stop-datetime='2026-10-07 15:00:00' \
-d db1 -t orders --flashback > flashback.sql
追问
- 追问:STATEMENT 模式能闪回吗?应对:不能,ROW 模式才有行镜像。
- 追问:binlog 占空间太大怎么办?应对:设
expire_logs_days=7自动清理;单独磁盘。
题目 10:mysqldump 导出大表为什么慢,怎么优化
考点
- 单线程导出
- 锁与一致性
- 并行导出
参考答案
1. 慢原因:mysqldump 默认单线程,逐行 SELECT + INSERT。
2. 优化:
- 大库用 XtraBackup 物理备份;
- 并行导出(mydumper 多线程);
- 只导必要表;
- 导出时
--quick(默认开启,逐行读不缓存全结果)。
# mydumper 多线程导出(替代 mysqldump)
mydumper -h127.0.0.1 -u root -p xxx \
--threads 4 --database db1 --outputdir /backup/
追问
- 追问:mysqldump 导出时锁表吗?应对:--single-transaction 不锁 InnoDB。
- 追问:导出时加 --single-transaction 还会卡吗?应对:大表导出仍占 IO,但不锁业务写。
题目 11:XtraBackup 增量备份怎么做
考点
- 基于 LSN
- 每周全量 + 每日增量
- 恢复时合并
参考答案
# 周一全量
xtrabackup --backup --target-dir=/backup/full --user=root
# 周三增量(基于周一全量)
xtrabackup --backup --target-dir=/backup/inc3 \
--incremental-basedir=/backup/full --user=root
# 恢复:先 prepare 全量,再 prepare 增量
xtrabackup --prepare --apply-log-only --target-dir=/backup/full
xtrabackup --prepare --apply-log-only --target-dir=/backup/full \
--incremental-dir=/backup/inc3
xtrabackup --copy-back --target-dir=/backup/full
1. 增量原理:记录上次备份后的 LSN,只备份变化的页。
2. 恢复:先 prepare 全量,再依次 prepare 增量。
3. 优势:节省备份空间与时间。
追问
- 追问:增量备份能随便跳吗?应对:不能,要按顺序 apply;建议每周全量重置。
- 追问:XtraBackup 备份期间锁表吗?应对:InnoDB 不锁,MyISAM/frm 短暂锁。
题目 12:数据误删与恶意删库的应急流程
考点
- 立刻止损
- 不重启不关机
- 保留现场
- 恢复
参考答案
1. 第一步:止损:
- 立刻停应用写入或切只读;
- 记录当前 binlog 位点;
- 不要重启 MySQL(binlog 可能还在内存)。
2. 第二步:保留现场:
- 保留 binlog、错误日志;
- 不要立刻清现场。
3. 第三步:恢复:
- 临时库 PITR;
- 导出丢失数据回灌。
4. 第四步:复盘:
- 为什么误删;
- 权限/审核/备份流程改进。
追问
- 追问:删库后能从从库恢复吗?应对:从库同步了删库,没用;靠备份+binlog。
- 追问:恶意删库怎么追责?应对:审计日志记录操作人,binlog 记录操作。
题目 13:MySQL 数据加密有哪些方式
考点
- 传输加密 TLS
- 静态加密 InnoDB TDE
- 应用层加密
参考答案
1. 传输加密:MySQL 8.0 默认 caching_sha2_password,连接用 TLS。
2. 静态加密(TDE):InnoDB 表空间加密,ALTER TABLE t ENCRYPTION='Y',磁盘文件加密。
3. 应用层加密:敏感字段(手机号、身份证)在应用层加密后入库,数据库存密文。
4. 备份加密:XtraBackup/mysqldump 加密备份文件。
-- InnoDB 表空间加密
ALTER TABLE emp ENCRYPTION='Y';
追问
- 追问:TDE 对性能影响?应对:5%~10%,可接受。
- 追问:应用层加密还能查询吗?应对:密文无法范围查询,要配合哈希字段或 ES。
题目 14:权限最小化怎么设计,应用账号怎么开权限
考点
- 不用 root
- 按库按权限授权
- 禁止 SUPER
参考答案
-- 应用账号:只授权业务库的 SELECT/INSERT/UPDATE/DELETE
CREATE USER 'app_user'@'应用IP' IDENTIFIED BY '强密码';
GRANT SELECT,INSERT,UPDATE,DELETE ON db1.* TO 'app_user'@'应用IP';
-- 不给 DROP/ALTER/INDEX/SUPER
-- 只读账号
CREATE USER 'ro_user'@'%' IDENTIFIED BY '强密码';
GRANT SELECT ON db1.* TO 'ro_user'@'%';
1. 应用账号:只给 DML 权限,不给 DDL。
2. 限制来源 IP:'user'@'应用IP',不允许 % 全开。
3. 密码策略:8.0 默认强密码插件,12 位+。
4. 定期审计:mysql.user 看冗余账号。
追问
- 追问:为什么不给应用 SUPER 权限?应对:SUPER 可关 binlog、kill 线程、写只读从库,危险。
- 追问:开发环境怎么开权限?应对:开发账号只读生产,写在测试库。
题目 15:怎么防 SQL 注入
考点
- 预编译 PreparedStatement
- 不拼接 SQL
- 输入校验
- 最小权限
参考答案
1. 预编译:用 ? 占位符,参数与 SQL 分离。
2. 禁止拼接 SQL:
// 危险:字符串拼接
String sql = "SELECT * FROM users WHERE name='" + name + "'";
// 安全:预编译
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name=?");
ps.setString(1, name);
3. ORM 框架:MyBatis 用 #{} 不用 ${}。
4. 最小权限:应用账号不给 DROP/FILE 权限。
5. 输入校验:特殊字符过滤。
追问
- 追问:MyBatis ${} 与 #{} 区别?应对:#{} 预编译安全,${} 字符串拼接有注入风险。
- 追问:LIKE 查询怎么防注入?应对:用 CONCAT 拼通配符,参数仍用占位符。
题目 16:审计日志(Audit Log)有什么用
考点
- 记录谁在什么时候做了什么
- 合规要求
- 安全审计
参考答案
1. 作用:记录所有连接、SQL 执行、登录登出,用于安全审计与追责。
2. MySQL 企业版:Enterprise Audit 插件;社区版用 Percona Audit Log Plugin。
3. 合规:金融、医疗行业监管要求。
4. 注意:审计日志本身占空间,定期归档。
追问
- 追问:审计日志会影响性能吗?应对:5%~10%,高并发可采样。
- 追问:审计日志存多久?应对:合规要求一般 6 个月~1 年。
题目 17:备份数据要存多久,为什么异地备份
考点
- 本地备份不够
- 异地防机房火灾
- 保留周期
参考答案
1. 本地备份:防误操作,但机房整体故障(火灾、断电)时备份一起没。
2. 异地备份:
- 跨城/跨云备份;
- 防机房级灾难;
- 合规要求(金融两地三中心)。
3. 保留周期:
- 全量备份:留 1~3 个月;
- binlog:留 7~30 天;
- 归档备份:留 1~7 年(合规)。
追问
- 追问:异地备份带宽够吗?应对:增量备份小,凌晨低峰同步。
- 追问:异地备份延迟多大?应对:分钟~小时级,不影响 RPO。
题目 18:热备、温备、冷备区别
考点
- 热备不锁库
- 温备锁部分
- 冷备停库
参考答案
| 方式 | 业务影响 | 一致性 | 速度 |
|------|----------|--------|------|
| 热备 | 无影响(InnoDB) | 一致性快照 | 快 |
| 温备 | 锁 MyISAM/全局读锁 | 一致 | 中 |
| 冷备 | 停库 | 绝对一致 | 最快(拷文件) |
1. 热备:mysqldump --single-transaction、XtraBackup,业务不中断。
2. 温备:LOCK TABLES/read_only,业务可读不可写。
3. 冷备:停 MySQL 拷数据文件,最安全但业务中断。
追问
- 追问:生产用哪种?应对:热备为主,大版本升级时冷备。
- 追问:冷备最快为什么不常用?应对:业务不能停。
题目 19:大表 DDL 前为什么要备份
考点
- DDL 可能失败
- 回滚需要备份
- pt-osc/gh-ost 也建议备
参考答案
1. DDL 风险:
- 加列/加索引中途失败,表可能损坏;
- DDL 误操作(如 DROP 列);
- 主从延迟。
2. 备份:DDL 前备一份,失败可恢复。
3. 在线 DDL 工具:pt-online-schema-change/gh-ost 本身建影子表,相对安全,但仍建议备份。
追问
- 追问:8.0 INSTANT ADD COLUMN 还需要备份吗?应对:INSTANT 秒级加列风险小,但其他 DDL 仍要备。
- 追问:DDL 中途失败会怎样?应对:MySQL 8.0 支持 DDL 原子提交,失败自动回滚,比 5.7 安全。
题目 20:常见坑与注意事项
考点
- 备份恢复高频坑
- 数据安全
- 运维操作
参考答案
1. 坑 1:备份做完没验证,恢复时发现坏的。
2. 坑 2:以为主从复制就是备份,误删后从库跟着删。
3. 坑 3:binlog 没开或保留太短,PITR 做不了。
4. 坑 4:mysqldump 导出没加 --single-transaction,锁表影响业务。
5. 坑 5:备份放本地盘,机房故障一起丢。
6. 坑 6:应用账号开了 root/SUPER,被注入删库。
7. 坑 7:密码弱、不外换,被暴力破解。
8. 坑 8:误删后重启 MySQL,内存 binlog 丢失。
9. 坑 9:大表 DDL 前没备份,失败回滚难。
10. 坑 10:备份脚本失败不告警,真要用时才发现没备份。
追问
- 追问:备份能防勒索病毒吗?应对:异地离线备份能防;在线备份被病毒加密一起丢。
- 追问:生产备份频率多少?应对:全量每周,binlog 实时,关键业务每天全量。
速查表:备份恢复速记
| 场景 | 工具/手段 |
|------|----------|
| 小库逻辑备份 | mysqldump --single-transaction --master-data=2 |
| 大库物理备份 | XtraBackup |
| PITR 时间点恢复 | 全量备份 + mysqlbinlog 重放 |
| 误删几行闪回 | binlog2sql / MyFlash(ROW 模式) |
| 防机房灾难 | 异地备份 + 延迟从库 |
| 防误删 | 延迟从库 + 备份 + 权限收紧 |
| 防注入 | 预编译 + ORM #{} |
| 权限最小化 | 应用只 DML,不给 DDL/SUPER |
| 备份验证 | 每周恢复演练 + checksum |
| 审计 | Enterprise Audit / Percona Audit |
复习清单
| 题目 | 核心结论 | 易错点 |
|------|----------|--------|
| 1 | 逻辑可读跨版本,物理快恢复 | 大表选物理备份 |
| 2 | --single-transaction 不锁 InnoDB | 忘加 --routines |
| 3 | XtraBackup 拷页+apply log | 同版本要求 |
| 4 | 全量+binlog 重放 PITR | 没开 binlog |
| 5 | 周全量+日 binlog+异地 | 不验证备份 |
| 6 | 临时库恢复再导回 | 在生产直接恢复 |
| 7 | 备份不验证=没备份 | 恢复演练缺失 |
| 8 | 主从不等于备份 | 误操作同步到从库 |
| 9 | binlog 是 PITR 与闪回基础 | STATEMENT 不能闪回 |
| 10 | 大库用 mydumper/XtraBackup | mysqldump 单线程慢 |
| 11 | 增量基于 LSN | 按顺序 apply |
| 12 | 止损→保留现场→恢复 | 误删后重启 |
| 13 | TLS/TDE/应用层加密 | 密文无法范围查询 |
| 14 | 应用只 DML,限 IP | 开 SUPER 权限 |
| 15 | 预编译防注入 | MyBatis ${} |
| 16 | 审计记录谁做了什么 | 合规要求 |
| 17 | 异地防机房灾难 | 本地备份单点 |
| 18 | 热备为主,冷备升级用 | 业务不能停 |
| 19 | DDL 前备份 | 8.0 DDL 原子但仍要备 |
| 20 | 不验证/主从当备份/权限松三大坑 | 备份失败不告警 |
练习题
1. 题目:业务误 DELETE FROM orders WHERE create_time<'2025-01-01',删了 100 万行,怎么恢复?
- 参考答案:立刻记录 binlog 位点;临时库恢复最近全量备份,PITR 重放 binlog 到 DELETE 前;或用 binlog2sql 生成反向 INSERT 回灌;最后验证数据。
2. 题目:mysqldump 导出 InnoDB 大库为什么要加 --single-transaction?
- 参考答案:利用 InnoDB MVCC 一致性快照,不锁表,业务可正常读写;不加会锁表影响业务。
3. 题目:主从复制能代替备份吗?为什么?
- 参考答案:不能,误操作/DROP 会同步到从库;备份是历史快照,能恢复到过去任意时间点。
4. 题目:应用连数据库的账号为什么不能给 root?
- 参考答案:应用一旦被注入,root 可 DROP DATABASE、写文件、读任意库;最小权限只给业务库 DML,限制来源 IP。
5. 题目:PITR 时间点恢复依赖什么?
- 参考答案:最近一次全量备份 + 备份后的所有 binlog(连续不缺),重放 binlog 到目标时间点。
下一篇预告:第 20 章 参数调优与性能监控面试精讲
文章回复
0 条公开回复