是的,Navicat 默认使用 FLUSH TABLES WITH READ LOCK 全局读锁进行完整备份,锁持续至备份结束;应改用 --single-transaction 实现无锁一致性备份。

FLUSH TABLES WITH READ LOCK 是 MySQL 原生命令,Navicat 默认就用它——不是“能否设置”,而是“它已经在干这事”,且无法在界面里关掉。
Navicat 备份是否自动锁表?
是的,只要没做干预,Navicat 所有完整备份(含“结构+数据”)都会触发 FLUSH TABLES WITH READ LOCK。这不是可选功能,是它的默认行为逻辑:
- 它不区分引擎类型,哪怕全库都是 InnoDB,也默认加全局读锁
- 锁持续到整个备份结束(包括写入 SQL 文件、压缩等),不是只锁几秒
- 你看到业务接口卡住、
MySQL server has gone away、DML 请求堆积,基本就是这个锁在生效
为什么不能靠“备份前手动加锁”来增强一致性?
因为 Navicat 的锁机制已经是最强一致性保障了——但它代价太高。你不需要“再加一层锁”,你需要的是:
- ✅ 用
--single-transaction替代全局锁(对 InnoDB 表) - ❌ 不要试图在 Navicat 界面里找“启用锁表”开关——它没有;也不要用“备份前执行 SQL”功能手动跑
FLUSH TABLES WITH READ LOCK,那只会让锁时间更长、冲突更剧烈
如何验证当前备份到底有没有锁表?
打开备份生成的 SQL 文件,搜索开头几行:
- 如果看到
FLUSH TABLES WITH READ LOCK;和UNLOCK TABLES;—— 正在锁表 - 如果看到
START TRANSACTION WITH CONSISTENT SNAPSHOT;—— 已切换为 MVCC 快照,无锁
后者才是你要的结果,但必须通过包装脚本绕过 Navicat 默认调用逻辑才能达成。
容易被忽略的关键点
--single-transaction 生效的前提不是“Navicat 设置对了”,而是:
- MySQL 版本 ≥ 5.6
- 目标库中不能有 MyISAM 表(否则会自动降级回锁表)
- 没有长事务未提交(否则快照起始会被阻塞)
- 从库不能开了
read_only=ON(否则FLUSH TABLES WITH READ LOCK会被拒绝,备份直接失败)
这些条件缺一不可。很多人改了脚本却仍锁表,问题往往出在 MyISAM 表或未清理的事务上。











