1.概述
随着数据量的增长和业务的扩展,数据库的高可用性和性能需求变得尤为重要,但与此同时单个数据库服务无法再满足日常的大量使用需求,负载过重。这时候就必须把数据库从单一部署调整为集群模式,实现负载均衡、读写分离从而保证系统的高可用。MySQL 主从复制 是一种常见的高可用架构,不仅可以分担主库的读压力,还能为数据备份和故障恢复提供保障。本文将详细介绍 MySQL 主从复制的实现原理,并提供完整的配置操作教程。
2.主从复制实现原理
MySQL
本身提供了主从复制的技术支持,所以无需通过第三方技术来协助实现。主从复制的过程主要基于binlog日志完成的,binlog(binary log 即二进制日志文件) 主要记录了 MySQL 数据库中数据的所有变化(数据库执行的所有 DDL 和 DML 语句)。因此,我们根据主库的 binlog 日志就能够将主库的数据同步到从库中。
步骤流程如下:
客户端提交写请求,主库master更新数据,并记录binlog
从库slave连接主库master:也就是在从库slave上执行change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量;开启数据复制同步,即在从库slave上执行start slave命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。主库会创建一个 binlog dump 线程来发送 binlog,通过
show processlist
可以看到:binlog变化之后 dump线程会读取主库master节点上的binlog日志,然后将binlog日志发送给从库slave节点上的I/O线程
从库slave的 I/O 线程将接收的 binlog 写入到 relay log 中
从库slave节点上的SQL线程,会来读取relaylog中的binlog日志,将其解析成具体的增删改操作,把这些在master节点上进行过的操作,重新在slave节点上也重做一遍,达到数据还原的效果,这样就可以保证master节点和slave节点的数据一致性了。.
3.主从复制搭建
主从架构的形式多种多样,有一主多从,也有多主多从的,这里我们以一主多从为例部署一个一主二从的集群,先准备三台机器如下:
master 10.10.0.10
slave1 10.10.0.14
slave2 10.10.0.22
接下来我们使用docker部署这3个MySQL实例,先部署主库master:
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
可以看到我们部署版本是5.7,这里我已经提前拉取过MySQL5.7的镜像了,没拉取的先拉取下镜像再执行上面的命令, -v
就是将容器内目录文件挂载到宿主机对应的目录文件,对docker不太熟悉的,可以看看之前我们总结的:docker使用入门教程
在/mydata/mysql/conf
下新增MySQL配置文件my.cnf
,内容如下:
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
# 配置时间
default-time_zone = '+8:00'
# 打开binlog
log-bin=mysql-bin
# 选择ROW(行)模式
binlog-format=ROW
# 配置MySQL replaction需要定义,不能slave的server_id重复
server_id=1
大体上就是配置了一下字符集、时间和开启binlog并设置为row格式,同时设置在主从架构中唯一的server_id。
重启MySQL服务让配置生效
docker restart mysql
当然你也可以先去宿主机/mydata/mysql/conf
配置好my.conf
,再执行上面的部署命令,这样一次搞定,不用重启了,反正都可以的,怎么舒服怎么来。
紧接着按照上面同样的操作部署从库slave1,配置文件和上面也差不多,修改server_id=2,保证与主库master不一样,并配置中继日志relaylog即可
server_id=2
#启用中继日志
relay-log=mysql-relay
启动成功之后,我们就可以按照上面的主从复制原理进行数据同步了。
首先在主库master创建一个用于复制的用户账号并赋权:
CREATE USER 'slave-user'@'%' IDENTIFIED BY '126289';
GRANT REPLICATION SLAVE ON *.* TO 'slave-user'@'%';
FLUSH PRIVILEGES;
接着查看主库master的binlog文件名和位置:
show master status;
然后来从库slave1上执行复制配置命令:
CHANGE MASTER TO
MASTER_HOST='10.10.0.10',
MASTER_USER='slave-user',
MASTER_PASSWORD='126289',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=751;
开启复制:
start slave;
查看复制状态:
show slave status;
重点关注下我圈出来的参数:Slave_IO_Running
和Slave_SQL_Running
都是Yes
,说明主从配置成功,否则就说明主从同步有问题,就需要看看Last_Error
报错信息了,比如说由于主从数据不一致导致的表不存在等:
最后一个圈出的参数Seconds_Behind_Master
代表的就是主从延迟时长,需要重点关注的参数。
现在你就可以在主库master上操作数据,从库slave1很快就同步了,由于都是新部署的实例,这里我在mater新增一个数据库db_test
和一张表tb_user
:
可以看到slave1很快就同步了master新增的数据库和表,还可以在master插入tb_user
数据,验证下slave1是否同步,你自己可以试试。
现在是一主一从的架构,但是随着业务系统使用时间的推移,数据库压力开始越来越大,这时候就需要部署更多的从节点来分担压力,于是乎就有了slave2,部署过程和上面一样,只是要稍微注意下复制配置如下:
CHANGE MASTER TO
MASTER_HOST='10.10.0.10',
MASTER_USER='slave-user',
MASTER_PASSWORD='126289',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1;
MASTER_LOG_FILE
是指定从库开始同步的主库 二进制日志文件名,告诉从库从哪个日志文件开始读取数据。
MASTER_LOG_POS
是指定从库从二进制日志的 特定位置 开始读取数据。
上面我们是通过show master status;
获得mater的binlog最新日志文件名和位置,然后去同步,这种情况是在master和slave1数据一致的情况是可以的,因为两个都是新部署的没有任何操作,但是部署slave2的是master已经使用一段时间了,这两个参数的值就不能从show master status;
中获取了,可能binlog都产生好几个文件了,slave2要想全量同步复制master的数据,就必须从最早的binlog文件的最初位置开始同步,这也是上面slave2同步参数由来。如果master有很多数据,你就会注意到slave2的Seconds_Behind_Master
主从延迟值不再是0
到这里,我们的一主二从的主从复制架构环境就算搭建完成了。
4.总结
MySQL 主从复制是提升数据库性能和可用性的有效手段,通过合理的配置和优化,可以有效实现读写分离、数据备份和故障恢复。本文从主从复制的原理入手,详细讲解了配置步骤和常见问题解决方案,希望能帮助你搭建稳定可靠的 MySQL 高可用架构。如果本文对你有帮助的话,麻烦给个一键三连(点赞、在看、转发分享)支持一下,感谢Thanks♪(・ω・)ノ