从库加索引不会同步到主库。MySQL 复制基于 binlog,只同步 DML 和 DDL 执行结果,CREATE INDEX 等从库本地 DDL 不反写主库 binlog,不影响主从一致性,但需注意 GTID 兼容性、统计信息更新及命名规范等问题。

从库加索引会不会被主库同步过去
不会。MySQL 的复制是基于 binlog 的逻辑复制,只同步 DML(INSERT/UPDATE/DELETE)和 DDL(CREATE/ALTER/DROP)语句的执行结果,但 CREATE INDEX 这类 DDL 在从库上执行后,不会反向写入主库 binlog,更不会推送到其他从库。只要不在主库执行,就纯属从库本地操作。
常见错误现象:ERROR 1786 (HY000): Statement violates GTID consistency —— 这通常是因为开了 enforce_gtid_consistency=ON 且用了非事务性 DDL(老版本 MySQL 中 CREATE INDEX 默认是非事务的),但 5.7.26+ 和 8.0 已默认支持在线加索引并记入 GTID,只要不是用 ALGORITHM=COPY 强制降级,一般不触发该错。
- 使用场景:读多写少的报表库、BI 查询从库、历史归档从库,需要加速特定
WHERE或ORDER BY字段,但主库因写入压力或规范限制不能加 - 参数差异:
ALGORITHM=INPLACE比COPY更安全,避免锁表;LOCK=NONE可确保读写都不阻塞(需引擎支持,InnoDB 5.6+ 基本满足) - 性能影响:加索引本身会消耗从库 I/O 和 CPU,若从库已高负载,建议在低峰期操作;索引越多,INSERT/UPDATE 的回放延迟可能越明显(因为每个写操作要维护更多索引)
主库没索引但从库有,会不会导致复制中断
不会。复制中断只发生在 SQL 线程执行事件失败时,比如主库删了某列,从库还按旧结构更新——而索引纯属查询优化器使用的元数据,不参与 DML 执行逻辑。从库多几个索引,对 relay log 回放完全透明。
容易踩的坑:DROP INDEX 语句如果误在主库执行,会同步删掉从库索引;但反过来,从库删自己的索引,主库毫无感知。所以必须管住运维习惯:所有 DDL 变更走统一发布流程,避免手工直连从库执行 DROP INDEX 后忘记同步文档。
- 使用场景:A/B 测试不同索引策略、灰度上线新查询路径、临时支撑某个下游系统导出需求
- 兼容性注意:MySQL 5.6 不支持
ALTER TABLE …… ALGORITHM=INPLACE, LOCK=NONE加二级索引;8.0 则支持对全文索引、空间索引等更多类型在线操作 - 验证方法:加完后在从库查
SHOW INDEX FROM tbl_name,再对比主库输出,确认仅从库多出对应行
从库索引命名要不要和主库保持一致
没必要,甚至不建议。索引名只是元数据标识,不影响查询优化器选索引;但同名可能掩盖“主从索引实际结构不同”的风险。比如主库有个 idx_user_status 是 (status),从库想扩展为 (status, created_at),如果强行重名,后续排查 EXPLAIN 时容易误判。
实操建议直接用语义化后缀区分:
CREATE INDEX idx_user_status_created_at_ro ON users (status, created_at);
- 推荐命名规则:
idx_{table}_{col1}_{col2}_{purpose},其中ro表示 read-only 场景专用 - 避免用
uk_或pk_前缀——唯一索引 / 主键必须主从一致,否则 INSERT/UPDATE 可能报错 - 不要依赖索引名做自动化下线判断:有些 DBA 工具靠名字匹配清理索引,从库索引若混入相同命名规则,可能被误删
从库建完索引,查询为什么没走
大概率是优化器没选它,而不是索引无效。从库的 ANALYZE TABLE 不会自动触发,统计信息还是主库同步过来的老数据,尤其当从库数据量因延迟或过滤(如 replicate_do_table)与主库不一致时,执行计划更容易偏差。
关键动作只有两个:
- 手动在从库运行
ANALYZE TABLE tbl_name,强制更新统计信息(注意:这会短暂锁表读,但比OPTIMIZE轻量得多) - 用
EXPLAIN FORMAT=TREE(8.0)或EXPLAIN+SELECT实际查询,确认是否命中新建索引;别只看SHOW INDEX - 检查查询中字段是否被函数包裹,比如
WHERE DATE(created_at) = '2024-01-01',会导致索引失效——这类问题在从库更隐蔽,因为开发通常只在主库环境测 SQL
最常被忽略的一点:从库的 sort_buffer_size、read_buffer_size 等配置可能比主库小,导致原本能走索引的 ORDER BY 查询被迫用 filesort,看起来像“索引没生效”。调参前先看 SHOW PROFILE 或慢日志里的 Using filesort 提示。