本节摘要:主从复制把主库的变更通过 binlog 搬到从库重放,是备份、读写分离、高可用的共同地基。本节配置一套异步复制,讨论延迟治理,并比较高可用方案的取舍。
-- 主库:建复制账号 CREATE USER 'repl'@'10.0.0.%' IDENTIFIED BY '强随机密码' REQUIRE SSL; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.%';
-- 从库:指向主库,开 GTID(全局事务号,8.0 默认) CHANGE REPLICATION SOURCE TO SOURCE_HOST = '10.0.0.5', SOURCE_USER = 'repl', SOURCE_PASSWORD = '强随机密码', SOURCE_AUTO_POSITION = 1; START REPLICA; SHOW REPLICA STATUS\G -- 两个关键行都要 Yes
复制线程模型:主库 dump 线程推 binlog,从库 IO 线程收进中继日志,SQL 线程重放。任何一环慢了,从库数据就落后。
-- 从库执行,Seconds_Behind_Source 就是延迟秒数 SHOW REPLICA STATUS\G
写完立刻读的场景(下单后跳订单页)读从库可能读不到,治法按性价比排:根治是大事务拆小(一个事务重放几分钟,从库就落后几分钟);应用侧对"写后读"路由主库;终极手段是半同步复制,至少一个从库确认收到才向客户端返回提交。
| 方案 | 切换方式 | 适用 |
|---|---|---|
| 异步复制加人工切换 | 手动提升从库 | 小团队,可容忍分钟级停机 |
| 半同步加编排切换 | 工具自动选主 | 多数线上业务 |
| 组复制 MGR | 多数派共识自动选主 | 强一致要求,运维门槛高 |
💡 关键直觉:复制解决的是"有没有副本",切换解决的是"谁来当主"。两个都要演练——只在文档里读过切换步骤的团队,半夜主库宕机时一定手忙脚乱。
复制搭建只是第一天,日常的体检与修链才是常态。体检看三处:两个线程是否都 Yes、延迟秒数、错误日志里有没有重放报错:
SHOW REPLICA STATUS\G -- 健康线:Replica_IO_Running=Yes, Replica_SQL_Running=Yes, -- Seconds_Behind_Source=0 且稳定
断链的常见病因与处置分三档。网络抖动导致 IO 线程断开:日志里是连接错误,重连即可,GTID 会自动续传。从库重放报错(比如主库上手工删过一行,从库重放更新语句时找不到目标):日志里是找不到记录类错误,先评估这条数据能否跳过——GTID 模式下注入空事务跳过,跳完必须做主从一致性校验补差异。磁盘满导致 SQL 线程停:清空间后重启线程。三档之外的兜底是从备份重建从库,流程就是 7.2 节的恢复演练,这也是备份与复制两节互为犄角的原因。
读写分离省下的机器不能拿正确性去换,路由规矩三条。写后读走主库:下单后立即查订单详情,这个窗口内的读必须路由主库,常见实现是会话级粘主(写后 N 秒内该用户的读都走主库)。要幂等的后台任务读从库时容忍延迟:对账任务比对的是历史区间,从库延迟几秒无妨,任务设计时别把"刚刚写入的数据"纳入比对窗口。监控延迟做降级:延迟超过阈值(比如五秒)时把只读流量切回主库,宁可主库压力大一点,不能让用户看见"支付成功但订单不存在"。
-- 延迟观测的进阶:performance_schema 里看线程级延迟 SELECT * FROM performance_schema.replication_connection_status\G
切换和复制一样,只在演练过的团队手里是高可用,没演练过的只是"看起来有备机"。季度演练的剧本:模拟主库宕机(直接停实例,别打招呼),值班同学按预案提升从库为读主库、改应用连接、恢复旧主为新从库,全程计时。第一次演练通常要几十分钟且状况百出——域名没改、应用配置写死 IP、提升后的旧数据冲突,每个状况都是预案的漏洞,修完预案再演练,直到十分钟内完成。自动化切换工具能把这个过程缩到秒级,但工具的选主逻辑、脑裂防护同样要演练验证,否则只是把"手忙脚乱"升级成"自动地手忙脚乱"。
半同步复制的语义随版本演进过一次,值得说清。老的半同步是"主库提交后等从库确认", AFTER_COMMIT 在返回客户端前确认,存在一个从库没收到但主库已提交的窗口。8.0 引入的无损半同步 AFTER_SYNC 把等待挪到确认收到才提交,主库没提交前从库必已收到,故障切换不丢已确认事务,这就是"无损"的含义:
-- 主库开启无损半同步(至少一个从库确认) SET GLOBAL rpl_semi_sync_master_enabled = ON; SET GLOBAL rpl_semi_sync_master_timeout = 3000; -- 从库无响应降级回异步的等待上限
注意 timeout 的降级语义:等到上限从库仍无响应,半同步自动退回异步——可用性优先于一致性是默认取向,金融场景要显式评估这个降级是否可接受,必要时用监控告警盯住降级事件。
再补一组容易误判的复制症状,做成速查。延迟一直在零与几十秒间波动:查大事务,一条慢更新重放几秒,批量任务窗口一过延迟就回落。IO 线程 Yes、SQL 线程 No:从库重放报错,查错误日志定位是数据冲突还是权限问题。两个线程都 Yes 但数据对不上:历史遗留的不一致,跑一致性校验工具量化差异,小差异修数据,大差异重建从库。延迟显示零但业务说读不到新数据:八成不是复制问题,是应用读了缓存或路由错了实例,先查应用侧再看数据库。症状与病因的一一对应,是复制排障的全部秘密。