主从复制、高可用与分库分表
单机 MySQL 在容量、性能与容灾上都有上限。复制用于扩展读能力与容灾,分库分表用于突破单机容量。本章讲清原理与权衡。
复制原理
MySQL 复制基于 binlog,三个关键线程:
- 主库把变更写入 binlog。
- 从库 I/O 线程拉取 binlog,写入本地 relay log。
- 从库 SQL 线程重放 relay log,应用变更。
binlog 格式:
Tip
生产推荐 binlog_format=ROW,它是数据恢复与 CDC 工具(如 Debezium、Canal)的基础,也是 GTID 与多线程复制的前提。
配置主从(简版)
复制延迟
从库重放通常慢于主库写入,表现为 Seconds_Behind_Source 增大。常见原因与对策:
- 大事务 / 大批量 DML → 拆小批量,分多次提交。
- 从库单线程回放 → 开启多线程复制(
replica_parallel_workers)。 - 从库承担大量读 → 增加从库或读写分离路由。
- 无主键表 + ROW 格式 → 补主键(否则回放全表扫描)。
Warning
读写分离下的复制延迟会导致「写后读不到」。对一致性敏感的操作(如支付后立即查询),应强制走主库,或用会话级路由保证同一请求读到最新数据。
高可用方案
分库分表
当单表数据量达到千万级、单库写入逼近上限时,考虑水平拆分。
拆分维度
- 垂直拆分:按业务/字段拆表拆库(如订单库、用户库)。
- 水平拆分:按分片键把同一张表的数据分散到多个库/表。
分片键选择
分片算法
中间件
- 客户端分片:ShardingSphere-JDBC、TSharding。
- 代理分片:ShardingSphere-Proxy、MyCat、Vitess。
Warning
分库分表是最后手段,会带来跨库事务、跨库 JOIN、全局排序、分布式 ID、扩容迁移等一系列复杂度。上分片前先穷尽:加索引、读写分离、归档冷数据、表分区、缓存等手段。
小结
- 复制基于 binlog,用 ROW 格式与 GTID 更安全可靠。
- 复制延迟无法完全消除,关键读必须路由主库。
- 高可用优先考虑官方 InnoDB Cluster / MGR 或云托管。
- 分库分表成本高昂,先优化再拆分的顺序不可颠倒。