乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 数据库基础与安装

    • MySQL 简介
    • MySQL 5.6 到 5.7 到 8.0 关键差异速查
    • 安装 MySQL 5.7
    • 连接与断开服务器
    • 创建数据库
    • 创建数据表
    • 数据库与数据表
    • 加载数据
    • 获取数据库信息
    • 批处理模式
    • SHOW 语句汇总
    • FLUSH 与 RESET 语句
    • my.cnf 核心参数
    • 字符集与排序规则
  • 第2章 SQL基础查询

    • SELECT
    • WHERE
    • ORDER BY
    • LIMIT
    • COUNT
    • 聚合函数
    • 比较运算符
    • 逻辑运算符
    • 算术运算符
    • 模式匹配
    • NULL 值处理
    • UPDATE
    • DELETE
    • REPLACE
    • SELECT INTO
  • 第3章 数据类型与运算符

    • 数值类型
    • 字符串类型
    • 日期时间类型
    • BIT 类型
    • ENUM 类型
    • SET 类型
    • JSON 类型
    • 类型转换
  • 第4章 函数与表达式

    • 字符串函数
    • 数值函数
    • 日期函数
    • 全文检索函数
  • 第5章 高级查询与子查询

    • JOIN
    • 子查询
    • UNION
    • GROUP BY
    • HAVING
    • DISTINCT
  • 第6章 表与索引

    • 数据定义语言
    • 修改表结构
    • 视图
    • 修改视图与检查选项
    • 外键
    • 索引
    • 唯一索引
    • 复合索引
    • 存储引擎对比
    • 分区表
    • 第一范式与第二范式
    • 第三范式与 BC 范式
    • 反范式设计
  • 第7章 存储过程与函数

    • 存储过程
    • 存储函数
    • 变量
    • 流程控制
    • 游标
    • 预处理语句
  • 第8章 事务与锁

    • 事务
    • 事务隔离级别
    • 锁机制
    • MVCC
    • 死锁专题分析
    • LOCK TABLES
    • XA 事务
  • 第9章 用户管理与安全

    • 用户管理
    • 权限管理
    • 角色
    • SQL 注入防范
  • 第10章 性能优化入门

    • 执行计划
    • 索引优化
    • 查询优化
    • 查询优化器提示
    • 慢查询日志
    • InnoDB 深入机制
    • InnoDB 专项优化
    • Performance Schema
    • sys Schema
  • 第11章 复制与高可用

    • 主从复制原理
    • 半同步复制配置
    • binlog 开启与 point-in-time 恢复
    • mysqldump 全库备份
    • mysqldump 单表与条件备份
    • mysqldump 恢复与导入
    • xtrabackup 全量热备
    • xtrabackup 准备与恢复
    • xtrabackup 增量与流式备份
  • 第12章 触发器与事件

    • 触发器
    • 事件调度器
  • 参考

    • MySQL 5.7 专业术语大全
    • MySQL 5.7 关键字与保留字大全

主从复制原理

导学

单台 MySQL 服务器既要处理写请求又要处理读请求,压力会越来越大。主从复制(Replication)让一台主库(Master)负责写,多台从库(Slave)负责读,是 MySQL 扩展读性能、实现高可用的最基础架构。理解 binlog、relay log 和复制线程的工作机制,是运维 MySQL 的必修课。

定义

主从复制:MySQL 将主库的数据变更记录到二进制日志(binlog),从库通过 I/O 线程读取 binlog 并写入中继日志(relay log),再由 SQL 线程重放 relay log 中的事件,实现数据同步。

核心概念

组件作用位置
binlog记录主库所有数据变更(DDL + DML)主库
relay log从库暂存从主库接收的 binlog 事件从库
I/O 线程连接主库,读取 binlog 并写入 relay log从库
SQL 线程读取 relay log,按顺序重放事件从库
master.info记录从库连接主库的配置和读取位置从库
relay-log.info记录 SQL 线程执行到 relay log 的位置从库

复制模式

模式特点适用场景
异步复制(默认)主库不等待从库确认,性能最好,但可能丢数据读扩展,允许秒级延迟
半同步复制主库等待至少一个从库确认收到 binlog 才返回数据安全优先,容忍轻微延迟
GTID 复制基于全局事务 ID,自动定位复制点,故障切换简单5.6+ 推荐,复杂拓扑必备

SQL 示例

场景一:配置异步复制(基础版)

主库配置(my.cnf):

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW

从库配置(my.cnf):

[mysqld]
server-id = 2
relay-log = mysql-relay-bin
read-only = 1

server-id 必须全局唯一,read-only=1 防止从库被误写入(有 SUPER 权限的用户仍可写)。

场景二:主库创建复制用户

执行语句:

-- 在主库上执行
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

结果解读:

  • REPLICATION SLAVE 权限是从库连接主库读取 binlog 的最低权限
  • 生产环境应将 % 替换为从库的具体 IP 地址

场景三:获取主库 binlog 位置

执行语句:

-- 在主库上执行,锁定表防止数据变更
FLUSH TABLES WITH READ LOCK;

-- 查看当前 binlog 文件名和位置
SHOW MASTER STATUS;

操作后结果:

FilePositionBinlog_Do_DBBinlog_Ignore_DB
mysql-bin.000001154

结果解读:

  • File:当前正在写入的 binlog 文件名
  • Position:当前写入位置(字节偏移量)
  • 从库需要从 mysql-bin.000001:154 这个位置开始同步
  • 记录后执行 UNLOCK TABLES; 解除锁定

场景四:从库启动复制

执行语句:

-- 在从库上执行
CHANGE MASTER TO
    MASTER_HOST = '192.168.1.10',
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'repl_password',
    MASTER_LOG_FILE = 'mysql-bin.000001',
    MASTER_LOG_POS = 154;

START SLAVE;

查看复制状态:

SHOW SLAVE STATUS\G

关键字段:

字段含义正常状态
Slave_IO_RunningI/O 线程是否运行Yes
Slave_SQL_RunningSQL 线程是否运行Yes
Seconds_Behind_Master从库延迟秒数0 或较小值
Last_IO_Error / Last_SQL_Error最近错误空

结果解读:

  • Slave_IO_Running = No:网络问题、权限问题、server-id 冲突
  • Slave_SQL_Running = No:主从数据不一致、SQL 执行错误(如重复键)
  • Seconds_Behind_Master = NULL:复制可能已停止或 I/O 线程异常

场景五:GTID 复制配置(推荐)

主库和从库配置(my.cnf):

[mysqld]
gtid-mode = ON
enforce-gtid-consistency = ON
log-bin = mysql-bin
server-id = 1  -- 主库为1,从库为2

从库启动 GTID 复制:

-- 无需指定 MASTER_LOG_FILE/POS,GTID 自动定位
CHANGE MASTER TO
    MASTER_HOST = '192.168.1.10',
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'repl_password',
    MASTER_AUTO_POSITION = 1;

START SLAVE;

结果解读:

  • MASTER_AUTO_POSITION = 1 启用 GTID 自动定位,无需手动指定 binlog 文件和位置
  • GTID 格式:uuid:transaction_id,如 3e11fa47-71ca-11e1-9e33-c80aa9429562:23
  • 故障切换时,新主库的 GTID 集合可以自动判断从库是否需要同步缺失数据

场景六:排查复制延迟

执行语句:

-- 查看从库延迟
SHOW SLAVE STATUS\G
-- 关注 Seconds_Behind_Master

-- 查看 SQL 线程正在执行的事件
SHOW PROCESSLIST;
-- 关注 User=system user, Command=Binlog Dump / SQL 线程

-- 查看 relay log 堆积情况
SHOW VARIABLES LIKE 'relay_log%';

常见延迟原因:

原因表现解决方向
主库写入量过大Seconds_Behind_Master 持续增长增加从库、拆分写入
从库单线程重放SQL 线程 CPU 100%5.7 开启多线程复制 slave_parallel_workers
大事务某条 SQL 执行时间长拆分大事务、避免 DELETE 全表
从库配置差I/O 或 CPU 瓶颈提升从库硬件

常见误区

误区正解
"主从复制是实时同步的"不是。异步复制有延迟(毫秒到秒级),Seconds_Behind_Master 显示的是估算延迟。
"从库设为 read-only 就完全不能写了"不是。read_only=1 只限制普通用户,有 SUPER 权限的用户(如 root)仍可写入。
"binlog 只记录 INSERT/UPDATE/DELETE"不是。binlog 记录所有数据变更,包括 DDL(CREATE/ALTER/DROP)和 DML。
"复制断了可以直接 START SLAVE 恢复"不一定。如果主从数据已不一致(如主库插入了从库已存在的数据),START SLAVE 会报错。需要先修复数据或跳过错误。
"GTID 复制比传统复制慢"不是。GTID 只是定位方式不同,传输和重放性能基本一致。GTID 的优势是故障切换和拓扑管理。
"一台主库可以配无数台从库"理论上可以,但每台从库都会连接主库读取 binlog,过多从库会拖垮主库网络。建议通过"级联复制"(从库再带从库)扩展。

面试考点

Q:MySQL 主从复制的原理?

主库将数据变更写入 binlog;从库的 I/O 线程连接主库,读取 binlog 写入 relay log;SQL 线程读取 relay log 按顺序重放事件,保持数据一致。默认是异步复制,主库不等待从库确认。

Q:binlog 的三种格式区别?

STATEMENT:记录 SQL 语句,体积小但某些语句(如 UUID()、NOW())在主从执行结果可能不一致。ROW:记录每行数据的变更,体积大但数据一致性最好,5.7 推荐。MIXED:MySQL 自动选择 STATEMENT 或 ROW,折中方案。

Q:主从延迟怎么排查?

  1. SHOW SLAVE STATUS 看 Seconds_Behind_Master;2. SHOW PROCESSLIST 看 SQL 线程状态;3. 检查主库写入量是否突增;4. 检查从库硬件是否瓶颈;5. 5.7 可开启 slave_parallel_workers 多线程重放。

Q:GTID 复制的好处?

  1. 自动定位复制点,无需手动指定 binlog 文件和位置;2. 故障切换简单,新主库可以自动判断从库数据是否完整;3. 避免传统复制中 CHANGE MASTER TO 指定错误位置导致数据错乱。

Q:从库可以执行写入操作吗?

可以但不推荐。read_only=1 只限制普通用户。如果从库写入数据与主库冲突(如主键重复),会导致 SQL 线程报错,复制中断。

小结

  • 主从复制通过 binlog → relay log → SQL 线程重放实现数据同步
  • 异步复制性能最好但可能丢数据,半同步复制平衡安全与性能,GTID 复制简化运维
  • 配置复制需要:唯一 server-id、binlog 开启、复制用户、CHANGE MASTER TO、START SLAVE
  • 排查复制问题看 SHOW SLAVE STATUS 的 Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master
  • GTID 是 5.6+ 的推荐方案,自动定位复制点,故障切换更可靠

下一章引子:复制解决了读扩展,但数据安全还需要备份机制——当主库磁盘损坏、误删数据时,只有备份能救命。

下一页
半同步复制配置