MyISAM 表在 mysqldump 时会因表级锁导致备份失败,需用 --lock-tables=false 或迁移至 InnoDB;InnoDB 虽支持 --single-transaction 无锁备份,但混用引擎仍触发全局锁,物理备份工具 xtrabackup 不支持 MyISAM,在线备份必须按引擎分策略处理。

MyISAM 表在 mysqldump 时可能锁表导致备份失败
MyISAM 默认使用表级锁,mysqldump 在不加 --single-transaction 时会执行 FLUSH TABLES WITH READ LOCK,整个库只读,业务写入阻塞。若备份耗时长或中途断开,锁可能残留,引发雪崩。
实操建议:
- 强制指定
--lock-tables=false(仅对 MyISAM 有效,但需确保备份期间无 DDL) - 改用
mysqlhotcopy(已废弃,仅限 Perl 环境且要求本地文件系统权限) - 更稳妥的做法是迁移至 InnoDB——它支持
--single-transaction,备份全程无锁
InnoDB 的 --single-transaction 不等于完全无影响
--single-transaction 依赖 MVCC 快照,看似“零感知”,但实际有隐含限制:
- 仅对 InnoDB 表生效;若库中混有 MyISAM 表,仍会触发全局锁
- 备份开始后新创建的表不会被包含(事务快照基于 START TRANSACTION 时间点)
- 大事务未提交会导致快照无法清理,
ibdata1持续膨胀,甚至拖慢备份本身 - DDL 操作(如
ALTER TABLE)会隐式提交当前事务,中断快照一致性
验证是否真“无锁”:备份过程中执行 INSERT INTO t VALUES (1);,再查 SHOW PROCESSLIST,确认无 Waiting for table flush 类等待。
物理备份(xtrabackup)要求引擎必须是 InnoDB 或 XtraDB
innobackupex(现整合进 xtrabackup)本质是拷贝 ibdata1、.ibd 和 redo log,它跳过 MyISAM 的 .MYD/.MYI 文件——不是忽略,而是不支持在线复制。
- 混合引擎库用
xtrabackup备份,MyISAM 表只能靠mysqldump单独补全 -
--skip-non-innodb参数会静默跳过非 InnoDB 表,容易遗漏,务必配合mysql -e "SELECT ENGINE,TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='db_name';"核查 - 恢复时若存在 MyISAM 表,需先停库,拷贝
.frm+.MYD+.MYI,再启库——顺序错或权限不对直接报Table 't' doesn't exist
备份方案设计必须按引擎拆解策略,不能一刀切
一个库同时存在 InnoDB 和 MyISAM 表时,mysqldump 和 xtrabackup 都无法单命令覆盖全部。常见错误是只测了主表引擎,上线后某张日志表用 MyISAM,恢复时发现数据丢失。
- 定期运行
SELECT TABLE_SCHEMA, ENGINE, COUNT(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA, ENGINE;监控引擎分布 - 备份脚本里区分处理:
mysqldump --single-transaction导出 InnoDB,mysqldump --lock-tables导出 MyISAM(安排在低峰期) - 长期看,应推动 MyISAM 表迁移:除全文索引(5.6+ InnoDB 已支持)和极少数 GIS 场景外,InnoDB 全面优于 MyISAM
真正麻烦的不是备份命令怎么写,而是恢复时才发现某张表引擎和预期不一致——这时候 redo log 无效、.frm 匹配不上、甚至字符集定义都藏在 .MYD 二进制里。










