MySQL主从复制

目录

一:MySQL主从复制原理

1:MySQL支持的复制类型

[(1) 基于语句的复制(SBR)](#(1) 基于语句的复制(SBR))

[(2) 基于行的复制(RBR)](#(2) 基于行的复制(RBR))

[(3) 混合模式复制(MBR)](#(3) 混合模式复制(MBR))

2:复制的工作过程

[(1) 主服务器操作](#(1) 主服务器操作)

[(2) 从服务器操作](#(2) 从服务器操作)

[(3) 详细流程](#(3) 详细流程)

二:案例环境

[1. 服务器规划](#1. 服务器规划)

[2. 网络要求](#2. 网络要求)

三:案例实施

1:配置master主服务器

(1)修改MySQL配置文件(my.cnf)

(2)重启MySQL服务

(3)创建复制专用用户

(4)查看主服务器状态

2:配置slave从服务器

(1)修改MySQL配置文件(my.cnf)

(2)重启MySQL服务

(3)登录MySQL,配置同步

(4)启动同步

(5)查看slave状态,确保一下两个值为YES

3:验证主从复制效果

(1)在主服务器创建测试数据库

(2)在从服务器验证


一:MySQL主从复制原理

1:MySQL支持的复制类型

(1) 基于语句的复制(SBR)

  • 主服务器记录执行的SQL语句

  • 从服务器重放这些SQL语句

  • 优点:日志量小

  • 缺点:某些函数(如UUID(), NOW())可能导致不一致

(2) 基于行的复制(RBR)

  • 主服务器记录行级别的变更

  • 从服务器直接应用这些行变更

  • 优点:数据一致性高

  • 缺点:日志量大

(3) 混合模式复制(MBR)

  • 默认使用基于语句的复制

  • 在特定情况下自动切换到基于行的复制

  • 结合了两者的优点

2:复制的工作过程

(1) 主服务器操作

  1. 二进制日志记录:主服务器将所有数据更改操作(DDL和DML)记录到二进制日志(binlog)中

  2. 日志刷新:通过sync_binlog参数控制日志刷新到磁盘的频率

(2) 从服务器操作

  1. I/O线程

    • 连接到主服务器

    • 请求主服务器发送binlog中的更新

    • 接收binlog并写入从服务器的中继日志(relay log)

  2. SQL线程

    • 读取中继日志中的事件

    • 重放这些事件,更新从服务器数据

(3) 详细流程

  1. 主库开启binlog,从库通过change master命令配置连接主库的信息

  2. 从库启动复制后,I/O线程与主库建立连接

  3. 主库验证从库连接后,开始发送binlog事件

  4. 从库I/O线程接收事件并写入relay log

  5. 从库SQL线程读取relay log并应用这些事件

  6. 从库记录已经处理的事件位置(relay-log.info)

二:案例环境

1. 服务器规划

  • 操作系统: openEuler

  • MySQL版本: 5.7 或 8.0 (建议使用相同版本)

|--------|-----------------|----------------|--------------|
| 主机 | 操作系统 | ip地址 | 应用 |
| Master | openEuler 24.03 | 192.168.10.101 | Mysql-server |
| Slave1 | openEuler 24.03 | 192.168.10.102 | Mysql-server |
| Slave2 | openEuler 24.03 | 192.168.10.103 | Mysql-server |
| mycat | openEuler 24.03 | 192.168.10.104 | mycat2 |
| 客户端 | openEuler 24.03 | 192.168.10.105 | mysql |
[案例环境]

2. 网络要求

  • 确保主从服务器之间网络互通

  • 开放MySQL默认端口3306

  • 关闭防火墙或设置相应规则

三:案例实施

1:配置master主服务器

(1)修改MySQL配置文件(my.cnf)

cpp 复制代码
[client]
socket=/usr/local/mysql/data/mysql.sock 
[mysqld] 
server-id=1
socket=/usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
skip-name-resolve
port = 3306
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
max_connections=2048
character-set-server=utf8
default-storage-engine=INNODB
lower_case_table_names=1
max_allowed_packet=16M

[mysqld_safe]
log-error=/usr/local/mysql/data/error.log
pid-file=/var/run/mariadb/mariadb.pid

(2)重启MySQL服务

cpp 复制代码
systemctl restart mysqld

(3)创建复制专用用户

cpp 复制代码
mysql -uroot -ppwd123
create user 'myslave'@'%' identified by '123456';
grant replication slave on *.* to 'myslave'@'%';
alter user 'myslave'@'%' identified with mysql_native_password by '123456';

(4)查看主服务器状态

cpp 复制代码
flush privileges;

show master status;
#记录输出中的File和Position值,例如:
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      745 | test_db      | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+

2:配置slave从服务器

在Slave1,Slave2服务器上面分别执行下面步骤:

(1)修改MySQL配置文件(my.cnf)

cpp 复制代码
[client]
socket=/usr/local/mysql/data/mysql.sock 
[mysqld] 
server-id=2
socket=/usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
skip-name-resolve
port = 3306
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
max_connections=2048
character-set-server=utf8
default-storage-engine=INNODB
lower_case_table_names=1
max_allowed_packet=16M

[mysqld_safe]
log-error=/usr/local/mysql/data/error.log
pid-file=/var/run/mariadb/mariadb.pid

(2)重启MySQL服务

cpp 复制代码
systemctl restart mysqld

(3)登录MySQL,配置同步

cpp 复制代码
mysql -uroot -ppwd123
change master to master_host='192.168.10.201',master_user='myslave',master_password='123456',master_log_file='mysql-bin.00001',master_log_pos=157;

(4)启动同步

cpp 复制代码
start slave;

(5)查看slave状态,确保一下两个值为YES

cpp 复制代码
start slave status\G;

3:验证主从复制效果

(1)在主服务器创建测试数据库

cpp 复制代码
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));
INSERT INTO test_table (name) VALUES ('测试数据1'), ('测试数据2');

(2)在从服务器验证

cpp 复制代码
USE test_db;
SELECT * FROM test_table;
相关推荐
小白勇闯网安圈6 小时前
Django 响应对象、文件上传与类视图
数据库·django·sqlite
努力的小雨7 小时前
同一份 SQL 跑多套环境:Ksql 变量怎么用才安全
数据库
科技绘图8 小时前
快鲸GEO vs 传统AI搜索优化:全链路自动化与高效内容生产在转化闭环上的对比
数据库·人工智能·自动化
ltl8 小时前
数据库作为 LLM 记忆体:语义缓存、RAG 与一致性
数据库
ltl8 小时前
WAL 与崩溃恢复:ARIES 协议怎么跑通
数据库
ltl8 小时前
TEE 数据库:EnclaveDB、Oblivious 原语与机密 SQL
数据库
麻瓜code9 小时前
【Mysql】重新学一遍 SQL 执行顺序
数据库·sql
这个DBA有点耶10 小时前
数据库一体机架构演进:从硬件堆叠到软硬深度耦合
服务器·网络·数据库·硬件架构·运维开发·database·数据库架构
一只fish10 小时前
优化器架构对比:Oracle vs PostgreSQL vs MySQL
mysql·postgresql·oracle
安_11 小时前
RAG的向量数据库:为LLM提供语义搜索能力
数据库