MySQL主从复制原理与实现
主从复制的作用
- 数据冗余与容灾: 通过将数据复制到一个或多个从服务器,可以创建数据的冗余副本。在主服务器发生故障的情况下,可以从服务器迅速接管服务,避免数据丢失和业务中断,实现高可用性。
- 读写分离: 主从复制允许将写操作(如INSERT、UPDATE、DELETE)集中在主服务器上,而将读操作(如SELECT)分散到一个或多个从服务器上。这种读写分离的设计可以显著减轻主服务器的负载,提高读操作的响应速度和系统整体的处理能力。
- 负载均衡: 从服务器可以分担读操作的负载,实现负载均衡。对于读密集型的应用,这可以极大地提升性能和响应时间。
实现原理
一、binlog
binlog 是 mysql Server 层生成的日志文件。binlog 文件是记录了所有数据库表结构变更核表数据修改的日志,不会记录查询类的操作。如SELECT、SHOW 等操作。
binlog 是追加写,写满一个文件,就创建一个新的文件继续写,不会覆盖以前的日志,保存的是全量的日志。
因此binlog 可以用于备份恢复、主从复制;
二、主从复制实现
mysql 的主从复制依赖于binlog,具体的过程主要有以下三个步骤:
- 主服务器开启binlog日志功能,记录所有改变数据的语句。
- 从服务器通过一个IO线程连接到主服务器,请求从最后一个成功复制的位置开始的binlog文件,主服务器响应从服务器的请求,发送binlog日志事件给从服务器。从服务器接收到这些日志后,将其存储在本地的“中继日志”(Relay Log)中。中继日志本质上是主服务器binlog日志的副本,保存在从服务器上。
- 从服务器开启SQL线程读取中继日志中的事件,并在从服务器的数据库上重放这些事件,以达到主从数据库之间的数据一致。
这个过程一般是异步的,也就是主库上执行事务操作的线程不会等待复制 binlog 的线程同步完成。
MySQL 主从复制模型:
- 同步复制:主库提交事务的线程等待所有从库复制成功后才能响应客户端。性能很差。
- 异步复制:主库的线程不需要等待从库复制成功,性能很好,但是主库一旦宕机,数据就会丢失。
- 半同步复制:主库只需要等待部分从库复制成功即可,不需要等待全部成功,是一种折中的方法,性能不会很差,在主库宕机后,也至少有一个从库上有最新的数据,不会发生数据丢失。
基于docker 的主从复制实现
使用docker 创建两个mysql容器,一个作为主库,一个作为从库,实现主从复制。
1. 基于 docker-compose 创建主从容器
编写 docker-compose.yaml
文件
version: '3.1'
services:
mysql-master:# 第一个service
image: mysql:8.0.26 # 使用的镜像
container_name: mysql-master # 容器名
environment:# 设置mysql的密码核数据库的环境变量
MYSQL_ROOT_PASSWORD: xxx
MYSQL_DATABASE: db_name
volumes:# 挂载卷
- ./master/data:/var/lib/mysql# mysql 的数据挂在到宿主机的master/data
- ./master/init/init.sql:/docker-entrypoint-initdb.d/init.sql:ro # 挂在数据库表脚本
ports:# 端口映射
- "3306:3306"
command:
--default-authentication-plugin=mysql_native_password# 默认认证插件
--log-bin=mysql-bin# 开启binlog日志功能,基础名为 mysql-bin
--server-id=1 # 指定唯一的ID
# 配置从服务器
mysql-slave:
image: mysql:8.0.26
container_name: mysql-slave
depends_on:
- mysql-master
environment:
MYSQL_ROOT_PASSWORD: xxx
MYSQL_DATABASE: db_name
volumes:
- ./slave/data:/var/lib/mysql
- ./master/init/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
ports:
- "3307:3306"
command:
--default-authentication-plugin=mysql_native_password
--server-id=2
--log-bin=mysql-bin
--relay-log=relay-bin# 指定中继日志(relay log)文件的基本名称
--read-only=1
volumes:
master-data:
slave-data:
启动容器:
docker-compose up -d
2. 配置主从复制
首先在主服务器中获取binlog的文件名和开始位置:
- 进入主容器
- 进入主容器的mysql
- 执行
SHOW MASTER STATUS\G
记录输出中的 File
和 Position
。
进入从容器的MySQL,输入以下命令配置从节点的复制:
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='replicator',
MASTER_PASSWORD='replicatorpassword',
MASTER_LOG_FILE='mysql-bin.000003', -- 使用上面记录的 File 值
MASTER_LOG_POS=838; -- 使用上面记录的 Position 值
START SLAVE;
查看从节点状态:
SHOW SLAVE STATUS\G;
确保 Slave_IO_Running
和 Slave_SQL_Running
均为 Yes
验证:
在主节点表中插入数据,然后去从节点表中去看有没有插入同样的数据,如果有,则主从复制配置成功。
如果没有,则在从节点执行SHOW SLAVE STATUS\G;
关注Last_Error
字段报错的问题。
3. bug记录
本人在创建时由于没有给从节点加载一样的数据库表结构,导致在主节点插入数据的时候从节点同步失败。Last_Error
字段报没有找到表。
解决方法就是在从节点的mysql中加载构建表的sql脚本,之后重新配置从节点的复制配置:
STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='replicator',
MASTER_PASSWORD='replicatorpassword',
MASTER_LOG_FILE='mysql-bin.000003', -- 使用主节点的File值
MASTER_LOG_POS=838; -- 使用主节点的Position值
START SLAVE;
SHOW SLAVE STATUS\G;
下一篇在此基础上实现读写分离:
MySQL实现读写分离
原文地址:https://blog.csdn.net/qq_44957574/article/details/140591590
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!