Mysql主从复制

一、什么是 MySQL 主从复制?
MySQL 主从复制是基于二进制日志(binlog)实现的异步 / 半同步数据复制技术,核心作用是:一台主库(Master)写入,多台从库(Slave)同步复制数据,是 MySQL 高可用、读写分离、数据备份、负载均衡的基础。
简单来说,就是一台主库负责处理数据写入,一台或多台从库自动同步主库的数据,承担数据读取的架构模式。
我们日常业务中,数据库的增、删、改操作全部走主库,查询请求分流到从库,既解决了单库读写压力瓶颈,也实现了数据实时备份。

主从复制的核心价值主要有四点:

  • 读写分离,提升并发性能:将高频查询请求剥离,主库专注写操作,大幅提升数据库整体吞吐量
  • 实时热备份,防止数据丢失:从库实时同步主库数据,无需频繁冷备份,规避主库宕机数据丢失风险
  • 支撑高可用、故障切换:主库故障时,可快速将从库提升为主库,保障业务不中断
  • 支持水平扩容:通过增加从库数量,无限扩展数据库查询能力

二、主从复制核心底层原理
主从复制的本质很简单:主库记录数据变更日志,从库主动拉取日志并重新执行,最终实现数据一致。

  1. 核心组件
  • 主库 Binlog(二进制日志):主库的核心日志,会记录所有增、删、改数据变更操作,不记录普通查询语句,是主从同步的数据源
  • 从库 IO 线程:专门负责和主库建立连接,主动拉取主库的 Binlog 日志,将日志内容写入本地的中继日志(Relay Log)
  • 从库 SQL 线程:读取本地中继日志,逐条重放日志中的数据操作,让从库数据和主库保持同步
  1. 同步执行流程
  2. 客户端向主库执行 INSERT、UPDATE、DELETE 等写操作
  3. 主库执行 SQL 语句,完成数据写入,同时将操作记录到本地 Binlog 日志中
  4. 从库的 IO 线程持续监听主库,主动拉取最新的 Binlog 日志
  5. 主库将新增的日志数据推送至从库,从库 IO 线程将日志写入本地 Relay Log(中继日志)
  6. 从库 SQL 线程实时读取中继日志,逐条执行日志中的数据操作
  7. 最终主从库数据完全一致,同步完成
    核心总结:主库负责记日志,从库负责拉日志、执行日志,全程是从库主动拉取,而非主库主动推送。

三、Binlog 三种日志格式
Binlog 的记录格式,直接决定主从同步的准确性和效率,三种格式各有优劣:

  1. STATEMENT(语句模式)
    直接记录客户端执行的原生 SQL 语句。优点是日志体积小、占用资源少;缺点是部分函数、随机语句、存储过程执行后,主从数据可能出现不一致,同步精度差。
  2. ROW(行模式)
    不记录 SQL 语句,直接记录每一行数据的变更前后状态。同步精度极高,几乎不会出现数据不一致问题,适配所有业务场景;唯一缺点是日志体积会稍大。
  3. MIXED(混合模式)
    是前两种模式的结合体,MySQL 会自动判断场景:普通语句用 STATEMENT 模式,特殊风险语句自动切换为 ROW 模式。兼顾体积和准确性,但不如纯 ROW 模式稳定。

四、三种主从同步模式

  1. 异步复制—— MySQL 默认模式
    异步复制是 MySQL 原生默认的同步模式,核心特点是主库与从库的日志同步完全解耦,主库无需等待从库任何响应,全程无阻塞写入。

执行时序:

  1. 客户端向主库提交事务;
  2. 主库执行事务,成功提交后,将本次事务变更记录写入本地 Binlog 日志;
  3. 主库立即返回「执行成功」给客户端,本次请求结束;
  4. 后台异步线程继续工作:从库 IO 线程后续拉取主库 Binlog,写入本地 Relay Log;
  5. 从库 SQL 线程重放日志,完成数据同步。
    整个过程中,主库的写入响应和从库的同步行为是异步并行的,两者互不干扰。
    核心优缺点:
  • 优点:零阻塞、写入性能最高、吞吐量最大,无额外网络等待开销,适配高并发写入场景。
  • 缺点:数据一致性最弱、存在丢数据风险。主库返回成功时,数据仅存在主库本地,从库大概率还未同步日志。如果此时主库瞬间宕机、磁盘损坏,未同步的 Binlog 会直接丢失,从库无法补齐数据,造成数据永久缺失。
  1. 半同步复制—— 生产推荐
    半同步复制是为了解决异步复制丢数据的问题诞生的,也是目前互联网公司核心业务的标配模式。它在性能和数据安全之间做了完美平衡,既不会像全同步复制那样严重拖垮性能,又能杜绝绝大多数数据丢失风险。
    核心定义:主库事务提交、写入 Binlog 后,必须阻塞等待至少一台从库确认接收日志并落盘,收到从库 ACK 应答后,才会响应客户端执行成功。

执行时序:

  1. 客户端提交写事务到主库;
  2. 主库执行事务,完成本地数据落盘,并写入本地 Binlog 日志;
  3. 主库进入短暂阻塞状态,暂停响应客户端,等待从库回执;
  4. 从库 IO 线程拉取该条 Binlog,成功写入本地 Relay Log 并刷盘;
  5. 从库立即向主库返回 ACK 确认包(仅确认日志落盘,不等待 SQL 执行);
  6. 主库收到 ACK,结束阻塞,返回「执行成功」给客户端;
  7. 后续从库后台异步执行 Relay Log,完成数据同步。
    关键核心细节:
  • 阻塞临界点:主库只等「从库日志落盘确认」,绝不等待从库执行完事务,极大降低了性能损耗;
  • 容错机制:主库默认超时时间为 1 秒(参数 rpl_semi_sync_master_timeout),若 1 秒内未收到从库 ACK,会自动降级为异步复制,避免大量请求阻塞、业务雪崩;
  • 数据安全保障:只要客户端收到成功响应,就意味着数据同时存在「主库+至少一台从库」双份磁盘落地,主库宕机也不会丢失数据。
    核心优缺点:
  • 优点:数据安全性极高,几乎零丢数据风险;性能损耗极低,仅增加少量网络等待耗时;支持自动降级,兼容极端异常场景。
  • 缺点:相比异步复制有轻微网络延迟,超高并发极致压测场景下性能略低于异步复制。
  1. 全同步复制
    全同步复制是安全级别最高的同步模式,也是最严苛的同步机制,彻底解决数据不一致、数据丢失问题,但牺牲了极致的写入性能,线上业务基本不会采用。
    核心定义:主库事务提交后,必须等待集群中所有从库全部完成「日志接收、落盘、事务重放执行」,所有从库全部返回确认 ACK 后,主库才会响应客户端执行成功。

执行时序:

  1. 客户端提交写事务到主库;
  2. 主库执行事务、写入 Binlog,进入长时间阻塞状态;
  3. 所有从库分别拉取 Binlog,写入 Relay Log,执行 SQL 完成数据更新;
  4. 每一台从库全部执行完成后,依次向主库返回确认包;
  5. 主库收集完所有从库的 ACK 确认,才解除阻塞,返回执行成功。
    核心优缺点:
  • 优点:全局数据强一致性,主从所有节点数据实时完全一致,零延迟、零丢失,无任何数据不一致风险。
  • 缺点:性能缺陷致命。集群从库数量越多,阻塞时间越长;只要有一台从库卡顿、故障、网络延迟,所有主库写入请求都会被阻塞,直接拖垮整个业务写入能力。

重点记住:MySQL 主从复制只会同步「开启同步之后的新数据」,不会自动同步历史存量数据。
如果主库已经运行一段时间,存在大量历史数据,直接配置主从同步、不做全量备份,最终结果就是:从库只有后续新增的数据,缺失所有历史数据,主从数据彻底不一致,甚至出现主键冲突、同步中断的问题。

常见问题

  • 同步延迟:多由大事务、主库写入并发过高、从库硬件配置偏低导致,可通过拆分大事务、升级从库配置、开启并行复制优化
  • 同步中断、主键冲突:大多是从库手动写入数据、历史数据不一致导致,生产环境务必设置从库只读
  • IO 线程异常:多为主从网络不通、同步账号密码错误、主库 Binlog 日志被清理导致

五.MySQL 主从复制 模式分类
MySQL 主从复制模式 = 同步机制 + 定位方式 + 记录格式 + 并行能力 + 架构形态

  1. 按事务一致性
    异步复制
    半同步复制
    全同步复制

  2. 按 binlog 定位方式
    传统 File & Position 模式
    GTID 模式(生产主流)

  3. 按 binlog 记录格式
    行模式(ROW)
    语句模式(STATEMENT)
    混合模式(MIXED)

  4. 按并行复制能力
    单线程复制
    多线程并行复制

  5. 高级复制架构
    组复制(MGR)
    主主复制
    级联复制

五、MySQL 一主两从,传统 File&Position 模式 + 异步复制

环境:

  • 主库 (Master):192.168.1.131

  • 从库 1 (Slave1):192.168.1.132

  • 从库 2 (Slave2):192.168.1.133

第一步:三台虚拟机 时间必须同步

主从时间不一致,复制会直接异常、延迟、报错。

所有机器执行(131/132/133 都运行)

  1. 安装时间同步工具

yum install -y chrony

  1. 启动并开机自启

systemctl start chronyd
systemctl enable chronyd

  1. 查看时间是否同步

date

三台机器时间误差必须 < 1 秒。

第二步:关闭防火墙 / 开放 3306(三台都执行)

临时关闭防火墙
systemctl stop firewalld

禁止开机启动
systemctl disable firewalld

关闭SELINUX
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

第三步:保证主从初始数据完全一致(核心步骤)

原理

  1. 主库锁表 → 备份数据 → 解锁

  2. 把备份文件发送到两个从库并恢复

  3. 恢复后主从数据 100% 一致

操作步骤

  1. 主库(131)锁表,禁止写入

FLUSH TABLES WITH READ LOCK;

执行后不要退出这个 MySQL 窗口! 锁表状态会保持。

  1. 查看主库 binlog 位置(记录下来,从库要用)

SHOW MASTER STATUS;

你会看到类似:

File | Position
binlog.000001 | 1148

记下来!等会儿配置从库要用。

  1. 新开一个 SSH 窗口,主库全量备份

mysqldump -uroot -p --all-databases --master-data=2 --single-transaction > all_db.sql

  1. 主库解锁

UNLOCK TABLES;

  1. 把备份文件发送到 从库 1、从库 2

发送到132
scp all_db.sql root@192.168.1.132:/root/

发送到133
scp all_db.sql root@192.168.1.133:/root/

  1. 从库 1(132)恢复数据

mysql -uroot -p < /root/all_db.sql

  1. 从库 2(133)恢复数据

mysql -uroot -p < /root/all_db.sql

第四步:配置主库(131)my.cnf

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema

重启 MySQL

systemctl restart mysqld

主库创建复制账号(给从库用)

CREATE USER 'repl'@'%' IDENTIFIED BY 'Aa123456.';
GRANT REPLICATION SLAVE ON . TO 'repl'@'%';
FLUSH PRIVILEGES;

第五步:配置从库 1(132)

[mysqld]
server-id = 2
relay-log = relay-bin
read_only = 1
super_read_only = 1

重启 MySQL

systemctl restart mysqld

执行主从关联命令

CHANGE MASTER TO
MASTER_HOST='192.168.88.131',
MASTER_USER='repl',
MASTER_PASSWORD='Aa123456.',
MASTER_LOG_FILE='binlog.000001', # 你刚才记录的FILE
MASTER_LOG_POS=1148; # 你刚才记录的START SLAVE;

第六步:配置从库 2(133)

[mysqld]
server-id = 3
relay-log = relay-bin
read_only = 1
super_read_only = 1

重启 MySQL

systemctl restart mysqld

执行主从关联命令

CHANGE MASTER TO
MASTER_HOST='192.168.88.131',
MASTER_USER='repl',
MASTER_PASSWORD='Aa123456.',
MASTER_LOG_FILE='binlog.000001', # 你刚才记录的FILE
MASTER_LOG_POS=1148; # 你刚才记录的START SLAVE;

第七步:验证主从是否成功(两个从库都执行)

SHOW SLAVE STATUS\G

看到这两个都为 YES 就成功了:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

第八步:验证主从数据是否真的一致

主库创建库 + 表 + 插入数据

CREATE DATABASE testdb;
USE testdb;
CREATE TABLE t1(id INT);
INSERT INTO t1 VALUES(1);

从库直接查询

USE testdb;
SELECT * FROM t1;

能查到数据 = 主从同步成功!

五.总结

  1. 主从复制核心是binlog + 3 个线程,实现主库数据自动同步到从库

  2. 生产环境标配:主从架构 + 读写分离 + 半同步复制

  3. 搭建关键:server-id 唯一、binlog 开启、主从数据初始一致、复制账号权限正确

  4. 核心验证:SHOW SLAVE STATUS 两个线程必须为YES

  5. 三台时间必须同步(chrony)

  6. 主库锁表备份 → 从库恢复 → 数据 100% 一致

  7. server-id 不能重复(1、2、3)

  8. 从库配置 read_only 防止误写

  9. 检查 SHOW SLAVE STATUS\G 两个 YES = 成功

posted @ 2026-06-04 13:54  modenq  阅读(29)  评论(0)    收藏  举报