mysqldump 和 xtrabackup 的区别、场景与常见问题
mysqldump是逻辑备份工具,导出的是 SQL 语句。xtrabackup是物理备份工具,备份的是 MySQL 底层数据文件。
简单理解:
text
mysqldump = 把数据库导出成 SQL 文件
xtrabackup = 给 MySQL 数据文件做一份一致性快照
一、核心区别
| 对比点 | mysqldump | xtrabackup |
|---|---|---|
| 备份类型 | 逻辑备份 | 物理备份 |
| 备份内容 | SQL 语句,如 CREATE TABLE、INSERT | MySQL 数据文件、表空间、redo log、元数据 |
| 备份粒度 | 库、表、部分数据都方便 | 更适合整个实例或大范围备份 |
| 恢复方式 | 执行 SQL 重新导入 | 拷贝物理文件回 MySQL 数据目录 |
| 备份速度 | 小库可以,大库较慢 | 大库更快 |
| 恢复速度 | 慢,尤其是大表和索引多的库 | 快,接近文件级恢复 |
| 可读性 | SQL 文件可读、可修改 | 物理文件不可直接阅读 |
| 跨版本能力 | 较好,适合迁移 | 较弱,依赖 MySQL 和 XtraBackup 版本 |
| 增量备份 | 原生命令不擅长 | 原生支持 |
| 典型用途 | 导数据、迁移、单表恢复、临时备份 | 生产大库备份、灾备、快速恢复、搭建从库 |
1. 备份层级不同
mysqldump 工作在 SQL 层。它连接 MySQL,把库表结构和数据导出成 SQL 文本。
导出的内容大致类似:
sql
CREATE TABLE users (
id bigint primary key,
name varchar(64)
);
INSERT INTO users VALUES (1, 'Alice');
INSERT INTO users VALUES (2, 'Bob');
所以 mysqldump 更像是把数据库重新描述一遍。恢复时,就是让 MySQL 再执行这些 SQL。
xtrabackup 工作在存储文件层。它备份的是 MySQL 的数据文件和日志文件,例如:
text
ibdata1
*.ibd
undo log
redo log
xtrabackup_checkpoints
xtrabackup_binlog_info
2. 恢复方式不同
mysqldump 恢复时,需要重新执行 SQL:
bash
mysql -u root -p app_db < app_db.sql
这个过程会重新建表、插入数据、维护索引。数据量越大,恢复越慢。
xtrabackup 恢复时,需要先 prepare,再把物理文件拷贝回 MySQL 的 datadir:
bash
xtrabackup --prepare --target-dir=/backup/mysql/full
xtrabackup --copy-back --target-dir=/backup/mysql/full
它不需要重新执行大量 INSERT,所以恢复整个实例通常比 mysqldump 快很多。
3. 一致性机制不同
mysqldump 对 InnoDB 表通常使用:
bash
mysqldump --single-transaction --quick app_db > app_db.sql
--single-transaction 会开启一个一致性读事务,利用 InnoDB 的 MVCC 机制导出同一时间点的数据。
但要注意:
- 主要适用于 InnoDB。
- 对 MyISAM、MEMORY 这类非事务表不保证一致性。
- 备份期间不建议执行
ALTER TABLE、DROP TABLE、TRUNCATE TABLE等 DDL。 - 大库备份时间长,会形成长事务,可能影响 undo 清理。
xtrabackup 的一致性方式不同。它一边复制数据文件,一边记录备份过程中产生的 redo log。备份完成后执行:
bash
xtrabackup --prepare --target-dir=/backup/mysql/full
prepare 会应用 redo log,把备份恢复到一致状态。这个过程类似 MySQL 崩溃恢复。
4. 对线上业务的影响不同
mysqldump 是通过 SQL 查询把数据读出来。它可能带来:
- 大量查询压力。
- 大量网络传输。
- 大表扫描。
- 客户端和服务端 CPU 消耗。
- 长事务影响 InnoDB purge。
- 恢复时目标库压力很大。
xtrabackup 主要读取底层数据文件。它可能带来:
- 磁盘 IO 压力。
- 文件复制压力。
- prepare 阶段的 CPU 和 IO 压力。
- 对 SQL 层的影响相对较小。
因此,生产大库通常更适合用 xtrabackup 做主备份。
5. 可移植性不同
mysqldump 是 SQL 文本,可移植性较好,适合:
- 跨机器迁移。
- 跨操作系统迁移。
- 跨 MySQL 小版本迁移。
- 某些跨大版本迁移。
- 修改 SQL 后再导入。
- 导入到兼容 MySQL 协议的数据库。
xtrabackup 是物理备份,可移植性较弱。它依赖:
- MySQL 主版本。
- Percona XtraBackup 版本。
- InnoDB 文件格式。
- redo/undo log 格式。
- MySQL 数据字典格式。
- 加密、压缩、表空间配置。
所以 xtrabackup 更适合同类 MySQL 实例之间恢复,不适合作为跨版本迁移工具。
6. 粒度不同
mysqldump 的备份粒度很灵活。
备份所有库:
bash
mysqldump -u root -p --all-databases > all.sql
备份单个库:
bash
mysqldump -u root -p app_db > app_db.sql
备份单张表:
bash
mysqldump -u root -p app_db users > users.sql
备份部分数据:
bash
mysqldump -u root -p app_db orders \
--where="created_at >= '2026-06-01'" > orders_june.sql
xtrabackup 更适合整个实例或物理层备份。它也有部分备份和表级恢复相关能力,但操作复杂,不如 mysqldump 直观。
二、适合使用 mysqldump 的场景
mysqldump 更适合逻辑层面的导出、迁移和局部恢复。
1. 小库日常备份
如果数据库只有几百 MB 到几 GB,恢复时间要求不高,用 mysqldump 简单直接。
bash
mysqldump -u backup -p \
--single-transaction \
--quick \
--routines \
--events \
--triggers \
app_db > app_db.sql
适合:
- 小型业务系统。
- 公司内部系统。
- WordPress、论坛、小型 SaaS。
- 想保留一份可读 SQL 文件。
2. 单表备份
如果上线前只修改某一张表,先备份这张表很方便。
bash
mysqldump -u root -p app_db important_table > important_table.sql
如果需要恢复:
bash
mysql -u root -p app_db < important_table.sql
3. 部分数据导出
例如只导出 2026 年 6 月之后的订单:
bash
mysqldump -u backup -p app_db orders \
--where="created_at >= '2026-06-01'" > orders_june.sql
这类按条件导出数据的场景,mysqldump 比 xtrabackup 更合适。
4. 跨环境迁移
例如从生产环境导数据到测试环境:
bash
mysqldump -u root -p \
--single-transaction \
--routines \
--events \
--triggers \
app_db > app_db.sql
mysql -u root -p app_db < app_db.sql
适合:
- 生产导测试。
- 老服务器迁移到新服务器。
- 跨 MySQL 小版本迁移。
- 修改表结构或字符集后重新导入。
5. 需要人工查看或修改备份内容
因为 .sql 文件可以直接打开,所以可以:
- 查看表结构。
- 查看部分数据。
- 删除不需要的 SQL。
- 只提取某几张表。
- 修改部分建表语句后再导入。
三、适合使用 xtrabackup 的场景
xtrabackup 更适合生产级、大数据量、要求快速恢复的场景。
1. 大库全量备份
几十 GB、几百 GB、TB 级 MySQL 实例,通常更适合用 xtrabackup。
bash
xtrabackup --backup \
--target-dir=/backup/mysql/full-2026-06-14 \
--user=backup \
--password
备份完成后必须执行:
bash
xtrabackup --prepare \
--target-dir=/backup/mysql/full-2026-06-14
2. 大库快速恢复
恢复流程通常是:
bash
systemctl stop mysqld
mv /var/lib/mysql /var/lib/mysql.bak
mkdir /var/lib/mysql
xtrabackup --copy-back \
--target-dir=/backup/mysql/full-2026-06-14 \
--datadir=/var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
相比 mysqldump 重新执行 SQL,xtrabackup 对整个实例的恢复速度通常更快。
3. 全量加增量备份
这是 xtrabackup 在生产中的典型用法。
全量备份:
bash
xtrabackup --backup \
--target-dir=/backup/mysql/base \
--user=backup \
--password
第一次增量:
bash
xtrabackup --backup \
--target-dir=/backup/mysql/inc1 \
--incremental-basedir=/backup/mysql/base \
--user=backup \
--password
第二次增量:
bash
xtrabackup --backup \
--target-dir=/backup/mysql/inc2 \
--incremental-basedir=/backup/mysql/inc1 \
--user=backup \
--password
典型策略:
text
周日:全量备份
周一:增量备份
周二:增量备份
周三:增量备份
...
4. 初始化从库
生产库数据量较大时,用 mysqldump 搭建从库会比较慢。xtrabackup 可以直接复制主库的一份物理数据,再根据 GTID 或 binlog 位点启动复制。
适合:
- 新增只读从库。
- 初始化灾备节点。
- 搭建复制集群。
- 大库迁移前准备副本。
5. 灾难恢复
生产环境中常见组合是:
text
xtrabackup 全量备份
+ xtrabackup 增量备份
+ MySQL binlog
= 恢复到指定时间点
例如误删数据发生在 10:30,可以先恢复最近一次全量和增量备份,再回放 binlog 到 10:29:59。
四、使用中常见问题:mysqldump
1. 大库备份慢,恢复更慢
mysqldump 恢复本质上是重新执行大量 SQL。大表、大索引场景下,恢复会非常慢。
常见表现:
text
备份几个小时
恢复十几个小时
导入时 CPU、IO 很高
建议:
- 大库不要把
mysqldump当主备份方案。 - 使用
xtrabackup做主备份。 - 只 dump 必要的库、表或数据。
2. 忘记加 --single-transaction
如果 InnoDB 表备份不加 --single-transaction,多个表可能不是同一个时间点的数据。
推荐:
bash
mysqldump -u backup -p \
--single-transaction \
--quick \
app_db > app_db.sql
3. 大表导出占用客户端内存
不加 --quick 时,客户端可能一次性缓存大量结果。
推荐:
bash
mysqldump -u backup -p \
--single-transaction \
--quick \
app_db > app_db.sql
4. 没有导出存储过程、事件、触发器
很多人只写:
bash
mysqldump -u root -p app_db > app_db.sql
恢复后可能发现存储过程、事件没有了。
推荐显式加:
bash
--routines --events --triggers
完整示例:
bash
mysqldump -u backup -p \
--single-transaction \
--quick \
--routines \
--events \
--triggers \
app_db > app_db.sql
5. 备份期间执行 DDL 导致失败或不一致
备份期间如果有人执行:
sql
ALTER TABLE orders ADD COLUMN remark varchar(255);
DROP TABLE users;
TRUNCATE TABLE logs;
可能导致 dump 报错,或者导出的结构和数据不一致。
建议:
- 备份窗口避免执行 DDL。
- 生产变更和备份时间错开。
- 大库使用
xtrabackup做主备份。
6. 字符集问题
导入后中文乱码,常见原因是导出和导入时字符集不一致。
可以显式指定:
bash
mysqldump -u root -p \
--default-character-set=utf8mb4 \
app_db > app_db.sql
mysql -u root -p \
--default-character-set=utf8mb4 \
app_db < app_db.sql
7. GTID 导入问题
GTID 环境下导入 dump,可能遇到 GTID_PURGED 相关报错。
常见处理:
bash
mysqldump --set-gtid-purged=OFF ...
是否关闭要看复制和恢复方案,不能无脑固定。
五、使用中常见问题:xtrabackup
1. 版本不匹配
这是 xtrabackup 最常见的问题之一。
例如:
text
MySQL 8.0 通常使用 XtraBackup 8.0
MySQL 8.4 通常使用 XtraBackup 8.4
xtrabackup 是物理备份,强依赖 InnoDB 文件格式、redo log 格式、数据字典格式。版本不匹配可能导致备份失败、prepare 失败或恢复后无法启动。
2. 忘记 prepare
只执行:
bash
xtrabackup --backup --target-dir=/backup/mysql/full
然后直接恢复,是不完整的。
必须先执行:
bash
xtrabackup --prepare --target-dir=/backup/mysql/full
prepare 会应用 redo log,让备份文件达到一致状态。
3. 恢复目录不是空目录
copy-back 时,目标 datadir 通常需要是空目录。
错误做法是旧数据还在 /var/lib/mysql 里就直接恢复。
推荐流程:
bash
systemctl stop mysqld
mv /var/lib/mysql /var/lib/mysql.bak
mkdir /var/lib/mysql
xtrabackup --copy-back \
--target-dir=/backup/mysql/full \
--datadir=/var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
4. 文件权限不对
恢复后如果忘记:
bash
chown -R mysql:mysql /var/lib/mysql
MySQL 可能启动失败,错误日志中会出现权限相关信息。
5. 磁盘空间不够
xtrabackup 备份和恢复时需要提前评估空间,尤其是:
- 全量备份目录。
- 增量备份目录。
- 压缩和解压临时空间。
- prepare 过程中产生的文件。
- 恢复时新的
datadir空间。
不要只按当前数据目录大小估算,应该预留额外空间。
6. 备份期间 IO 压力大
xtrabackup 对 SQL 层影响较小,但会大量读取数据文件。
可能表现:
text
数据库响应变慢
磁盘 util 飙高
备份耗时变长
可以考虑:
bash
xtrabackup --backup \
--parallel=4 \
--throttle=100 \
--target-dir=/backup/mysql/full \
--user=backup \
--password
实际参数需要根据磁盘性能和业务压力调整。
7. 增量 prepare 顺序错误
增量恢复必须按顺序应用:
text
base -> inc1 -> inc2 -> inc3
示例:
bash
xtrabackup --prepare --apply-log-only \
--target-dir=/backup/mysql/base
xtrabackup --prepare --apply-log-only \
--target-dir=/backup/mysql/base \
--incremental-dir=/backup/mysql/inc1
xtrabackup --prepare \
--target-dir=/backup/mysql/base \
--incremental-dir=/backup/mysql/inc2
前面的增量步骤通常加 --apply-log-only,最后一步不加。顺序错误可能导致备份不可用。
六、实际生产怎么选
| 场景 | 推荐 |
|---|---|
| 备份一个小库 | mysqldump |
| 备份一张表 | mysqldump |
| 导出部分数据 | mysqldump |
| 给开发测试数据 | mysqldump |
| 跨版本迁移 | mysqldump |
| 几十 GB 以上生产库 | xtrabackup |
| 几百 GB 或 TB 级库 | xtrabackup |
| 快速恢复整个实例 | xtrabackup |
| 搭建从库 | xtrabackup |
| 做增量备份 | xtrabackup |
| 恢复到某个时间点 | xtrabackup + binlog |
比较推荐的生产备份体系:
text
每天或每周:xtrabackup 全量备份
每天或每小时:xtrabackup 增量备份
持续保留:MySQL binlog
临时导出:mysqldump
这样可以同时覆盖:
- 整库灾难恢复。
- 大库快速恢复。
- 指定时间点恢复。
- 单表或部分数据导出。
- 跨环境迁移和测试数据准备。