MySQL 主从复制架构搭建及其原理

前言

系统的性能瓶颈一般出现在数据库上,以 mysql 为例,如果存在高并发的写请求,势必会有锁表,锁数据行的情况发生,这时候如果有读请求刚好访问到被锁的数据,那么读请求会阻塞,直到写请求处理完释放锁,系统性能大大下降。

为了提高数据库性能,可以搭建一个简单的 mysql 主从复制集群。使用 mysql 主从复制集群,master 节点用来处理写请求,slave 节点用来处理读请求,当 master 数据变化时,自动将新的数据异步同步到 slave 节点上,实现读写分离。根据读请求的并发量的大小,动态扩展集群里的 slave 节点,实现水平化扩容。

本文演示搭建一个 mysql 主从复制集群(一主一从)的基本流程。

启动两台虚拟机,地址分别为 192.168.130.128,192.168.130.129,两台机器都以安装了 mysql 8.0.36

Linux(CentOS7)安装 MySQL8-CSDN博客https://blog.csdn.net/typeracer/article/details/137183709

主库

配置文件

mysqld\]下增加以下内容 > # 配置要给Slave同步的数据库 > > binlog-do-db=test > > # 不用给Slave同步的数据库,一般是Mysql自带的数据库就不用给Slave同步了 > > binlog-ignore-db=mysql > > binlog-ignore-db=information_schema > > binlog-ignore-db=performance_schema > > binlog-ignore-db=sys > > # 自动清理7天前的log文件 > > expire_logs_days=7 > > # 启用二进制日志 > > log-bin=mysql-bin > > # 为 0 则是文件系统自行决定什么时候来做同步,或者cache满了之后才同步到磁盘,性能最好,不过风险也最大 > > # 为 n 每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。 > > sync_binlog=1 > > # Master的id,这个要唯一,唯一是值,在主从中唯一 > > server-id=1 > > # 主库读写 > > read_only = 0 ### 启动服务 指定我们自己的配置文件启动 mysql 服务 ```bash ./mysqld --defaults-file=/usr/local/mysql/my.cnf ``` 查看 log_bin 是否开启 ```bash show variables like '%log_bin%'; ``` ![](https://file.jishuzhan.net/article/1777332549006135297/00c0f8025a5867394aabf8f35b463647.webp) ### 查看主库状态 ```bash show master status; ``` ![](https://file.jishuzhan.net/article/1777332549006135297/6c36401aff272665ac5a5c22d4ad5026.webp) File 和 Position 需要记下来,在从库配置连接主库时需要用到。 ### 创建同步用户 ```bash create user 'backup'@'%' IDENTIFIED BY '123456'; grant file on *.* to 'backup'@'%'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* to 'backup'@'%'; ``` ## 从库 ### 配置文件 > # 指定要同步master的数据库,不填默认复制全部 > > # replicate-do-db=test > > # 配置从服务器的ID,唯一的 > > server-id=2 > > # 从库只读 > > read_only=1 ### 启动服务 指定我们自己的配置文件启动 mysql 服务 ```bash ./mysqld --defaults-file=/usr/local/mysql/my.cnf ``` ### 配置主库连接 * source_host 主库ip * source_port 主库端口 * source_user 主库创建的同步用户 * source_password 密码 * master_log_file 主库的binlog文件 * mast_log_pos 主库的binlog文件偏移量 * get_master_public_key 获取主库公钥加密密码 ```bash change replication source to source_host='192.168.130.128',source_port=3306,source_user='backup',source_password='123456',master_log_file='mysql-bin.000001',master_log_pos=157,get_master_public_key=1; ``` 注意 这里是从库配置连接主库使用的用户和密码 由于本文使用的是mysql8,在创建主库的同步用户时没有指定认证方式,所以在配置连接主库时需要加上 get_master_public_key=1 这个参数,否则启用同步后,IO线程会出错误,状态一直为Replica_IO_Running: Connecting,从而同步不了。 如果创建用户时指定了 mysql_native_password 认证方式,则不需要加上此参数。 ```bash #指定认证方式 create user 'backup'@'%' identified with 'mysql_native_password' by '123456'; #若没有指定认证方式,MySQL 8.0默认使用caching_sha2_password # 如果使用caching_sha2_password认证方式,mysql会要求连接开启SSL,或者使用RSA对密码进行加密 # 否则连接可能会报如下的错误:Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection. create user 'backup'@'%' IDENTIFIED BY '123456'; ``` ### 开启同步 开启同步 ```bash start replica; ``` 其他相关命令 ```bash stop replica; reset replica all; ``` ### 查看从库状态 ```bash show replica status\G; ``` ![](https://file.jishuzhan.net/article/1777332549006135297/ec6f1e83877cf55ba2378c8ef4405aae.webp) IO 线程和 SQL 线程状态都为 Yes,即主从配置成功。 ## 验证 在主库创建 test 库,在 test 库中创建 test 表,插入一条数据 > create database test; > > use test; > > create table test > > ( > > id varchar(30) collate utf8mb4_general_ci default '' not null > > primary key, > > name varchar(100) collate utf8mb4_general_ci null, > > parentId varchar(30) collate utf8mb4_general_ci null comment '父分类id' > > ) > > comment 'test'; > > insert into test values('1','name1',null); ![](https://file.jishuzhan.net/article/1777332549006135297/95584611d1985f69f50403cf64568b04.webp) ![](https://file.jishuzhan.net/article/1777332549006135297/75cc7a403593809764ed4e6ca8a1d88e.webp) 从库检查 ![](https://file.jishuzhan.net/article/1777332549006135297/c7230b16eb3475f0168a732edc4342db.webp) ## 主从复制原理 plantUML > > ``` > @startuml > 'https://plantuml.com/sequence-diagram > > autonumber > > database master > participant 主库bin_log > participant 从库IO线程 > participant 从库relay_log > participant 从库SQL线程 > database slave > > master <- slave: 连接主库 > master -> 主库bin_log: 数据更新\n写入二进制日志 > 从库IO线程 -> 主库bin_log: 读取 > 从库IO线程 -> 从库relay_log: 写入 > 从库SQL线程 -> 从库relay_log: 读取 > 从库SQL线程 -> slave: 重放 > > @enduml > ``` 时序图 ![](https://file.jishuzhan.net/article/1777332549006135297/76534496de93edbb24529441a91dda96.webp)

相关推荐
松果猿7 分钟前
空间数据库学习(二)—— PostgreSQL数据库的备份转储和导入恢复
数据库
c无序11 分钟前
【Docker-7】Docker是什么+Docker版本+Docker架构+Docker生态
docker·容器·架构
Kagol15 分钟前
macOS 和 Windows 操作系统下如何安装和启动 MySQL / Redis 数据库
redis·后端·mysql
无名之逆16 分钟前
Rust 开发提效神器:lombok-macros 宏库
服务器·开发语言·前端·数据库·后端·python·rust
s91236010116 分钟前
rust 同时处理多个异步任务
java·数据库·rust
数据智能老司机24 分钟前
CockroachDB权威指南——CockroachDB 架构
数据库·分布式·架构
矿渣渣40 分钟前
RM Cortex-A7 架构中“SEV”汇编指令解析
汇编·架构
hzulwy1 小时前
Redis常用的数据结构及其使用场景
数据库·redis
程序猿熊跃晖1 小时前
解决 MyBatis-Plus 中 `update.setProcInsId(null)` 不生效的问题
数据库·tomcat·mybatis
uhakadotcom2 小时前
Flutter入门指南:快速构建高性能移动应用
面试·架构·github