xtrabackup仅支持innodb/xtradb热备,因其依赖redo日志和lsn机制;myisam无崩溃恢复能力,xtrabackup会跳过其文件(.myd/.myi),不加锁导致备份不一致,必须用innobackupex加全局读锁才能安全备份混合引擎库。

不能直接用 xtrabackup 安全备份混合引擎库(InnoDB + MyISAM)——它会跳过 MyISAM 表,且不加锁,导致数据不一致。
为什么 xtrabackup 不适合混合引擎备份
xtrabackup 专为 InnoDB/XtraDB 设计,只复制 ibdata1、.ibd 和 redo log;对 MyISAM 表(.frm、.MYD、.MYI)完全忽略。即使你手动拷贝 MyISAM 文件,也因无全局读锁而可能处于写入中途状态,恢复后查不到最新数据或报错 Table is marked as crashed。
- MyISAM 不支持崩溃恢复,必须靠
FLUSH TABLES WITH READ LOCK保证文件一致性 -
xtrabackup的--backup阶段默认不触发该锁(仅在最后短暂加锁获取 binlog 位点,但 MyISAM 文件早已复制完毕) - 官方明确说明:
xtrabackup不支持 MyISAM 备份;innobackupex才是为此设计的封装脚本(虽已废弃,但仍是混合场景唯一可行路径)
必须用 innobackupex(即使已弃用)
Percona 在 8.0+ 版本中移除了 innobackupex,但只要你的 MySQL 是 5.7/8.0 且含 MyISAM 表,就必须降级使用 XtraBackup 2.4(对应 innobackupex),否则无法安全备份混合库。
- 安装命令:
yum install percona-xtrabackup-24(CentOS/RHEL)或apt install percona-xtrabackup-24(Debian/Ubuntu) - 验证存在:
which innobackupex应返回路径;若提示 command not found,说明装的是 8.0+ 版本,得卸载重装 2.4 - 执行全备:
innobackupex --user=root --password='xxx' /data/backup/mixed—— 它会在备份开始时自动执行FLUSH TABLES WITH READ LOCK,等所有 MyISAM 表刷盘并锁住后,再复制文件,最后释放锁 - 注意:锁表时间 = 所有 MyISAM 表
FLUSH耗时,大 MyISAM 表会导致业务短暂只读,需避开高峰
--databases 指定库时仍要小心引擎混用
即使你只备份某几个库,只要其中任意一张表是 MyISAM,innobackupex 就会为整个备份过程加全局读锁——它不区分表引擎做局部锁。
- 错误写法:
innobackupex --databases='app_db' ...→ 若app_db含 MyISAM 表,仍锁全实例 - 正确做法:先确认目标库引擎分布:
SELECT table_schema,table_name,engine FROM information_schema.tables WHERE table_schema='app_db'; - 若全是 InnoDB,可放心用
xtrabackup --databases=app_db ...,零锁表 - 若混用,就老实用
innobackupex全库备份,或把 MyISAM 表迁走(如转为 ARCHIVE 或拆到单独实例)
prepare 和 restore 阶段没区别,但路径权限常被忽略
innobackupex 备份出的目录结构和 xtrabackup 一致,prepare 和 copy-back 命令完全相同,但实操中 80% 的失败发生在权限上。
-
--prepare必须用同一用户运行(通常是root),否则可能报Permission denied on xtrabackup_logfile -
--copy-back后,/var/lib/mysql下所有文件属主必须是mysql:mysql,且ibdata1等文件不能有 SELinux 上下文残留(RHEL/CentOS 上跑restorecon -Rv /var/lib/mysql) - MySQL 启动失败常见日志:
InnoDB: Operating system error number 13 in a file operation→ 几乎全是权限或 SELinux 问题
真正麻烦的从来不是命令怎么写,而是你根本不知道那张不起眼的 mysql.general_log(MyISAM 引擎)正在拖慢整个备份流程,还悄悄破坏一致性。混合引擎不是“能用就行”,是“要么全换 InnoDB,要么接受锁表代价”。











