微信三公机器人 来展开"主从复制扩展"这个系列第一部分的完整框架

这个话题是数据库架构演进的基础课题。结合搜索结果,我来展开"主从复制扩展"这个系列第一部分的完整框架。


---

一、先厘清一个关键认知


有一篇文章的开篇概括得非常到位:[citation:26.3]

主从复制、读写分离、分库分表这三板斧,就是数据库从单机走向分布式架构时最经典的三个台阶。很多人把它们混为一谈,但实际定位完全不同:

> - 主从复制解决的是高可用

读写分离解决的是读压力的横向扩展

分库分表解决的是数据量和并发量双双超出单机承载上限


主从复制自身不直接解决"扩展"问题——它解决的是数据冗余和可用性。但它是读写分离的前提(得有从库才能把读分流),也是分库分表的基础设施(每个分片内部仍然需要主从复制来保证高可用)。


---

二、主从复制的核心架构

2.1 标准流程


主库 Master → binlog → 网络传输 → 从库 Slave

 ├─ I/O 线程:接收 binlog → relay log

 └─ SQL 线程:重放 relay log → 数据同步


主库写入二进制日志(binlog),从库通过一个 I/O 线程把 binlog 拉到本地写入中继日志(relay log),再由 SQL 线程逐条重放。[citation:26.5]

2.2 三种同步模式


| 模式 | 写入延迟 | 数据安全 | 适用场景 |

|:----:|:-------:|:-------:|---------|

| 异步复制(默认) | 最低 | 最低(主库挂了可能丢数据) | 读多写少,允许少量数据丢失 |

| 半同步复制 | 中等 | 较高(至少一个从库收到才返回) | 对数据一致性要求较高的业务 |

| 全同步复制 | 最高 | 最高(所有从库都写入才返回) | 金融级场景(但性能代价极大) |

2.3 GTID 复制 vs 传统位点复制


| 对比项 | 传统位点复制 | GTID 复制 |

|-------|:----------:|:---------:|

| 同步依据 | binlog 文件名 + 偏移量 | 全局唯一事务 ID(GTID) |

| 主从切换 | 需手动找位点,容易出错 | 自动定位,切换更可靠 |

| 并行复制 | 需额外配置 | 天然支持,效率更高 |

| 使用建议 | 已有存量系统 | 新系统首选 |


---

三、从主从复制到读写分离

3.1 为什么需要读写分离


单机数据库的瓶颈通常是读流量远大于写流量。一台主库扛着全部读请求时,CPU 和 IO 很容易被打满。


传统模式(主库扛所有):

 所有请求 → 主库 → CPU 100% → 写入也变慢


读写分离模式:

 写请求 → 主库(专注写入)

 读请求 → 从库(水平扩展读能力)

3.2 实现方式


| 方案 | 代表技术 | 优点 | 缺点 |

|------|---------|------|------|

| 应用层直连 | 代码中维护多数据源 | 轻量、无额外组件 | 耦合度高,扩展需改代码 |

| 中间件代理 | ShardingSphere / ProxySQL / MaxScale | 对应用透明,集中管理 | 引入额外延迟和维护成本 |

| 云托管 | 云 RDS 的只读实例 | 零运维 | 厂商锁定 |

3.3 关键痛点


主从延迟是读写分离最主要的风险。[citation:26.8]

我曾遇到过一个从库因为大事务导致延迟达到 6 小时,最终只能重建同步。


生产环境通常按业务容忍度分级处理:强一致性读强制走主库;弱一致性读走从库。


---

四、扩展的边界:什么时候该从"主从复制"走到下一步


这是一个很实用的判断框架:


graph TD

 A[当前数据库状态] --> B{读压力 > 写压力?}

 B -->|是| C{读压力大到主库 CPU 高?}

 C -->|否| D[加从库 + 读写分离]

 C -->|是| E{单表数据量 > 500万?}

 E -->|否| D

 E -->|是| F[水平分片/分库分表]


 B -->|否| G{写压力大?}

 G -->|是| H{主库 IO 打满?}

 H -->|否| I[优化SQL + 缓存]

 H -->|是| J[分库分表 + 分布式事务]


关键观察点来自搜索结果:[citation:26.9]

加了两台机器做主从复制后,写入依然卡顿——因为瓶颈不在机器数量,而在所有写都压在同一张主库上。


---

五、配置要点

主库配置


[mysqld]

server-id = 1

log_bin = mysql-bin

binlog_format = ROW # 建议用 ROW 格式,一致性最好

sync_binlog = 1 # 每次事务提交都刷盘

binlogdodb = your_db # 只复制指定库(可选)

从库配置


[mysqld]

server-id = 2

relay_log = mysql-relay-bin

read_only = ON # 防止从库被误写入

logslaveupdates = ON # 级联复制时需要

建立复制


-- 传统位点方式

CHANGE MASTER TO

 MASTER_HOST='192.168.1.100',

 MASTER_USER='repl',

 MASTER_PASSWORD='password',

 MASTERLOGFILE='mysql-bin.000001',

 MASTERLOGPOS=154;

START SLAVE;


-- GTID 方式(推荐)

CHANGE MASTER TO

 MASTER_HOST='192.168.1.100',

 MASTER_USER='repl',

 MASTER_PASSWORD='password',

 MASTERAUTOPOSITION=1;

START SLAVE;


-- 检查同步状态

SHOW SLAVE STATUS\G

-- 关注:SlaveIORunning: Yes

-- SlaveSQLRunning: Yes

-- SecondsBehindMaster: 0


---

六、常见问题与排查


| 症状 | 可能原因 | 排查方向 |

|------|---------|---------|

| SlaveIORunning: Connecting | 网络不通 / 用户名密码错 | ping + CHANGE MASTER 重新配置 |

| SlaveSQLRunning: No | relay log 中有 SQL 错误 | SHOW SLAVE STATUS 看 LastError;SET GLOBAL SQLSLAVESKIPCOUNTER = 1 跳过 |

| SecondsBehindMaster 持续上升 | 大事务 / 从库性能不足 | 对大事务拆分批操作;升级从库硬件 |

| 主从数据不一致 | binlog_format 为 STATEMENT | 改用 ROW 格式 + pt-table-checksum 校验 |


---

七、本系列的后续方向


"主从复制扩展"这个命题至少还有以下几个方向值得深入:

主从复制扩展(二)——级联复制与多主架构:当从库数量超过 10 个时,主库的 binlog 分发会成为瓶颈,级联复制或多主环形复制可以解决

只读实例的在线扩展和缩容:如何在不停服的情况下增加/移除从库

跨地域复制与延迟优化:异地多活的延迟治理

从主从复制到分布式数据库的平滑演进:从 MGR 到 TiDB 的过渡路径


你是想继续深入某个具体方向,还是需要我帮你跑一个 Docker 环境下的主从复制搭建过程来把配置落地?


0 评论

发表评论