当前位置: 首页 > news >正文

MySQL主从复制与高可用架构

摘要:主从复制是 MySQL 实现读写分离和数据冗余的基础,高可用架构则是保障业务连续性的关键。本文从 Binlog 的三种格式讲起,深入解析主从复制的核心原理与三种复制模式(异步/半同步/组复制),对比 MHA、MGR、Orchestrator 等高可用方案的优劣,并给出完整的搭建命令和故障切换实战。全文包含架构图和配置示例,建议收藏。


一、为什么需要主从复制?

单节点 MySQL 面临三大瓶颈:

瓶颈表现主从复制解决方案
读性能瓶颈单机 QPS 有上限,读请求过多导致 CPU/IO 满载一主多从,读写分离,读流量分散到多个从库
单点故障主库宕机,业务完全不可用从库提升为主库,实现故障转移
数据安全单节点数据丢失风险高数据实时同步到从库,提供冗余备份

上图展示了典型的读写分离架构:写操作(Insert/Update/Delete)全部发往主库(Master),读操作(Select)分散到多个从库(Replica),通过负载均衡实现读流量的水平扩展。


二、Binlog:主从复制的基石

2.1 Binlog 的三种格式

Binlog(Binary Log)是 MySQL 的二进制日志,记录了所有修改数据的操作。主从复制本质上就是从库读取主库的 Binlog 并重放

格式记录内容优点缺点适用场景
STATEMENTSQL 语句原文日志量小某些语句(如 UUID、NOW())在主从执行结果不一致简单场景,不推荐生产
ROW每行数据的变更前后值精确复制,无歧义日志量大(批量更新会记录所有行)生产环境推荐
MIXED混合模式,MySQL 自动选择兼顾日志量和准确性切换逻辑不透明,可能引入不确定性折中方案
-- 查看当前 Binlog 格式SHOWVARIABLESLIKE'binlog_format';-- 动态修改(建议 ROW 格式)SETGLOBALbinlog_format='ROW';-- 永久修改(my.cnf)[mysqld]binlog_format=ROW

2.2 Binlog 与 Redo Log 的区别

特性BinlogRedo Log
层级Server 层存储引擎层(InnoDB)
内容逻辑日志(SQL 或行数据变更)物理日志(页数据的物理修改)
用途主从复制、数据恢复、审计崩溃恢复(Crash Recovery)
写入方式追加写,日志文件会轮转循环写,固定大小(如 2 个 1GB 文件)
是否必须主从复制场景必须开启InnoDB 必须开启

两阶段提交:为了保证 Binlog 和 Redo Log 的一致性,InnoDB 使用两阶段提交(2PC):

  1. Prepare 阶段:事务先将修改写入 Redo Log,状态设为 prepare
  2. Commit 阶段:事务将修改写入 Binlog,然后将 Redo Log 状态改为 commit

这样即使崩溃,也能通过 Redo Log 状态判断事务是否需要回滚或提交。


三、主从复制的核心原理

3.1 复制流程详解

主从复制涉及三个核心线程:

线程所在节点职责
Binlog Dump Thread主库读取 Binlog 文件,将日志事件发送给从库的 I/O 线程
I/O Thread从库连接主库,接收 Binlog 事件,写入 Relay Log(中继日志)
SQL Thread从库读取 Relay Log,重放 SQL 语句,将数据变更应用到从库

复制流程

  1. 主库执行 DML/DDL 操作,记录到 Binlog
  2. 从库的 I/O 线程连接主库,请求指定位置之后的 Binlog
  3. 主库的 Binlog Dump 线程读取 Binlog,通过网络发送给从库
  4. 从库的 I/O 线程将接收到的 Binlog 事件写入 Relay Log
  5. 从库的 SQL 线程读取 Relay Log,按顺序重放事件,更新从库数据

3.2 两种复制方式:基于位置 vs 基于 GTID

基于文件位置(File + Position)
-- 从库配置CHANGE MASTERTOMASTER_HOST='192.168.1.10',MASTER_USER='repl',MASTER_PASSWORD='password',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;

缺点

  • 主从切换后,新主库的 Binlog 位置与旧主库不同,从库需要重新定位
  • 多个从库指向同一个主库时,位置管理复杂
  • 故障恢复时容易出错
基于 GTID(Global Transaction Identifier)

GTID 是 MySQL 5.6+ 引入的全局事务标识符,格式为source_id:transaction_id

-- 主库和从库都开启 GTID[mysqld]gtid_mode=ONenforce_gtid_consistency=ON-- 从库配置CHANGE MASTERTOMASTER_HOST='192.168.1.10',MASTER_USER='repl',MASTER_PASSWORD='password',MASTER_AUTO_POSITION=1;-- 自动定位,无需指定文件和位置

GTID 的优势

  • 自动定位:从库只需知道已执行到哪个 GTID,无需关心文件和位置
  • 主从切换简单:新主库的 GTID 集合与旧主库一致,从库自动追平
  • 故障恢复可靠:不会遗漏或重复执行事务

四、三种复制模式

4.1 异步复制(Asynchronous Replication)

默认模式。主库执行完事务后立即返回客户端,不等待从库确认。

客户端 ← 主库提交成功(立即返回) ↓ Binlog Dump Thread 异步发送给从库 ↓ 从库 I/O Thread 接收并写入 Relay Log ↓ 从库 SQL Thread 重放

优点:主库性能最好,无延迟
缺点:主库宕机时,从库可能丢失未同步的数据(数据不一致)
适用:读多写少、允许少量数据丢失的场景

4.2 半同步复制(Semi-Synchronous Replication)

MySQL 5.5+ 引入。主库执行完事务后,至少等待一个从库确认收到 Binlog 后才返回客户端

上图展示了半同步复制的 ACK 机制:主库在 commit 前等待从库返回 ACK,确保至少一个从库已收到数据。

-- 主库安装半同步插件INSTALL PLUGIN rpl_semi_sync_masterSONAME'semisync_master.so';SETGLOBALrpl_semi_sync_master_enabled=1;SETGLOBALrpl_semi_sync_master_timeout=10000;-- 10秒超时降级为异步-- 从库安装半同步插件INSTALL PLUGIN rpl_semi_sync_slaveSONAME'semisync_slave.so';SETGLOBALrpl_semi_sync_slave_enabled=1;

优点:保证至少一个从库有最新数据,减少数据丢失风险
缺点:增加主库延迟(等待 ACK 的时间),性能略低于异步
适用:对数据一致性要求较高的场景

4.3 组复制(Group Replication / MGR)

MySQL 5.7.17+ 引入的原生高可用方案,基于 Paxos 协议实现多主强一致性复制。

核心特点

  • 多主模式:多个节点可同时写入,自动处理冲突
  • 自动故障检测:节点故障自动踢出集群
  • 自动选主:主库故障后自动选举新主库
  • 数据强一致性:基于 Paxos 协议,大多数节点确认后才提交
-- 组复制配置示例(单主模式)[mysqld]server_id=1gtid_mode=ONenforce_gtid_consistency=ONbinlog_format=ROWlog_bin=mysql-bin plugin_load_add=group_replication.so group_replication_group_name='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'group_replication_local_address='192.168.1.10:33061'group_replication_group_seeds='192.168.1.10:33061,192.168.1.11:33061,192.168.1.12:33061'group_replication_single_primary_mode=ONgroup_replication_enforce_update_everywhere_checks=OFF

三种复制模式对比

特性异步复制半同步复制组复制(MGR)
数据一致性弱(可能丢失)较强(至少一个从库确认)强(多数节点确认)
主库延迟中等(等 ACK)较高(等多数确认)
故障切换手动手动/脚本自动
写入扩展单主单主多主(可选)
复杂度
适用场景读多写少数据安全要求高金融级高可用

五、高可用架构方案对比

5.1 方案总览

方案原理自动切换数据一致性适用场景
MHA基于 SSH 的脚本化切换依赖半同步中小型业务
MGRMySQL 原生组复制强一致MySQL 5.7.17+ 推荐
OrchestratorRaft 共识 + 可视化可配置大规模集群
ProxySQL中间件读写分离否(需配合 MHA/MGR)依赖后端读写分离场景

5.2 MHA(Master High Availability)

MHA 是由日本开发者用 Perl 编写的开源高可用方案,由两部分组成:

  • MHA Manager:管理节点,负责监控主库状态、执行故障切换
  • MHA Node:数据节点,部署在每个 MySQL 服务器上,执行日志解析和差异补全

故障切换流程

  1. Manager 检测到主库故障(通过 ping 和 SELECT 1 检测)
  2. 从多个从库中选择数据最新的一个作为候选主库(对比 Relay Log 位置)
  3. 将其他从库的 Relay Log 中的差异事件应用到候选主库
  4. 提升候选主库为新主库
  5. 将其他从库指向新主库

MHA 配置示例

# /etc/mha/app1.cnf[server default]user=mhapassword=mha_passwordssh_user=rootrepl_user=replrepl_password=repl_passwordping_interval=1master_binlog_dir=/var/lib/mysqlremote_workdir=/var/log/masterhamanager_workdir=/var/log/masterha/app1manager_log=/var/log/masterha/app1/manager.log[server1]hostname=192.168.1.10port=3306[server2]hostname=192.168.1.11port=3306candidate_master=1# 优先提升为主库[server3]hostname=192.168.1.12port=3306no_master=1# 不参与主库竞选

MHA 的优缺点

优点缺点
故障切换速度快(通常 10-30 秒)已停止维护(2018 年后无更新)
支持基于 GTID 和基于位置的复制需要 SSH 免密登录,存在安全风险
切换过程中尽量保证数据一致性只支持单主架构
社区使用广泛,文档丰富配置复杂,依赖 Perl 环境

5.3 MGR(MySQL Group Replication)

MGR 是 MySQL 官方推出的原生高可用方案,基于 Paxos 协议实现。

两种模式

模式特点适用场景
单主模式(Single-Primary)只有一个节点可写,其他只读,自动选主大多数业务场景
多主模式(Multi-Primary)所有节点都可写,自动处理冲突写密集型、多地域写入

MGR 的核心优势

  • 原生集成:无需第三方工具,MySQL 内置
  • 自动故障检测与切换:节点故障自动踢出,新主自动选举
  • 数据强一致性:基于 Paxos,写入需多数节点确认
  • 弹性扩展:可在线添加/移除节点

MGR 的限制

  • 只支持 InnoDB 存储引擎
  • 表必须有主键
  • 不支持 SERIALIZABLE 隔离级别
  • 网络延迟要求高(建议 < 10ms)

5.4 Orchestrator

GitHub 开源的 MySQL 高可用管理工具,基于 Raft 协议实现 Manager 自身的高可用。

核心特性

  • 可视化拓扑:Web 界面直观展示主从关系
  • 智能故障检测:不仅检测主库宕机,还能检测网络分区、复制延迟等
  • 优雅主从切换:支持计划内切换(如维护窗口),零数据丢失
  • Hooks 机制:切换前后可执行自定义脚本(如切换 VIP、通知告警)

Orchestrator 配置要点

{"Debug":true,"ListenAddress":":3000","MySQLTopologyUser":"orchestrator","MySQLTopologyPassword":"password","MySQLTopologyMaxPoolConnections":3,"RecoveryPeriodBlockSeconds":3600,"PreFailoverProcesses":["echo 'Will recover from {failureType} on {failedHost}' >> /tmp/recovery.log"],"PostFailoverProcesses":["echo 'Recovered from {failureType} on {failedHost}, new master is {successorHost}' >> /tmp/recovery.log"]}

六、实战:搭建一主两从 + MHA 高可用

6.1 环境准备

角色IP主机名
Master192.168.1.10db-master
Slave1192.168.1.11db-slave1
Slave2192.168.1.12db-slave2
MHA Manager192.168.1.20mha-manager

6.2 主库配置

# /etc/mysql/my.cnf [mysqld] server_id = 10 log_bin = mysql-bin binlog_format = ROW gtid_mode = ON enforce_gtid_consistency = ON binlog_expire_logs_seconds = 604800 # 7天 # 半同步复制(可选) plugin_load_add = semisync_master.so rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 10000
-- 创建复制用户CREATEUSER'repl'@'192.168.1.%'IDENTIFIEDBY'repl_password';GRANTREPLICATIONSLAVEON*.*TO'repl'@'192.168.1.%';FLUSHPRIVILEGES;-- 查看主库状态SHOWMASTERSTATUS;-- 或(GTID 模式)SHOWGLOBALVARIABLESLIKE'gtid_executed';

6.3 从库配置

# /etc/mysql/my.cnf [mysqld] server_id = 11 # Slave2 改为 12 log_bin = mysql-bin binlog_format = ROW gtid_mode = ON enforce_gtid_consistency = ON read_only = ON # 从库只读 # 半同步复制(可选) plugin_load_add = semisync_slave.so rpl_semi_sync_slave_enabled = 1
-- 配置主从关系(GTID 模式)CHANGE MASTERTOMASTER_HOST='192.168.1.10',MASTER_USER='repl',MASTER_PASSWORD='repl_password',MASTER_AUTO_POSITION=1;STARTSLAVE;-- 检查从库状态SHOWSLAVESTATUS\G-- 确认: Slave_IO_Running = Yes, Slave_SQL_Running = Yes

6.4 复制延迟监控

-- 查看从库延迟(Seconds_Behind_Master)SHOWSLAVESTATUS\G-- 更精确的延迟监控(MySQL 8.0)SELECTMAX(TIMESTAMPDIFF(SECOND,LAST_QUEUED_TRANSACTION_START_QUEUE_TIMESTAMP,LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP))ASdelay_secondsFROMperformance_schema.replication_applier_status_by_worker;-- 查看 Relay Log 应用进度SHOWPROCESSLIST;-- 查看 SQL Thread 状态

6.5 故障切换演练

# 1. 模拟主库故障systemctl stop mysql# 在 db-master 上执行# 2. MHA Manager 自动检测并切换(约 10-30 秒)# 查看切换日志tail-f/var/log/masterha/app1/manager.log# 3. 验证新主库mysql-h192.168.1.11-e"SHOW MASTER STATUS;"# 4. 将故障节点恢复为从库# 在 db-master 上执行CHANGE MASTER TOMASTER_HOST='192.168.1.11',MASTER_USER='repl',MASTER_PASSWORD='repl_password', MASTER_AUTO_POSITION=1;START SLAVE;

七、读写分离实践

7.1 应用层实现

// Spring Boot + MyBatis 动态数据源@ConfigurationpublicclassDataSourceConfig{@BeanpublicDataSourceroutingDataSource(){DynamicRoutingDataSourceroutingDataSource=newDynamicRoutingDataSource();Map<Object,Object>targetDataSources=newHashMap<>();targetDataSources.put("master",masterDataSource());targetDataSources.put("slave1",slave1DataSource());targetDataSources.put("slave2",slave2DataSource());routingDataSource.setTargetDataSources(targetDataSources);routingDataSource.setDefaultTargetDataSource(masterDataSource());returnroutingDataSource;}}// 注解方式切换数据源@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public@interfaceDataSource{Stringvalue()default"master";}// Service 层使用@ServicepublicclassOrderService{@DataSource("master")// 写操作走主库publicvoidcreateOrder(Orderorder){orderMapper.insert(order);}@DataSource("slave1")// 读操作走从库publicOrdergetOrder(Longid){returnorderMapper.selectById(id);}}

7.2 中间件实现(ProxySQL)

ProxySQL 是高性能的 MySQL 中间件,支持读写分离、连接池、查询缓存等功能。

-- 1. 添加后端服务器INSERTINTOmysql_servers(hostgroup_id,hostname,port)VALUES(10,'192.168.1.10',3306),-- hostgroup 10: 写组(主库)(20,'192.168.1.11',3306),-- hostgroup 20: 读组(从库)(20,'192.168.1.12',3306);-- 2. 配置用户INSERTINTOmysql_users(username,password,default_hostgroup)VALUES('app_user','password',10);-- 3. 配置读写分离规则INSERTINTOmysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply)VALUES(1,1,'^SELECT.*FOR UPDATE',10,1),-- SELECT FOR UPDATE 走主库(2,1,'^SELECT',20,1),-- 普通 SELECT 走从库(3,1,'.*',10,1);-- 其他(INSERT/UPDATE/DELETE)走主库-- 4. 加载配置到运行时LOADMYSQL SERVERSTORUNTIME;LOADMYSQL USERSTORUNTIME;LOADMYSQL QUERY RULESTORUNTIME;-- 5. 持久化到磁盘SAVEMYSQL SERVERSTODISK;SAVEMYSQL USERSTODISK;SAVEMYSQL QUERY RULESTODISK;

八、面试高频考点速记

Q1:MySQL 主从复制的原理是什么?

主库将数据变更记录到 Binlog,从库的 I/O 线程连接主库读取 Binlog 并写入 Relay Log,SQL 线程读取 Relay Log 重放到从库。涉及三个线程:主库的 Binlog Dump 线程、从库的 I/O 线程和 SQL 线程。

Q2:Binlog 的三种格式有什么区别?生产环境用哪种?

STATEMENT 记录 SQL 原文,日志量小但可能有主从不一致;ROW 记录每行变更,精确复制但日志量大;MIXED 自动选择。生产环境推荐 ROW 格式,确保数据一致性。

Q3:GTID 相比传统基于位置的复制有什么优势?

GTID 为每个事务分配全局唯一标识,从库只需追踪已执行的 GTID 集合,无需关心文件和位置。主从切换时自动定位,不会遗漏或重复事务,故障恢复更可靠。

Q4:半同步复制和异步复制的区别?

异步复制主库提交后不等待从库确认,性能最好但可能丢数据。半同步复制主库至少等待一个从库确认收到 Binlog 后才返回客户端,保证至少一个从库有最新数据,减少数据丢失风险,但增加了主库延迟。

Q5:MHA 和 MGR 有什么区别?

MHA 是第三方 Perl 脚本工具,基于 SSH 实现故障切换,速度快但已停止维护。MGR 是 MySQL 原生方案,基于 Paxos 协议实现多主强一致性复制,自动故障检测和切换,是官方推荐的高可用方案(MySQL 5.7.17+)。

Q6:主从延迟怎么解决?

  1. 硬件层面:从库配置不低于主库,使用 SSD;2. SQL 层面:避免大事务,将大事务拆分为小事务;3. 架构层面:增加从库数量分散读压力,或使用缓存(Redis)分担读请求;4. 参数优化:开启并行复制(slave_parallel_workers),调整 sync_binlog 和 innodb_flush_log_at_trx_commit。

Q7:读写分离后从库数据延迟,读不到最新数据怎么办?

  1. 强制走主库:对实时性要求高的查询使用@DataSource("master");2. 延迟阈值判断:如果 Seconds_Behind_Master > 阈值,自动切到主库;3. 业务容忍:大部分业务允许秒级延迟;4. 使用 MGR:单主模式下写入后立即可从主库读取。

结语

主从复制是 MySQL 水平扩展的基石,高可用架构则是业务连续性的保障。

选择建议

  • MySQL 5.6/5.7 早期:MHA + 异步/半同步复制
  • MySQL 5.7.17+ / 8.0:优先选择MGR,原生支持、自动切换、强一致性
  • 大规模集群:Orchestrator + ProxySQL,可视化管理和智能切换
  • 云环境:直接使用云厂商的 RDS 高可用方案(如阿里云 PolarDB、AWS Aurora)

无论选择哪种方案,监控和演练都是必不可少的:没有监控的高可用等于没有高可用,没有演练的故障切换等于没有故障切换。


如果本文对你有帮助,欢迎点赞收藏!

http://www.jsqmd.com/news/864534/

相关文章:

  • d2s-editor:暗黑破坏神2存档编辑器的终极免费Web工具指南
  • 普通人年薪翻倍跳板:收藏这份AI大模型应用开发工程师成长指南
  • NodeMCU PyFlasher:告别命令行困扰,3步搞定ESP8266固件烧录的智能方案
  • 后端接口错误码到底该怎么设计?我见过最烂的和最优雅的两种方案
  • Betaflight飞控固件2026完全指南:从入门到精通的7个实用技巧
  • NotebookLM智能摘要失真问题(底层token切分逻辑与人工校准SOP)
  • 终极指南:如何免费获取Cursor Pro功能,轻松突破试用限制
  • 浙江话AI语音项目最后通牒:2024Q3起ElevenLabs将关闭非ISO方言模型上传通道,现在必须掌握这5个迁移预案
  • 分布式ID生成方案详解与实战
  • Go 微服务必备:服务发现、配置中心、中间件是怎么协作的?
  • ElevenLabs接入云南话语音合成:从零部署到商用上线的7大关键配置(含昆明/大理/红河三地方言音素映射表)
  • 潮州话TTS落地最后一公里:ElevenLabs音频后处理秘技(含潮汕童谣节奏建模与语义停顿注入)
  • Python Selenium 瀏覽器自動化測試工具
  • 职场新人不会写自我介绍怎么办?AI三分钟帮你搞定,面试邀约直接翻倍!
  • 分享一个专门用于 SAP 开发的 Claude Code Skill 插件集合
  • 端侧AI基础设施:核心环节与代表企业
  • 裸辞转行AI大模型:我的探索与收获,收藏这份经验助你启程!
  • 大模型赋能政务审批:从 “人工审” 到 “智能核”
  • 如果你还在为CAD、SolidWorks的许可发愁,看看这八家
  • 406_C++_磁盘检查流程安全重构分析:从 system/popen 到 fork/exec 的防命令注入升级
  • 观察不同模型在 Taotoken 平台上的响应速度与效果差异
  • 独立开发者如何借助taotoken以更低成本启动ai项目
  • 时序例外:false_path / multicycle_path / max_delay
  • 新手程序员必备:收藏这份GPT大模型学习指南,从入门到精通!
  • 2026企业网盘选型指南:外部协作可控、合规审计、版本追溯的8款测评盘点
  • 昇腾CANN实战:FlashAttention 在昇腾NPU上的实现与性能调优
  • Spek音频频谱分析器:完整指南与实用技巧
  • GitLab CI|CD 配置笔记
  • 游戏化编程教学系统CodeCombat本地化部署实战:构建高效稳定的离线学习环境
  • 2026网盘怎么选:别只盯“不限速”,更该看同步稳定性与数据安全