MySQL 主从复制
目录
++[一、概述... 2](#一、概述... 2)++
++[1.1、主从复制... 2](#1.1、主从复制... 2)++
++[1.2、复制架构... 2](#1.2、复制架构... 2)++
++[1.3、MySQL复制的优点... 2](#1.3、MySQL复制的优点... 2)++
++[二、原理... 2](#二、原理... 2)++
++[2.1、MySQL 主从复制原理(经典异步复制)... 2](#2.1、MySQL 主从复制原理(经典异步复制)... 2)++
++[2.2、流程图... 3](#2.2、流程图... 3)++
++[三、搭建... 3](#三、搭建... 3)++
++[3.1、服务器准备... 3](#3.1、服务器准备... 3)++
++[3.2、主库配置... 4](#3.2、主库配置... 4)++
++[3.3、从库配置... 5](#3.3、从库配置... 5)++
++[四、测试... 6](#四、测试... 6)++
++[4.1、在主库上创建数据库、表,并插入数据... 6](#4.1、在主库上创建数据库、表,并插入数据... 6)++
一、概述
1.1、主从复制
主从复制 是指将主数据库(Master)上的 DDL 和 DML 操作记录到 二进制日志(binary log) 中,并将这些日志传送到从数据库(Slave),由从库的 I/O 线程 和 SQL 线程 进行读取和重放(也称"重做"),从而使从库的数据与主库保持同步。
整个过程分为三个主要步骤:
- 主库将所有数据变更操作(如 INSERT、UPDATE、DELETE、CREATE 等)记录到二进制日志(binlog)中;
- 从库 I/O 线程连接主库并读取 binlog 内容,写入本地的中继日志(relay log);
- 从库 SQL 线程读取中继日志并执行其中的 SQL 操作,实现与主库数据的一致性。
1.2、复制架构
MySQL支持一台主库同时向多台从库进行复制,从库同时也可以作为其他从服务器的主库,实现链状复制。
MySQL 支持一主多从的复制架构,即一台主库(Master)可以同时将其二进制日志复制到多台从库(Slaves),实现数据的同步分发。
此外,从库也可以同时充当其他从库的主库,继续将接收到的变更同步到下一级从库,形成所谓的**链式复制(Chain Replication)**结构。这种方式适用于层级分布式系统中,便于数据逐级传播,减轻主库负载。
复制架构可以包括:
- 一主多从(One Master, Multiple Slaves)
- 级联复制 / 链式复制(Cascading Replication)
- 环状复制(Circular Replication,主要用于多主容灾方案)
这种灵活的复制机制为高可用、读写分离、备份容灾等场景提供了有力支持。
1.3、MySQL复制的优点
1. 高可用性与容灾备份
- 主库故障时可快速切换到从库,减少业务中断时间。
- 从库可作为热备份,提升数据安全性。
2. 读写分离,提升性能
- 主库负责写操作,从库负责读操作,减轻主库负载,提高系统整体并发能力。
3. 备份不中断业务
- 在从库上进行全库备份或逻辑备份,避免在主库备份时影响正常业务操作。
二、原理
2.1、MySQL 主从复制原理(经典异步复制)
第一阶段:主库写入二进制日志(binlog)
- 当主库执行 DML(INSERT/UPDATE/DELETE)或 DDL(CREATE/ALTER) 操作后,先写入事务日志,再将变更记录写入 binlog(二进制日志)。
- binlog 是主从复制的基础,记录了所有可复制的变更语句或事件。
第二阶段:从库 IO 线程拉取 binlog
- 从库通过 CHANGE MASTER TO 命令配置主库信息后,启动 IO 线程。
- 从库的 IO 线程连接主库的 复制线程(dump thread),从指定位置(File + Position 或 GTID)开始读取 binlog。
- 主库将 binlog 内容发送给从库,从库写入本地的 中继日志(relay log)。
第三阶段:从库 SQL 线程重放 relay log
- 从库的 SQL 线程 读取本地的 relay log,将其中的 SQL 语句逐条执行,以重现主库的数据更改。
- 最终,实现主从数据一致。
2.2、流程图
主库(Master)在事务提交时 ,会将数据变更记录写入 二进制日志(binlog) 文件中。
- 从库(Slave)的 IO 线程 连接主库,读取 binlog 内容并写入从库的中继日志(relay log)。
- 从库的 SQL 线程 解析并 重放中继日志(relay log)中的事件,将这些变更应用到自己的数据中,从而实现与主库的数据同步。
三、搭建
3.1、服务器准备
|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| #开放指定的3306端口号(重新加载防火墙配置使其生效): firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload #验证端口是否已开放 firewall-cmd --list-ports |
| #关闭服务器的防火墙(禁止防火墙开机自启): systemctl stop firewalld systemctl disable firewalld |
3.2、主库配置
- 修改MySQL的配置文件/etc/my.cnf文件:
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #mysql服务ID,保证整个集群环境中唯一,取值范围:1 - 2^32-1,0 是非法的,不能使用,默认为1 server-id=1 #是否只读,1代表只读,0代表读写 read-only=0 #忽略的数据,指不需要同步的数据库 #binlog-ignore-db=mysql #指定同步的数据库 #binlog-do-db=db01 |
忽略这些数据库的变更,不记录进 binlog,也就不会被从库同步;binlog-do-db 和 binlog-ignore-db 不能同时使用(会冲突)。
登录mysql,创建远程连接的账号,并授予主从复制权限
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #创建itcast用户,并设置密码,该用户可在任意主机连接MySQL服务 CREATE USER 'itcast'@'%' IDENTIFIED WITH mysql_native_password BY '123.asd#!M'; #为'itcast'@'%'用户分配主从复制权限 GRANT REPLICATION SLAVE ON *.* TO 'itcast'@'%'; FLUSH PRIVILEGES; |
- 'itcast'@'%':用户 itcast 可从任意主机连接(% 代表任意 IP)。
- IDENTIFIED WITH mysql_native_password:指定使用传统的身份验证插件(兼容性更好)。
- BY '123.asd#!M':设置用户密码为 123.asd#!M。
- 查看当前密码策略:SHOW VARIABLES LIKE 'validate_password%';
validate_password_policy (密码策略级别)
validate_password_length (最小长度)
validate_password_mixed_case_count (大小写字母要求)
validate_password_number_count (数字要求)
validate_password_special_char_count (特殊字符要求)
- REPLICATION SLAVE 权限允许该用户作为从库连接主库,读取二进制日志进行数据复制。
- 'itcast'@'%' 表示允许从任意主机连接。
- FLUSH PRIVILEGES; 刷新权限,使更改立即生效。
- 验证用户是否创建成功:
|----------------------------------------------------------|
| SELECT user, host FROM mysql.user WHERE user = 'itcast'; |

- 通过指令,查看二进制日志坐标:
|---------------------|
| SHOW MASTER STATUS; |

- File:当前正在写入的二进制日志文件(如 mysql-bin.000001)
- Position:当前写入位置(如 154),从库复制将从这里开始
- Binlog_Do_DB:配置中指定的需要记录到 binlog 的数据库(可为空)
- Executed_Gtid_Set:如果启用了 GTID 模式,这里会显示 GTID 集
3.3、从库配置
- 修改MySQL的配置文件/etc/my.cnf文件:
|--------------------------------------------------------------------------------------------------------|
| #mysql服务ID,保证整个集群环境中唯一,取值范围:1 - 2^32-1,0 是非法的,不能使用,默认为1 server-id=2 #是否只读,1代表只读,0代表读写 read-only=1 |
登录mysql,设置主库配置
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CHANGE REPLICATION SOURCE TO SOURCE_HOST = '主库 IP 或主机名', SOURCE_USER = '用户名', SOURCE_PASSWORD = '密码', SOURCE_LOG_FILE = 'binlog 文件名', SOURCE_LOG_POS = 位置号; |
通过 SHOW MASTER STATUS 获取 binlog 文件名,同样通过 SHOW MASTER STATUS 获取位置号。

- 配置完成后,启动复制:
|----------------|
| START REPLICA; |
查看主从同步状态:
|------------------------|
| SHOW REPLICA STATUS\G |

\G 是 MySQL 命令行客户端 中的一个 输出格式控制符 ,它的作用是让查询结果纵向(垂直)显示,以提高可读性,尤其是字段很多时。
四、测试
4.1、在主库上创建数据库、表,并插入数据
- 创建数据库
|------------------------------------------------------------------------|
| CREATE DATABASE db01 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; |
- CHARACTER SET utf8mb4 **:**使用 utf8mb4 字符集,支持完整的 UTF-8 字符(包括表情符号、中文、日文等)。
- COLLATE utf8mb4_general_ci : 指定排序和比较规则为不区分大小写(ci = case-insensitive)的"通用"规则。
- 创建数据表
|------------------------------------------------------------------------------------------------------------------------------|
| USE db01; CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, age INT, grade VARCHAR(10) ); |
- AUTO_INCREMENT 是 MySQL 中用于实现自动增长列的关键字,通常用于主键字段,特别是 id 字段。
- 插入数据
|-----------------------------------------------------------------------------------------------------------|
| INSERT INTO student (name, age, grade) VALUES ('Alice', 20, 'A'), ('Bob', 22, 'B'), ('Charlie', 21, 'A'); |