全局锁(ftwrl)会导致主库业务彻底停摆,所有写操作、事务提交及ddl被阻塞,引发请求超时、连接池堆积和上游熔断;从库执行则加剧主从延迟且锁残留风险高。

全局锁会让主库业务直接停摆
执行 FLUSH TABLES WITH READ LOCK 后,主库所有写操作(INSERT、UPDATE、DELETE)、事务提交、ALTER TABLE 等全部被阻塞。用户下单、余额变更、日志写入等关键路径会卡在数据库层,表现为请求超时或长时间等待。
- 不是“变慢”,是彻底阻塞——哪怕只有一条未提交的事务,
FTWRL也会等它结束才加锁 - 连接池里的空闲连接无法复用,新请求持续堆积,可能触发上游服务熔断
- 监控里
Threads_running会飙升,Com_commit归零,Innodb_row_lock_time无意义(因为根本没走到行锁)
从库上用全局锁会加剧主从延迟
从库执行 FTWRL 后,SQL 线程停止回放 binlog,但主库仍在持续写入。积压的 binlog 不会消失,解锁后必须顺序重放——而 MySQL 5.6 之前是单线程回放,延迟可能从秒级拉长到分钟甚至小时级。
- 用户在主库刚下单,从库查不到订单,前端反复刷新也看不到,体验断裂
- 如果备份耗时 20 分钟,binlog 积压量 ≈ 主库 20 分钟的写入总量
-
Seconds_Behind_Master在锁期间不更新(SQL 线程暂停),实际延迟远大于监控显示值
全局锁无法规避 DDL 导致的备份不一致
--single-transaction 能解决 DML 一致性,但防不住 DDL——比如备份中途执行 ALTER TABLE,可能导致表结构和数据快照错配。这时有人会想:“那我干脆用全局锁兜底”。但问题在于:
-
FTWRL本身不阻塞正在执行的 DDL;它只阻塞后续新发起的 DDL,而正在运行的 DDL 可能已修改元数据 - 如果备份工具(如
mysqldump)先 dump 表结构、再 dump 数据,中间恰好有DROP COLUMN,dump 出来的 SQL 可能含已删除字段,恢复时报错 - 真正安全的做法是:提前禁止 DDL(如临时撤掉 DBA 权限),而非依赖锁机制去“堵”
锁释放失败会导致从库长期只读
FTWRL 的释放依赖显式 UNLOCK TABLES 或客户端断连。但生产环境常有网络抖动、连接池异常关闭等情况,导致锁残留。
- 不同于
set global read_only = 1,FTWRL的锁状态不会因超时自动释放 - 锁残留后,
SHOW PROCESSLIST里看不到阻塞源,只能靠SELECT * FROM performance_schema.metadata_locks查(MySQL 5.7+) - 从库锁住不放,主从延迟持续扩大,且
READ_ONLY状态为 OFF,容易被误判为“正常”
真正麻烦的从来不是“要不要加锁”,而是“加了之后怎么确保它一定被释放”。任何依赖人工 UNLOCK TABLES 的流程,在无人值守的备份脚本里都是高危操作。











