延迟从库不能自动防误删,仅提供可干预时间窗口;必须提前配置read_only/super_read_only、停sql线程后再设master_delay、监控sql_remaining_delay而非seconds_behind_master,gtid模式下禁用sql_slave_skip_counter。

不能靠延迟从库“自动防误删”,它只提供一个可干预的时间窗口;必须提前配好、监控到位、响应及时,否则误删一执行,从库立刻跟上,数据就没了。
STOP SLAVE SQL_THREAD 是前置硬性条件
直接运行 CHANGE MASTER TO MASTER_DELAY = 3600 会报错 ERROR 3085 (HY000): This operation cannot be performed with a running slave sql thread——MySQL 强制要求先停 SQL 线程。
- 只停 SQL 线程:
STOP SLAVE SQL_THREAD;(IO 线程继续拉 binlog,保证 relay log 不断) - 再设延迟:
CHANGE MASTER TO MASTER_DELAY = 3600; - 最后重启 SQL 线程:
START SLAVE SQL_THREAD; - 如果从库已运行一段时间,
CHANGE MASTER TO会清空当前位点,务必提前用SHOW SLAVE STATUS\G记下Master_Log_File和Read_Master_Log_Pos,并在CHANGE MASTER TO中显式补全,否则可能从 binlog 开头重放
监控必须盯紧 SQL_Remaining_Delay,不是 Seconds_Behind_Master
Seconds_Behind_Master 是总滞后秒数,不反映你设的延迟是否真在生效;真正决定抢救窗口是否还在的,是 SQL_Remaining_Delay 字段——它是个倒计时,只有 SQL 线程卡在延迟队列里时才非 NULL。
- 大事务正在执行(如长 UPDATE),
Seconds_Behind_Master飙到 10000+,但SQL_Remaining_Delay仍是 3600 → 正常,延迟仍在 -
Seconds_Behind_Master = 0,但SQL_Remaining_Delay = 3590→ 实际仍在延迟中,只是没积压其他事件 - 监控脚本若只查
Seconds_Behind_Master,会误判延迟失效,错过抢救时机
GTID 模式下严禁用 sql_slave_skip_counter
启用了 gtid_mode = ON 的生产环境,SET GLOBAL sql_slave_skip_counter = 1 会破坏 GTID 集合一致性,导致复制中断甚至数据错乱。
- 误删发生后,正确做法是:
STOP SLAVE SQL_THREAD; - 用
mysqlbinlog解析中继日志或主库 binlog,定位到误删前最后一个事务的 GTID - 再用
START SLAVE UNTIL SQL_AFTER_GTIDS = 'xxx:yyy'精确回放到那个 GTID - 导出数据后恢复主库,整个过程不碰
sql_slave_skip_counter
read_only 和 super_read_only 必须启用
延迟从库若没开 read_only = ON,运维连上去随手 DROP TABLE,延迟就彻底失去意义;而 super_read_only = ON 能防止有 SUPER 权限的用户绕过 read_only 写入。
-
SET GLOBAL read_only = ON;(普通用户无法写) -
SET GLOBAL super_read_only = ON;(连 root 也无法写,除非先关它) - 这两项必须写进配置文件
my.cnf并重启生效,避免重启后失效 - 别信“反正只读从库没人连”,生产环境总有临时排查连上去的场景,权限锁死是底线
延迟从库的价值不在“慢”,而在“可控暂停”——它不替你判断哪条语句危险,只确保你有几分钟时间去执行 STOP SLAVE SQL_THREAD、查位点、导数据。所有配置都得在误操作发生前完成,事后补救毫无意义。











