【实战篇】Docker安装MySQL集群

上次我们讲了 Linux安装Mysql主从集群(图文解说详细版) 那么这次我们来讲一下如何使用Docker安装Mysql主从集群,相信你看到这篇文章肯定知道docker是什么了吧,我们在这里就不再赘述,而且相信你已经把docker安装好了,如果你还没有安装好,可以参考这两篇文章:

Windows安装Docker(图文解说详细版)

Linux安装Docker(图文解说详细版)

两个环境安装好之后的操作基本是一样的,那么本文就拿Windows作为载体进行一个环境的搭建。

MySQL主从集群是一种[数据库架构模式],由一个主数据库(Master)和多个从数据库(Slave)组成。在主从集群中,主数据库负责处理写操作(如插入、更新、删除),而从数据库则用于读操作。

我们这次搭建3个容器,一个是容器作为主节点,两个容器作为从节点,因为我们是在docker上面搭建,所以映射到我们本地的ip都是一样的,但是端口是不一样的,所以我们这次就定义这样的架构:(192.168.20.16 是博主的本地的地址,具体ip请各位根据自己本地的来)

ip 端口 角色
192.168.20.16 13306
192.168.20.16 13307
192.168.20.16 13308

搭建master节点

准备好环境之后我们直接执行下面的语句,这条语句是将本地的 13306端口映射到mysql容器里面的3306(mysql默认的端口),并且把容器里面两个重要的文件夹挂载到Windows服务器中,一个是mysql读取默认配置文件的地方,一个是mysq存储数据的地方,这样我们重启容器的时候数据就不会丢失了,会直接存在我们Windows机器的 C:\docker\mysql\master\data文件夹里面

bash 复制代码
docker run -d -p 13306:3306 -v C:\docker\mysql\master\conf:/etc/mysql/conf.d -v C:\docker\mysql\master\data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql-master mysql:8.0.29

打开cmd命令直接执行即可,如果你需要改挂载的目录,可以直接改为你的目录即可,但是有个注意的地方就是Windows机器使用盘符 C:加反斜杠 \ 而linux则是斜杠:\ 直接在bash命令行输入即可:

如果是第一次拉 mysql:8.0.29这个镜像,则需要下载,作者这里因为下载过一次了就是截图这样的,如果不报错的话,我们输入以下命令

bash 复制代码
docker ps

就可以看到一个名叫 mysql-master的容器正在运行了

mysql服务都会读取一个 /etc/mysql/conf.d 文件夹里面叫做my.cnf的文件,所以我们需要在三个容器中都去配置这个文件,因为我们前面已经把容器里面 /etc/mysql/conf.d的文件夹挂载到我们的Windows主机下面的 C:\docker\mysql\master\conf 文件夹里面了,所以我们直接在该文件夹下面创建一个my.cnf文件,这样在我们的容器里面也会有,mysql容器启动的时候就会读取这个文件了。

ini 复制代码
[mysqld]
# 服务器唯一id,默认值1
server-id=1
# 设置日志格式,默认值ROW
binlog_format=STATEMENT

mysql主节点搭建好之后,我们就需要准备给从节点读取binlog日志的账号和密码了,如果你不熟悉binlog文件的原理可以参考博主之前写的一篇文章:

我不小心把生产的数据改错了!同事帮我用MySQL的BinLog挽回了罚款

sql 复制代码
-- 创建slave用户
CREATE USER 'slave'@'%';
-- 设置密码
ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
-- 查询主服务器状态(binlog)的当前状态
SHOW MASTER STATUS;

这个 binlog.000003和这个 1333我们要记住,后面要用

搭建从节点1

而搭建从节点的命令和主节点差不多,但是要注意的是映射到主机的端口变为了 13307,挂载到主机的文件为 C:\docker\mysql\slave1,这里如果没有先建这个文件夹也是没有关系,执行这个命令之后,docker会自动创建该文件夹

bash 复制代码
docker run -d -p 13307:3306 -v C:\docker\mysql\slave1\conf:/etc/mysql/conf.d -v C:\docker\mysql\slave1\data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql-slave1 mysql:8.0.29

在我们的cmd命令行执行,如果返回一串字符串那就说明我们的从节点1的容器已经跑起来了:

这里也要重复上面的动作:创建my.cnf文件,在该文件夹下面创建一个my.cnf文件,但是他的内容如下(注意这里的server-id要和主机区分开,否则后面读取binlog的时候会失败):

ini 复制代码
[mysqld]
# 服务器唯一id,默认值1
server-id=2
# 设置日志格式,默认值ROW
binlog_format=STATEMENT

我们改变默认密码校验方式,这样做的目的是为了防止在Navicat,以及java应用等服务端中连不上密码,因为Navicat的校验模式和命令行的校验模式可能有区别。前面的主节点和后面的从节点2都要执行这个操作。

sql 复制代码
#进入容器:
docker exec -it mysql-slave1 env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

这里我们需要查看本机的ip信息,用作后面告诉从库主库的ip和其他的信息在哪,不能写 127.0.0.1,亲测不会生效 Slave_IO_Running的状态一直为 Connecting而且会报错: Last_IO_Error: error connecting to master 'slave@127.0.0.1:13306' - retry-time: 60 retries: 4 message: Can't connect to MySQL server on '127.0.0.1:13306' (111)

CHANGE MASTER TO 命令是用于配置从库(Slave)如何连接到主库(Master)并同步数据的关键操作,我们把主机的地址,分给从库的账号密码,主机mysql的端口,binlog日志的名称和当前位置在从库执行

sql 复制代码
CHANGE MASTER TO MASTER_HOST='192.168.20.16', 
MASTER_USER='slave',MASTER_PASSWORD='123456', MASTER_PORT=13306,
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1333; 

配置完成之后我们执行下面的命令:

sql 复制代码
START SLAVE;
-- 查看状态
SHOW SLAVE STATUS\G

如果出现 Slave_IO_Running 和 Slave_SQL_Running 参数都是YES 则说明成功了,如果不是请看下面的情况(就和作者上方图一样),遇到的问题:

server-id 不一致问题

解决方法:前面我们明明配置了my.cnf文件,但是这里还是报错说我们的从节点和主节点的 server-id是一样的,原因是我们在挂载C盘文件,修改my.cnf文件的时候赋予的权限太高了,其实在连接到mysql命令行的时候它就已经提示了:

bash 复制代码
World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.

my.cnf 的权限是 777(全局可读写),MySQL 出于安全考虑会忽略此类配置文件。所以我们只需要在Windows上修改一下对应的文件权限即可

修改了之后我们再查看我们的 my.cnf文件就变为这样了:

之后再重启我们的从节点:再次执行 SHOW SLAVE STATUS\G命令之后就可以看到状态已经都是成功了

bash 复制代码
docker restart mysql-slave1

搭建从节点2

整体步骤和搭建从节点1 差不多,我们只需要保证my.cnf文件里面的 server-id不一样即可

bash 复制代码
docker run -d -p 13308:3306 -v C:\docker\mysql\slave2\conf:/etc/mysql/conf.d -v C:\docker\mysql\slave2\data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql-slave2 mysql:8.0.29
sql 复制代码
[mysqld]
# 服务器唯一id,默认值1
server-id=3
# 设置日志格式,默认值ROW
binlog_format=STATEMENT

至此,我们在Windows上面使用docker搭建mysql主从集群已经完成了。

使用客户端连接三个节点

我们用Navicat来测试一下三个节点是否可以连接成功:

可以看到三个节点都连接成功了,这个时候我们可以在主节点创建数据看看是否能同步到从节点去:

数据库成功:

表成功:

数据不成功:

数据库和表成功,数据不成功问题

问题:这个时候我们首先想到的是不是binlog读取的时候出现了问题,于是博主去查看从节点的状态:

跟着日志去查看表的错误日志:

sql 复制代码
SELECT * FROM performance_schema.replication_applier_status_by_worker\G

错误日志显示:

bash 复制代码
Worker 1 failed executing transaction 'ANONYMOUS' at master log binlog.000004, end_log_pos 1629; Error executing row event: 'Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.'

OHHHHHHHH!找到原因了:主库和从库的 binlog_format 设置不一致 所以前面从库出现的 server-id 不一致问题,我们主库的 my.cnf权限问题就好了,之后重启,再次查看主节点的状态:

再次手动修改两个从节点的信息就好了:

再次验证试试就可以看到数据是一样的了:OHHHHHHHHHHH!!!

可能有些网有和博主一样好奇:我在从节点里面修改数据会怎么样?答案可能大家都猜到了,只会在当前从节点生效,其他节点数据都不会变动,所以我们这个架构只适合主节点作为写入或者读取节点,而从节点则只能作为读取节点使用了。

相关推荐
学Java的bb2 小时前
后端Web实战-MySQL数据库
数据库·mysql
卸任2 小时前
Docker打包并部署Next.js
前端·docker·next.js
农民也会写代码3 小时前
dedecms修改描述description限制字数长度的方法
mysql·php·cms·dedecms
头发还在的女程序员3 小时前
ThinkPHP+Mysql 灵活用工小程序-技术深度解析与实践指南
数据库·mysql·小程序
昌sit!4 小时前
k8s基本概念
云原生·容器·kubernetes
斯普信专业组4 小时前
Kubernetes部署apisix的理论与最佳实践(四)
云原生·容器·kubernetes
^_^ 纵歌5 小时前
如何把ubuntu 22.04下安装的mysql 8 的 数据目录迁移到另一个磁盘目录
mysql·ubuntu·adb
苦逼IT运维5 小时前
Jenkins + SonarQube 从原理到实战三:SonarQube 打通 Windows AD(LDAP)认证与踩坑记录
运维·服务器·windows·docker·云计算·jenkins·devops