跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

mysql主从同步时执行计划不一致_统一主从环境配置与统计信息

主从EXPLAIN结果不同源于优化器决策依据差异:统计信息陈旧、optimizer_switch不一致、read_only不限制临时表、binlog_format非ROW等导致执行计划漂移。 为什么主从上
EXPLAIN
结果不一样? 主从同步本身不保证执行计划一致——MySQL 优化器基于统计信息、索引分布、配置参数和实际数据分布做决策,而这些在主从间天然可能不同。最常见诱因是:从库没开
innodb_stats_persistent
,或
innodb_stats_auto_recalc
关闭后统计信息长期未更新,导致从库用的是过期直方图或采样估算。 实操建议: 主从都设
innodb_stats_persistent = ON
,并确认
innodb_stats_auto_recalc = ON
(5.6.6+ 默认开启,但升级或手动配置时容易漏) 检查
information_schema.INNODB_TABLESTATS
和
INNODB_INDEXSTATS
表的
last_update
字段,对比主从是否严重滞后 若业务允许,可在从库执行
ANALYZE TABLE
强制刷新(注意:会加表级读锁,大表慎用)
slave_parallel_type = LOGICAL_CLOCK
下为何还卡在单线程回放? 即使开了并行复制,只要事务之间存在逻辑依赖(比如同一张表的写操作被分到不同事务但有锁等待),从库仍会退化为串行回放。更隐蔽的问题是:主库 binlog_format 不是
ROW
,或用了
STATEMENT
模式混写,导致 GTID event 分组失效,
LOGICAL_CLOCK
失去判断依据。 实操建议: 确认主库
binlog_format = ROW
,且所有写入(包括应用层、中间件、定时任务)都不绕过该设置 查从库状态:
SHOW SLAVE STATUS\G
中看
Slave_SQL_Running_State
是否频繁出现
Waiting for preceding transaction to commit
临时启用
slave_preserve_commit_order = ON
(8.0.13+)可缓解乱序提交引发的阻塞,但会轻微增加延迟 从库
read_only = ON
但还是能写进临时表?
read_only
默认不限制
TEMPORARY
表创建,也不阻止
CREATE TEMPORARY TABLE
或
INSERT INTO ... SELECT
这类隐式临时表操作。这类行为不会写入 binlog,但会污染从库的查询缓存、影响
EXPLAIN
的“真实”执行路径(比如优化器误判临时表大小),进而导致主从执行计划偏差。 MySQL(Linux) MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。 下载 实操建议: 严格设置
super_read_only = ON
(需先开
read_only
),它才真正禁止所有写操作,包括临时表 监控从库是否频繁出现
Created_tmp_tables
增长(用
SHOW GLOBAL STATUS LIKE 'Created_tmp%'
),异常高说明有应用在从库跑分析类 SQL 应用层避免在从库执行
SELECT ... INTO OUTFILE
、
SELECT ... INTO DUMPFILE
等带写副作用的语句 主从
optimizer_switch
不一致引发计划漂移 哪怕 MySQL 版本相同,
optimizer_switch
默认值也可能因编译选项或补丁版本微调而不同。比如
index_merge=on
在主库生效、从库关闭,就可能导致主走索引合并、从走全表扫描;又或者
condition_fanout_filter=off
导致从库低估连接结果集大小,选错驱动表。 实操建议: 主从都显式设置统一值:
SET PERSIST optimizer_switch = 'index_merge=on,index_merge_union=on,...';
(8.0.22+ 支持
PERSIST
,否则改
my.cnf
并重启) 用
SELECT @@optimizer_switch;
对比主从输出,逐项核对,尤其关注
materialization
、
semijoin
、
loosescan
这些影响较大的开关 上线前在从库执行
EXPLAIN FORMAT=TREE
(8.0.16+)对比主库输出,比传统
EXPLAIN
更直观暴露优化器决策差异 执行计划不一致从来不是孤立现象,它背后往往是统计信息陈旧、配置项错位、或写操作逃逸了只读约束。最容易被忽略的,是那些“看起来不影响同步”的配置——比如
tmp_table_size
主从不一致,会让同样一条
GROUP BY
在从库被迫落磁盘,触发不同的排序算法选择,最终改变执行路径。

相关文章