news 2026/10/10 2:53:14

MySQL 备份与恢复实战:mysqldump、XtraBackup、binlog 增量与时间点恢复(PITR)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL 备份与恢复实战:mysqldump、XtraBackup、binlog 增量与时间点恢复(PITR)
个人主页: > for_ever_love__ <(欢迎各位大佬莅临😊)
其他栏目: > 大模型开发从0到1 <
其他栏目: > iOS项目总结大全 <
其他栏目: > 我想学python了 <
其他栏目: > iOS UI <

文章目录

  • MySQL 备份与恢复实战:mysqldump、XtraBackup、binlog 增量与时间点恢复(PITR)
    • 一、先建立正确的备份心智模型
      • 1.1 三种备份层次
      • 1.2 冷备 / 温备 / 热备
    • 二、mysqldump:逻辑备份的基本盘
      • 2.1 一条正确的全库备份命令
      • 2.2 常见的部分备份写法
      • 2.3 恢复
    • 三、Percona XtraBackup:物理热备的主力
      • 3.1 它凭什么能做到热备
      • 3.2 全量备份与恢复
      • 3.3 增量备份
      • 3.4 关键元数据文件
      • 3.5 压缩、流式备份与 Clone Plugin
    • 四、binlog:把 RPO 从"一天"压到"几乎为零"
      • 4.1 必须先配好这些
      • 4.2 定期刷出并异地保存 binlog
      • 4.3 时间点恢复(PITR)完整流程
      • 4.4 只回滚一条误操作(闪回思路)
    • 五、三种方案怎么选
    • 六、一套可以直接抄的备份策略
    • 七、恢复演练:别跳过这一步
    • 八、常见误区
    • 小结

MySQL 备份与恢复实战:mysqldump、XtraBackup、binlog 增量与时间点恢复(PITR)

备份这事儿有个残酷的特点:平时看起来毫无价值,出事那天决定你的去留。

更残酷的是:绝大多数团队"有备份",但从来没验证过能不能恢复。
这篇把三种备份方式、增量策略、以及真正救命的 binlog 时间点恢复讲清楚,
顺带给出一套可以直接抄走的备份脚本和恢复演练流程。

一、先建立正确的备份心智模型

在选工具之前,先回答两个问题,它们决定一切:RPO(能容忍丢多少数据)
和RTO(多久能恢复服务)。RPO 是 5 分钟还是 0、RTO 是 2 小时还是 10 分钟,
直接决定你是"每天一备"还是"全备 + 增量 + 实时 binlog"。

然后记住一条铁律:

没有演练过的备份 = 没有备份。

1.1 三种备份层次

类型备份对象代表工具速度恢复粒度
逻辑备份SQL 语句 / 数据行mysqldump、mydumper慢单库、单表、单行
物理备份数据文件(.ibd、ibdata、redo)XtraBackup、Clone Plugin快整实例为主
binlog 备份增量变更日志mysqlbinlog、FLUSH LOGS极快任意时间点

现实中的标准组合是:每周一次全备 + 每天一次增量 + 实时备份 binlog,
出事时按"全备恢复 → 增量回放 → binlog 追平到误操作前一秒"的顺序还原。

1.2 冷备 / 温备 / 热备

方式数据库状态影响说明
冷备实例关闭停服systemctl stop mysqld后直接打包数据目录
温备运行中,加全局读锁只读可写不可FLUSH TABLES WITH READ LOCK
热备运行中,正常读写几乎无影响靠 MVCC + redo,XtraBackup / mysqldump 一致性快照

冷备最简单也最可靠,但现在基本没人能接受停服。
热备是主流,热备的核心就是"拿到一个一致性时间点 + 拿到对应的 binlog 位点"。

二、mysqldump:逻辑备份的基本盘

2.1 一条正确的全库备份命令

mysqldump-h127.0.0.1-uadmin-p'***'\--single-transaction --master-data=2--flush-logs\--routines--triggers--events--hex-blob\--default-character-set=utf8mb4 --set-gtid-purged=OFF\--all-databases|gzip>/backup/full_$(date+%F).sql.gz

每个参数的含义,一个都不能少:

参数为什么必须
--single-transaction在一个事务里用 RR 一致性快照导出,不锁表。只对 InnoDB 有效
--master-data=2把备份时刻的 binlog 文件名和位置写成注释记进文件,做增量恢复要用(新版也写作--source-data)
--flush-logs备份开始时切一个新的 binlog,之后的新变更都在新文件里,方便定位
--routines --triggers --events存储过程、触发器、事件。默认只带触发器,函数和过程不带
--hex-blob用十六进制导出 BINARY / BLOB,避免二进制内容损坏
--default-character-set=utf8mb4防止中文和 emoji 变乱码
--set-gtid-purged=OFF恢复到其它实例(比如做从库之外的用途)时,避免写入 GTID 集导致冲突

⚠️--single-transaction的坑:

  • 只对 InnoDB 保证一致性。库里还有 MyISAM 表的话,得改用--lock-all-tables
    (或者干脆别用 MyISAM)。
  • 它靠 RR 快照,所以备份期间不要执行 DDL。DDL 不参与 MVCC 快照,
    会导致导出的数据和之后拿到的 binlog 位点对不上。这也是 DDL 要放低峰的原因之一。
  • 长事务会让它卡住:快照要等所有活跃事务结束才能建立。

2.2 常见的部分备份写法

mysqldump-uadmin-p--single-transaction--databasesshop>shop.sql# 单库mysqldump-uadmin-p--single-transaction shop orders order_items>tables.sql# 指定表mysqldump-uadmin-p--no-data shop>shop_schema.sql# 只备结构# 按条件导出(归档常用):先 EXCHANGE 出分区,再 dump 独立表mysqldump-uadmin-p--single-transaction\--where="created_at >= '2024-01-01' AND created_at < '2024-02-01'"\shop orders>orders_202401.sql

2.3 恢复

mysql-uadmin-p</backup/full_2024-06-01.sql# 全库gunzip</backup/full_2024-06-01.sql.gz|mysql-uadmin-p# 压缩过的# 单库:备份文件里没有 CREATE DATABASE 时,必须先建库再导入mysql-uadmin-p-e"CREATE DATABASE shop DEFAULT CHARSET utf8mb4;"mysql-uadmin-pshop<shop.sql

mysqldump 的致命弱点:恢复慢。
恢复 = 逐条执行 INSERT + 重建所有索引,通常是备份时间的 3~10 倍。
几百 GB 的库恢复到能用,几个小时是常态。
所以大库(> 200GB)不要用 mysqldump 做主备份,改用 XtraBackup。

需要多线程逻辑备份时用mydumper / myloader:

mydumper-uadmin-p'***'-h127.0.0.1--outputdir/backup/mydump_$(date+%F)\--threads8--compress--rows100000--trx-consistency-only myloader-uadmin-p'***'--directory/backup/mydump_2024-06-01\--threads8--overwrite-tables

三、Percona XtraBackup:物理热备的主力

3.1 它凭什么能做到热备

原理一句话:拷数据文件的同时,另起线程持续拷贝 redo log,最后用 redo 把文件"追平"到一致状态。

1. 启动一个后台进程,实时监听 redo log 变化,写入 xtrabackup_log 2. 拷贝 InnoDB 数据文件(.ibd)和系统表空间(此时文件是"不一致"的,没关系) 3. FLUSH TABLES WITH READ LOCK(短暂锁,防 DDL,同时取 binlog 位点) 4. 拷贝 .frm / 非 InnoDB 表文件 / 记录 binlog 位点 5. UNLOCK TABLES,停止 xtrabackup_log

恢复时,XtraBackup 内嵌一个 InnoDB 实例,回放 xtrabackup_log,
已提交事务应用、未提交事务回滚——过程和 InnoDB 崩溃恢复一模一样。

⚠️ 版本对应关系要记牢:

XtraBackup 版本支持的 MySQL
2.4MySQL 5.6 / 5.7
8.0MySQL 8.0(不支持 5.7)

而且8.0 版本的 XtraBackup 去掉了innobackupex,直接用xtrabackup命令。

3.2 全量备份与恢复

# 备份xtrabackup--backup--user=admin--password='***'--host=127.0.0.1\--target-dir=/backup/full_$(date+%F)# 准备(prepare)= 崩溃恢复,把文件追平到一致状态xtrabackup--prepare--target-dir=/backup/full_2024-06-01# 恢复:停库 → 清空数据目录 → 拷回 → 改权限 → 启动systemctl stop mysqldrm-rf/var/lib/mysql/* xtrabackup --copy-back --target-dir=/backup/full_2024-06-01chown-Rmysql:mysql /var/lib/mysql systemctl start mysqld

想保留原备份文件就用--copy-back;想省一次拷贝用--move-back(备份会被消耗掉)。

prepare 这一步必须在恢复之前做,也可以提前做——很多团队在备份机上就 prepare 好,
这样真正故障时就只剩copy-back+ 启动,RTO 短很多。

3.3 增量备份

增量备份只拷LSN 大于上次备份的页,所以很快、很小。

# 周日:全备xtrabackup--backup--target-dir=/backup/full--user=admin--password='***'# 周一:基于全备的增量xtrabackup--backup--target-dir=/backup/inc1 --incremental-basedir=/backup/full\--user=admin--password='***'# 周二:基于上一次增量的增量xtrabackup--backup--target-dir=/backup/inc2 --incremental-basedir=/backup/inc1\--user=admin--password='***'

恢复时的 prepare 顺序是最容易搞错的地方:

# 1. 先 prepare 全备,注意 --apply-log-only(不回滚未提交事务)xtrabackup--prepare--apply-log-only --target-dir=/backup/full# 2. 依次把增量并入全备(除最后一个外都要带 --apply-log-only)xtrabackup--prepare--apply-log-only --target-dir=/backup/full --incremental-dir=/backup/inc1# 3. 最后一个增量:不带 --apply-log-only,让它做最终回滚xtrabackup--prepare--target-dir=/backup/full --incremental-dir=/backup/inc2# 4. 拷回systemctl stop mysqldrm-rf/var/lib/mysql/* xtrabackup --copy-back --target-dir=/backup/fullchown-Rmysql:mysql /var/lib/mysql systemctl start mysqld

为什么最后一个增量不能加--apply-log-only?
因为未提交事务可能在最后一个增量里才结束,提前回滚会破坏一致性。
记住口诀:除最后一次外,全部加--apply-log-only。

3.4 关键元数据文件

备份目录里有几个文件,出事了要看它们:

文件内容用途
xtrabackup_checkpoints备份类型(full/incremental)、from_lsn、to_lsn判断增量链是否正确
xtrabackup_binlog_info备份时刻的 binlog 文件名 + 位点 + GTID做时间点恢复的起点
xtrabackup_info备份命令、时长、版本等审计和排查
backup-my.cnf备份时的最小配置恢复时参考
cat/backup/full/xtrabackup_binlog_info# mysql-bin.000042 197362 a1b2c3d4-...:1-98213

3.5 压缩、流式备份与 Clone Plugin

# 压缩备份(需额外安装 qpress),恢复前先 --decompressxtrabackup--backup--compress--compress-threads=4--target-dir=/backup/full_comp# 流式备份:直接传到备份机,不在本地落盘xtrabackup--backup--stream=xbstream --target-dir=/tmp\|sshbackup@10.0.0.9"xbstream -x -C /backup/full_$(date+%F)"

不想装 XtraBackup 的话,8.0.17+ 自带Clone Plugin也能做物理备份:

CLONELOCALDATADIRECTORY='/backup/clone_20240601';-- 本地克隆CLONE INSTANCEFROM'admin'@'10.0.0.8':3306IDENTIFIEDBY'***';-- 远程克隆

限制:克隆会清空目标目录 / 本地实例,且版本必须完全一致。
它更适合"快速建从库",做长期备份管理不如 XtraBackup 灵活。

四、binlog:把 RPO 从"一天"压到"几乎为零"

全备只能回到"备份那个时刻"。要少丢数据,必须靠 binlog 做增量。

4.1 必须先配好这些

[mysqld] server_id = 1 log_bin = /data/mysql/mysql-bin # 8.0 默认已开启 binlog_format = ROW # 强烈建议 ROW,STATEMENT 有不确定性风险 sync_binlog = 1 # 每次提交刷盘,宕机不丢 binlog innodb_flush_log_at_trx_commit = 1 binlog_row_image = FULL # gh-ost 和闪回工具都依赖它 binlog_expire_logs_seconds = 604800 # 保留 7 天(5.7 用 expire_logs_days)
SHOWVARIABLESLIKE'binlog_expire_logs_seconds';SHOWBINARYLOGS;SHOWMASTERSTATUS;-- 8.4 起为 SHOW BINARY LOG STATUS

⚠️sync_binlog=1和innodb_flush_log_at_trx_commit=1就是常说的"双一",
是最安全的配置,代价是每次提交多一次 fsync。金融类业务必须双一,
普通业务可以折中成sync_binlog=100+innodb_flush_log_at_trx_commit=2。

4.2 定期刷出并异地保存 binlog

FLUSH LOGS;-- 切一个 binlog,老的就可以拿去备份了(命令行:mysqladmin flush-logs)

备份 binlog 的最简做法:定时把已写完的 binlog 文件 rsync 到备份机。
更稳妥的是用mysqlbinlog --read-from-remote-server实时拉取(相当于一个轻量 binlog server)。

4.3 时间点恢复(PITR)完整流程

场景:周日 02:00 做全备,周三 14:30 有人执行了UPDATE orders SET status=0忘加 WHERE。
要恢复到 14:29。

# 1. 恢复全备(数据回到周日 02:00)systemctl stop mysqld;rm-rf/var/lib/mysql/* xtrabackup --copy-back --target-dir=/backup/full;chown-Rmysql:mysql /var/lib/mysql# 2. 先隔离业务!用 --skip-networking 启动,或改防火墙,别让应用连进来systemctl start mysqld --skip-networking# 3. 找到全备对应的 binlog 位点cat/backup/full/xtrabackup_binlog_info# mysql-bin.000042 197362# 4. 定位误操作位置(ROW 格式要 decode 才看得懂)mysqlbinlog --base64-output=decode-rows-v--start-position=197362\/data/mysql/mysql-bin.000042|grep-n-B5-A5"UPDATE \`orders\`"# 5. 假设误操作位点在 8934201,恢复到它之前(stop-position 是开区间)mysqlbinlog --start-position=197362--stop-position=8934200\/data/mysql/mysql-bin.000042 /data/mysql/mysql-bin.000043|mysql-uadmin-p# 也可以按时间:--start-datetime / --stop-datetime='2024-06-05 14:29:59'# 6. 校验数据,确认无误后再开放业务

关键注意点:一定要先隔离业务再恢复;--stop-position是开区间,要停在误操作的前一个位置;
多个 binlog 文件按顺序写在一条命令里即可;用 GTID 的库加--skip-gtids避免冲突。

4.4 只回滚一条误操作(闪回思路)

全库 PITR 太重时,可以只把误操作"反向"执行。
ROW 格式下UPDATE的 binlog 同时有 before image 和 after image,
用binlog2sql这类工具能自动生成反向 SQL:

python binlog2sql.py-h127.0.0.1-uadmin-p'***'--start-file='mysql-bin.000042'\--start-datetime='2024-06-05 14:30:00'--stop-datetime='2024-06-05 14:31:00'-B# -B 生成回滚 SQL

⚠️ 前提是binlog_row_image=FULL,否则 before image 不全,生成不了反向 SQL——这也是前文强调要设 FULL 的原因。

五、三种方案怎么选

场景推荐方案理由
小库(< 50GB),跨平台/跨版本迁移mysqldump逻辑备份兼容性最好
中等库(50GB~500GB),生产主备份XtraBackup 全备 + 增量恢复快、锁窗口短
大库(> 500GB)XtraBackup + 延迟从库靠延迟从库把 RTO 压到分钟级
只想要逻辑备份但嫌慢mydumper / myloader多线程
快速建从库XtraBackup 或 Clone Plugin直接拷数据 + 位点
需要恢复到任意秒上面任意一种 + binlogbinlog 才是 RPO 的保障
归档历史分区mysqldump +--where或SELECT INTO OUTFILE粒度最灵活

额外强烈推荐:延迟从库(Delayed Replica)。对付"误删数据"这类人为事故,它比任何备份都快:

STOP REPLICA;-- 从库上设置延迟 1 小时CHANGEREPLICATIONSOURCETOSOURCE_DELAY=3600;STARTREPLICA;-- 出事后把从库追到误操作前一秒STARTREPLICA UNTIL SOURCE_LOG_FILE='mysql-bin.000042',SOURCE_LOG_POS=8934200;

(5.7 用的是STOP SLAVE/CHANGE MASTER TO MASTER_DELAY/START SLAVE UNTIL。)

六、一套可以直接抄的备份策略

#!/bin/bash# /usr/local/bin/mysql_backup.sh —— 周日全备,其余日子增量set-euopipefailDATE=$(date+%F);DOW=$(date+%u);BASE=/backup/mysql;USER=admin;PASS='***'if["$DOW"-eq7];then# 全备TARGET=${BASE}/full_${DATE};rm-rf"${BASE}/inc_"* xtrabackup--backup--user=${USER}--password=${PASS}--target-dir="${TARGET}"xtrabackup--prepare--target-dir="${TARGET}"# 提前 prepare,缩短 RTOelse# 增量:基于上一次增量,没有就基于全备BASEDIR=$(ls-d${BASE}/inc_*2>/dev/null|tail-1)BASEDIR=${BASEDIR:-$(ls -d ${BASE}/full_*|tail-1)}TARGET=${BASE}/inc_${DATE}xtrabackup--backup--user=${USER}--password=${PASS}--target-dir="${TARGET}"\--incremental-basedir="${BASEDIR}"firsync-a--delete/data/mysql/mysql-bin.* backup@10.0.0.9::mysql-binlog/# binlog 异地find${BASE}-maxdepth1-typed-mtime+30-execrm-rf{}\;# 保留 30 天echo"$(date)backup${TARGET}done">>/var/log/mysql_backup.log

配套的监控告警:备份是否成功(退出码 + 日志关键字)、备份文件大小是否合理
(突然变小通常是出了大问题)、备份耗时趋势、最近一次成功备份距现在多久(超过 48 小时必须告警)。

七、恢复演练:别跳过这一步

每季度至少做一次:找一台空闲机器装同版本 MySQL → 用最近的备份完整恢复(含增量 + binlog)→
记录总耗时,这就是你的真实 RTO→ 抽样校验数据 → 把 RTO 写进文档跟业务容忍度对齐。

CHECKSUMTABLEorders;-- 校验用SELECTCOUNT(*),MAX(id),MAX(created_at)FROMorders;

⚠️ 演练中最常发现的问题:备份脚本里的密码早就过期了(一直在"假备份")、
备份目录磁盘满了只有空文件、增量链的--incremental-basedir指错导致链断、
恢复后才想起备份机的 MySQL 版本和数据目录不兼容。

八、常见误区

误区 1:有了主从复制就不用备份。——主库上一条DROP TABLE毫秒级同步到从库,复制不是备份,它只保证冗余,不防误操作。

误区 2:备份文件生成了就等于备份成功。——没恢复过就不知道它是否可用,"备份了 3 年第一次恢复发现全是空文件"是真实案例。

误区 3:binlog 随便设个过期时间就行。——binlog 保留时间必须≥ 全备周期;7 天一次全备却只留 3 天 binlog,中间 4 天就是恢复不了的空洞。

误区 4:--single-transaction万能。——库里有 MyISAM 表、或备份期间有 DDL,一致性就不成立。

误区 5:XtraBackup 增量 prepare 时全部加--apply-log-only。——最后一次不能加,否则未提交事务不回滚。

误区 6:恢复完直接开放业务。——先隔离校验再放流量,恢复现场被二次污染是真实发生过的。

误区 7:备份和原始数据放同一块盘。——磁盘一坏两边一起没。遵循3-2-1 原则:3 份副本、2 种介质、1 份异地。

小结

  • RPO 和 RTO 决定备份方案,先跟业务对齐这两个数字再谈工具
  • 三种备份层次:逻辑备份(mysqldump/mydumper)、物理备份(XtraBackup/Clone)、binlog 增量
  • mysqldump 必备参数:--single-transaction --master-data=2 --flush-logs --routines --triggers --events --hex-blob
  • mysqldump 的弱点是恢复慢(要重放 SQL + 建索引),大库请用 XtraBackup
  • XtraBackup 靠"拷数据文件 + 并行追 redo"实现热备,恢复时 prepare 相当于一次崩溃恢复
  • 增量 prepare 口诀:除最后一次外,全部加--apply-log-only
  • 出事后看xtrabackup_binlog_info拿位点,再用mysqlbinlog --start-position/--stop-position追平
  • binlog 才是把 RPO 压到秒级的关键:binlog_format=ROW+binlog_row_image=FULL+ 双一 + 过期时间 ≥ 全备周期
  • 人为误删的克星是延迟从库(SOURCE_DELAY)和 binlog 闪回工具
  • 复制不是备份;备份必须异地;必须定期做恢复演练并测出真实 RTO

下一篇聊生产关键参数调优——备份决定了你能不能活下来,参数决定了你能不能跑得稳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 2:51:17

Hadoop实战:用MapReduce和朴素贝叶斯构建用户性别预测模型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 2:50:55

混合结构总体最小二乘法求解空间直线拟合

本文针对的是这样一项事情, 就是人们不能直接把最小二乘法或者是总体最小二乘法拿来直接用于求解空间直线的拟合问题, 于是该篇文章就提出了一种算法, 这种算法是基于混合结构的总体最小二乘法的, 其目的就是为了实现空间直线的拟合。先把空间直线的参数方程, 变成空间直线的通…

作者头像 李华
网站建设 2026/10/10 2:50:44

单片机毕设项目:基于STM32的智能空气监测与自适应通风治理装置设计 基于物联网的人居环境多指标远程巡检与安全预警系统设计(030120)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/10/10 2:49:08

“测量技术:亚像素精度、1D/2D/3D”的核心,是把图像中的“像素坐标”转化为“物理尺寸”的精度阶梯

“测量技术&#xff1a;亚像素精度、1D/2D/3D”的核心&#xff0c;是把图像中的“像素坐标”转化为“物理尺寸”的精度阶梯。亚像素是手段&#xff0c;1D/2D/3D是维度&#xff0c;精度是贯穿其中的目标。 亚像素精度&#xff1a;突破“像素”的物理极限 像素是数字图像的最小单…

作者头像 李华
网站建设 2026/10/10 2:48:12

网盘程序升级:无感知备份与增量同步技术实践

1. 一次数据丢失事故&#xff0c;逼出来的"无感知备份"需求上个月帮一个做制造设备的团队看服务器&#xff0c;对方IT主管打开共享盘的时候&#xff0c;发现某销售小组的方案文件夹空了三天。翻日志才知道&#xff0c;不是病毒&#xff0c;不是硬盘故障&#xff0c;是…

作者头像 李华