从库执行flush tables with read lock会报error 1290,因read_only=on时该命令被禁止;它不阻塞sql线程,无法保证数据静止,真正安全暂停同步需先set global super_read_only = on再stop slave。

从库执行 FLUSH TABLES WITH READ LOCK 会报错或无效
因为从库默认不支持全局只读锁(FLUSH TABLES WITH READ LOCK)的语义——它不是“禁止写入”,而是“等待SQL线程回放完所有中继日志后暂停写入”。但这个命令在从库上实际会触发错误:ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement,尤其当配置了 read_only=ON 时。更关键的是,该命令不会阻塞SQL线程本身,所以即使锁成功,从库仍可能继续应用relay log,导致你误以为“已停写”,实则数据仍在变更。
read_only 和 super_read_only 的行为差异直接影响锁感知
从库应始终启用 read_only=ON,但这只是对普通用户生效;DBA 或拥有 SUPER 权限的账号仍可写。若需真正阻止所有写操作(包括复制线程以外的任何写),必须设 super_read_only=ON(MySQL 5.7.8+)。注意:一旦开启 super_read_only,连 STOP SLAVE 都会被拒绝,除非先临时关闭它。常见误操作是只开 read_only 就以为万无一失,结果同事用 root 账号直接 INSERT 到从库,破坏一致性。
从库没有 binlog 写权限,LOCK TABLES 不影响复制链路
主库上 LOCK TABLES ... WRITE 会阻塞其他会话并禁止 binlog 记录(除非显式 SET sql_log_bin=1),但从库即使执行 LOCK TABLES t1 WRITE,也仅锁定本地表,不影响 IO/SQL 线程——SQL线程照常回放 relay log,可能立刻与你刚加的锁冲突,报 ERROR 1205 (40001): Deadlock found when trying to get lock。这不是 bug,而是设计使然:从库的锁机制与复制逻辑完全解耦,它不参与 binlog 生成,也不协调事务提交顺序。
真正安全的“暂停同步”只能靠 STOP SLAVE + super_read_only
想让从库彻底静止、可验证一致性,唯一可靠路径是:
- 先确认 SQL 线程已追平:
Seconds_Behind_Master = 0且Slave_SQL_Running_State显示Slave has read all relay log - 执行
SET GLOBAL super_read_only = ON(需先关read_only若已开) - 再执行
STOP SLAVE—— 此时 IO 和 SQL 线程都停,且无任何用户能写
漏掉 super_read_only 这步,就等于留了个 root 后门;只停 slave 不设只读,DBA 登录后仍可任意改数据。生产环境做一致性校验或备份前,这两步缺一不可。











