什么是主从复制
简单来说,主从复制是一种数据同步技术,可以让我们把一个 MySQL 服务的数据同步到一个或多个其它 MySQL 服务中,其中被同步的 MySQL 我们一般称为 “源” 或 “Master(主)”,而进行同步的 MySQL 一般称为 “副本” 或 “Slave(从)”

虽然主从复实现的方法与配置参数繁多,但是各位读者不用担心,在本系列文章中我们会和各位读者一起从最简单的使用 Binary log(二进制日志) 的方法配置一主一从复制开始,逐步掌握 MySQL 中关于主从复制的各种配置与优化操作
为什么需要主从复制
在配置主从复制之前我们先来了解一下我们为什么需要它
首先,主从复制的架构可以支持我们进行读写分离,既 Master 只负责写操作,Slave 只负责读操作,这种分工的做法既分散了 MySQL 读写压力,又避免了同时读写造成的锁冲突,简单有效的提高了 MySQL 读写与并发性能

其次,主从复制提供的数据备份(在 Slave 进行备份不影响 Master 的性能)、故障切换(在 Master 出现故障时切换到 Slave)等能力也对系统的可靠性与容错性有不小的提升。
另外,在主从复制架构下我们可以更大胆的实现计算量庞大的数据分析需求而不用担心影响到数据库的性能,所以在数据需求日渐增长的数据时代,我们有更充足的理由选择进行主从复制配置
基于 Binary log 的主从复制
主从复制分为 Binary log(二进制日志) 与 GTID(全局事务标识) 两种不同的方法,我们今天主要来了解基于 Binary log 的主从复制配置
简单来说,在 Binary log 模式下,作为 Master 的 MySQL 服务会把写操作(UPDATE、INSERT、DELETE)根据所配置的不同格式写入 Binary log,而 Slave 则会读取 Master 的 Binary log 储存到本机上的 Relay log 中,并且定期执行其中的操作

Slave 会执行 Binary log 中所有的操作吗?答案是不一定,Slave 会接收 Binary log 的全部内容但是会根据配置的不同来决定执行哪些操作,比如可以让 Slave 只同步或忽略指定的 Database 或 Table
Slave 接收 Binary log 的全部内容不会浪费资源吗?为什么不让 Master 发送最新的记录?我们需要知道的是,虽然 Slave 会接收全部的 Binary log 但是会记录一个 offset 来标识最后同步的位置,每一次只同步最新的记录,所以不存在浪费资源的问题
这样做的另外一个好处是 Slave 对于 Master 是”透明的”,这不仅不会变相的增加 Master 的负担,还可以保证同步的稳定性,即使 Slave 因为某些原因停止工作一段时间,也可以通过 offset 标识来正确的同步最新数据,而且这一过程基本上不会对 Master 产生任何影响
主从复制的配置
到这里相信读者们已经对主从复制有了一个初步的了解,那么接下来我们就从使用 Docker 部署 MySQL 开始进行 Binary log 模式下一主一从的配置
Docker compose
为了方便与配置复用性,我们使用 Docker compose 来部署 MySQL 服务,编写配置文件 replication.yaml 文件内容如下
在 replication.yaml 中使用 mysql 8.0 镜像部署两个名称分别为 mysql-master 与 mysql-slave-001 的服务,其中比较值得注意是 L14 的目录映射配置,它把 MySQL 容器中的 /etc/mysql/conf.d 目录映射到服务器主机当前目录(./ 代表当前目录)下的 ./mysql-cluster/mysql-master/config 中,这样一来我们之后编辑 MySQL 的配置文件时就不需要进入容器内部了,L29 与其它的目录映射也是同理
使用 Command-1 中的命令来启动两个 MySQL 服务
-
• -f:指定配置文件
-
• -d:在后台启动
-
使用 Command-2 中的命令来查看容器状态
根据 MySQL 版本的不同这里指定的配置文件目录 /etc/mysql/conf.d 可能会有所不同,这是非常容易踩坑的一个点,如果有读者使用以上配置启动容器失败,建议先通过 Command-3 停止并删除容器,然后删除配置文件中的 L14 和 L29 并再次启动容器,然后进入容器并查看配置文件 /etc/my.cnf
以下为 mysq 8.0 的默认 my.cnf 文件内容,可以看到在 L36 引入了 /etc/mysql/conf.d/ 目录下的所有配置,而这就是我们需要存放自己配置文件的位置(把服务器主机上某个目录映射到这里),读者们一定要根据实际情况来映射目录
容器成功启动后会在当前目录下生成配置文件中的映射目录,下图为详细的目录关系,接下来我们要做的就是在主机的 ./mysql-replication/mysql-master/config 与 ./mysql-replication/mysql-slave-001/config 目录下分别编写 Master 与 Slave 的配置文件

MySQL 主从复制配置
master.cnf
我们首先来编写 Master 的配置,配置文件 master.cnf 内容如下,保存到主机的 ./mysql-replication/mysql-master/config 目录下
-
• server_id:服务的唯一 ID,为了方便可以设置为与端口相同的数字
-
• log-bin:开启 Binary log 并指定日志文件名称
-
• binlog-ignore-db:不需要进行同步的数据库名称
-
• binlog_cache_size:每个事务用于缓存 Binary log 的大小,默认 32k 建议根据业务自行调节
-
• binlog_format:Binary log 的格式,可选参数有 mixed、statement、row,本章主要目标为实现配置,各参数间的区别我们会在后续的文章中进行测试
-
• expire_logs_days:Binary log 过期清理时间,默认为 0 不清理
-
slave.cnf
Slave 的配置内容如下,保存到主机的 ./mysql-replication/mysql-slave-001/config 目录下
-
• relay_log:开启 Slave 的中继日志并命名
-
• read_only:设置 slave 为只读
-
• log_slave_updates:Slave 是否将复制事件写入自己的 Binary log,这里涉及到多 Master 与 Slave 间的数据同步问题,我们会在后续的文章中进行测试
编写完成之后我们需要重启容器来使其读取最新的配置
启用主从复制
编写完配置文件并放在指定目录后,我们需要进入容器进行一些简单的设置才能使主从复制生效。在 Master 中需要创建用于复制的用户并授予权限,在 Slave 中则需要明确主机的 IP、端口、复制用户等信息
Master
使用 Command-5 进入 Master 容器
进入容器中的 MySQL 服务(根据实际情况替换用户及密码)
创建用于同步信息的用户
-
• repl:用户名称,请根据实际需求更改
-
• %:不限制登录 IP,请根据实际情况修改
-
• 123456:用户密码,请根据实际情况修改
-
为用户授予 slave 权限
-
• *.*:任何 Database 任何 Table
-
查看 Master 状态并记录 Position 的值

Master 上的工作已完成,接下来进入 Slave 进行配置
Slave
使用 Command-5 与 Command-6 替换命令中的容器名称与用户,进入 Slave 容器,并使用以下命令配置目标 Master
-
• MASTER_HOST:Master 的 IP 地址
-
• MASTER_USER:Master 中用于同步的用户名
-
• MASTER_PORT:Master 的端口号
-
• MASTER_LOG_FILE:Master 状态查询中的 File 字段值
-
• MASTER_LOG_POS:Master 状态查询中的 Position 字段值
-
• GET_MASTER_PUBLIC_KEY:获取 Master 的公钥,解决身份认证问题
启动 Slave 并查看状态
若状态输出中 Slave_IO_Running 与 Slave_SQL_Running 同为 Yes 则说明主从复制正常运行,如果出现异常建议查看 Last_Error 字段来进行排查

停止与重置 Master 设置(备用)
测试
进入 Master 创建名为 test 的 Database 并在其中创建 user 表
插入测试数据
进入 Slave 查看数据是否同步

到此为止我们对主从复制的基本配置已经完成,如果想了解更多主从复制的配置参数或优化过程,请关注系列后续文章
原文始发于微信公众号(Transistor):MySQL-主从复制(一)部署
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/286513.html