使用docker-compose部署MySQL三主六从半同步集群(MMM架构)

本文详细介绍了如何使用docker-compose在三个节点上部署MySQL的三主六从半同步集群。首先,讲解了安装docker和docker-compose的两种方法,接着逐个部署master1、master2、master3节点,配置主从同步,并确保所有节点正确配置。然后,部署了slave1、slave2、slave3节点,配置了从节点的主从同步。最后,校验了集群的同步状态,并探讨了主从复制可能遇到的问题以及高可用架构MMM。
摘要由CSDN通过智能技术生成

🔊博主介绍

🌟我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文专业写手、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五公里、🚀徒步爬过衡山、🔥有过三个月减肥20斤的经历、是个喜欢躺平的狠人。

📕拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、Spring MVC、SpringCould、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RockerMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。

📙有过从0到1的项目高并发项目开发与管理经验,对JVM调优、MySQL调优、Redis调优 、ElasticSearch调优、消息中间件调优、系统架构调优都有着比较全面的实战经验。

📘有过云端搭建服务器环境,自动化部署CI/CD,弹性伸缩扩容服务器(最高200台),了解过秒级部署(阿里云的ACK和华为云的云容器引擎CCE)流程,能独立开发和部署整个后端服务,有过分库分表的实战经验。

🎥经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧,与清华大学出版社签下了四本书籍的合约,并将陆续在明年出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!


🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。

💡在这个美好的时刻,本人不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

🥤本文内容

CSDN

部署MySQL三主六从半同步集群

一主二从同步集群规划

master节点:ip地址:192.168.80.101 mysql端口:33061
slave1节点:ip地址:192.168.80.102 mysql端口:33062
slave2节点:ip地址:192.168.80.103 mysql端口:33063
服务器登录的用户名密码都是root用户admin密码
master节点的mysql登录账户是root用户masterroot密码
slave1节点和slave2节点的mysql登录账户是root用户slaveroot密码

sudo useradd -r -s /sbin/nologin -d /var/lib/mysql mysql
sudo usermod -d /var/lib/mysql mysql
sudo chown -R mysql:mysql /var/lib/mysql  
sudo chmod -R 755 /var/lib/mysql
grep mysql /etc/passwd
sudo usermod -d /var/lib/mysql mysql
sudo setenforce 0

需要安装docker和docker-compose

命令形式安装
安装docker
# 更新软件包
sudo yum update -y
# 安装必要依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加软件源信息
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新 yum 缓存
sudo yum makecache fast
# 安装 Docker
sudo yum install docker-ce docker-ce-cli containerd.io
# 启动 Docker 后台服务
sudo systemctl start docker
# 新建 daemon.json 文件
sudo vim /etc/docker/daemon.json
# 将下面的配置复制进去,然后执行 service docker restart即可:
{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
# 如果想要用阿里云的docker镜像源,可看这个网址 https://cr.console.aliyun.com/cn-qingdao/mirrors
# 安装好后使用如下命令查看安装的版本,如果正常输出说明安装成功
docker version
安装docker-compose
# 下载docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 授权
sudo chmod +x /usr/local/bin/docker-compose
# 安装好后使用如下命令查看安装版本,如果正常输出说明安装成功
docker-compose version
宝塔面板形式安装

执行Centos安装脚本,命令如下:

yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec

官网地址:https://www.bt.cn/new/download.html

下载完成之后,执行以下命令查看宝塔面板,命令如下:

bt

查看面板地址,命令如下:

14

修改登录面板的密码,命令如下:

5

登录之后需要绑定一个账号,如果绑定不上则执行以下命令:

curl -k -sSO http://101.37.149.22:5880/new/auto_node.sh && bash auto_node.sh

输出结果如下:

[root@mhamanager app1]# curl -k -sSO http://101.37.149.22:5880/new/auto_node.sh && bash auto_node.sh
 ______     _________            _______         _        ____  _____   ________    _____     
|_   _ \   |  _   _  |          |_   __ \       / \      |_   \|_   _| |_   __  |  |_   _|    
  | |_) |  |_/ | | \_|  ______    | |__) |     / _ \       |   \ | |     | |_ \_|    | |      
  |  __'.      | |     |______|   |  ___/     / ___ \      | |\ \| |     |  _| _     | |   _  
 _| |__) |    _| |_              _| |_      _/ /   \ \_   _| |_\   |_   _| |__/ |   _| |__/ | 
|_______/    |_____|            |_____|    |____| |____| |_____|\____| |________|  |________| 
                                                                                               
自动修复节点中... 
开始测试节点...请勿中断程序... 
hosts指定节点: 103.212.48.148
域名解析节点:  103.212.48.148
节点连接测试正常,修复已完成! 请登录面板查看是否正常

其他异常查看官方论坛,地址:https://www.bt.cn/bbs/thread-87257-1-1.html

登录之后在左侧找到docker点击安装即可。

需要注意的是,宝塔面板的防火墙都是开机自启动的,需要注意防火墙端口。

部署node1节点的master1

docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir /opt/software/mysqlcluster/master1
cd /opt/software/mysqlcluster/master1
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node1_master1  # 指定容器名称为mysql_node1_master1
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33061:3306"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node1master1root  # 设置root用户的密码  
    volumes:  # 定义数据卷
      - /var/lib/mysql:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode1master1root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir /opt/software/mysqlcluster/master1/conf
vi /opt/software/mysqlcluster/master1/conf/my.cnf
my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1010  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3306  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
log-bin = mysql-bin # 启用二进制日志  
log-bin-trust-function-creators = 1  # 允许二进制日志中记录函数创建的事件
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
log_bin_trust_function_creators=1  # 允许二进制日志中记录函数创建的事件
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = rpl_semi_sync_master.so   # 配置半同步复制
rpl_semi_sync_master_enabled = 1  # 开启半同步复制
rpl_semi_sync_master_timeout = 5000 # 配置主从同步超时时间(毫秒)
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时
授权启动
sudo chmod 644 /opt/software/mysqlcluster/master1/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/master1/conf/my.cnf mysql_node1_master1:/etc/mysql/my.cnf

重启容器

docker restart mysql_node1_master1

进入主节点容器,命令如下:

docker exec -it mysql_node1_master1 bash

登录mysql,命令如下:

mysql -u root -pnode1master1root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装semisync_master模块,通过扩展库来安装半同步复制模块,需要指定扩展库的文件名,命令如下:

install plugin rpl_semi_sync_master soname 'semisync_master.so';

查看系统全局参数,命令如下:

show global variables like 'rpl_semi%';

输出结果如下:

mysql> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

rpl_semi_sync_master_timeout就是半同步复制时等待应答的最长等待时间,默认是10秒,可以根据情况自行调整。rpl_semi_sync_master_wait_point其实表示一种半同步复制的方式。半同步复制有两种方式,一种是我们现在看到的这种默认的AFTER_SYNC方式。这种方式下,主库把日志写入binlog,并且复制给从库,然后开始等待从库的响应。从库返回成功后,主库再提交事务,接着给客户端返回一个成功响应。而另一种方式是叫做AFTER_COMMIT方式。他不是默认的。这种方式,在主库写入binlog后,等待binlog复制到从库,主库就提交自己的本地事务,再等待从库返回给自己一个成功响应,然后主库再给客户端返回响应。

打开半同步复制的开关,命令如下:

set global rpl_semi_sync_master_enabled=ON;

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node1master1root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node1master1root';
FLUSH PRIVILEGES;

查看master节点状态

show master status;

输出结果:

mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000003 |      196 |              |                  | 7410e8b2-e12b-11ee-9499-0242ac160002:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql> 

重启master节点的mysql服务,命令如下:

docker restart mysql_node1_master1

部署node2节点的master2

docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir /opt/software/mysqlcluster/master2
cd /opt/software/mysqlcluster/master2
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node2_master2  # 指定容器名称为mysql_node2_master2
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33062:3307"  # 将容器的3306端口映射到主机的33064端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node2master2root  # 设置root用户的密码  
    volumes:  # 定义数据卷
      - /var/lib/mysql:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode2master2root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
sudo chmod -R 755 /var/lib/mysql/
mkdir /opt/software/mysqlcluster/master2/conf
vi /opt/software/mysqlcluster/master2/conf/my.cnf
my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1020  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3307  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
log-bin = mysql-bin # 启用二进制日志  
log-bin-trust-function-creators = 1  # 允许二进制日志中记录函数创建的事件
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
log_bin_trust_function_creators=1  # 允许二进制日志中记录函数创建的事件
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = rpl_semi_sync_master.so   # 配置半同步复制
rpl_semi_sync_master_enabled = 1  # 开启半同步复制
rpl_semi_sync_master_timeout = 5000 # 配置主从同步超时时间(毫秒)
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时
授权启动
sudo chmod 644 /opt/software/mysqlcluster/master2/conf/my.cnf
sudo chmod 644 /var/lib/mysql

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/master2/conf/my.cnf mysql_node2_master2:/etc/mysql/my.cnf

重启容器

docker restart mysql_node2_master2

进入主节点容器,命令如下:

docker exec -it mysql_node2_master2 bash

登录mysql,命令如下:

mysql -u root -pnode2master2root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装semisync_master模块,通过扩展库来安装半同步复制模块,需要指定扩展库的文件名,命令如下:

install plugin rpl_semi_sync_master soname 'semisync_master.so';

查看系统全局参数,命令如下:

show global variables like 'rpl_semi%';

输出结果如下:

mysql> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

rpl_semi_sync_master_timeout就是半同步复制时等待应答的最长等待时间,默认是10秒,可以根据情况自行调整。rpl_semi_sync_master_wait_point其实表示一种半同步复制的方式。半同步复制有两种方式,一种是我们现在看到的这种默认的AFTER_SYNC方式。这种方式下,主库把日志写入binlog,并且复制给从库,然后开始等待从库的响应。从库返回成功后,主库再提交事务,接着给客户端返回一个成功响应。而另一种方式是叫做AFTER_COMMIT方式。他不是默认的。这种方式,在主库写入binlog后,等待binlog复制到从库,主库就提交自己的本地事务,再等待从库返回给自己一个成功响应,然后主库再给客户端返回响应。

打开半同步复制的开关,命令如下:

set global rpl_semi_sync_master_enabled=ON;

授权,命令如下:

SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node2master2root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node2master2root';
FLUSH PRIVILEGES;
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';

查看master节点状态

show master status;

输出结果:

mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000003 |      196 |              |                  | 0b986205-e1b3-11ee-adae-0242ac170002:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql>

部署node3节点的部署master3

docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir /opt/software/mysqlcluster/master3
cd /opt/software/mysqlcluster/master3
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node3_master3  # 指定容器名称为mysql_node3_master3
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33063:3308"  # 将容器的3306端口映射到主机的33064端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node3master3root  # 设置root用户的密码  
    volumes:  # 定义数据卷
      - /var/lib/mysql3:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode3master3root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir /opt/software/mysqlcluster/master3/conf
vi /opt/software/mysqlcluster/master3/conf/my.cnf
my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1030  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3308  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
log-bin = mysql-bin # 启用二进制日志  
log-bin-trust-function-creators = 1  # 允许二进制日志中记录函数创建的事件
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
log_bin_trust_function_creators=1  # 允许二进制日志中记录函数创建的事件
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = rpl_semi_sync_master.so   # 配置半同步复制
rpl_semi_sync_master_enabled = 1  # 开启半同步复制
rpl_semi_sync_master_timeout = 5000 # 配置主从同步超时时间(毫秒)
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时
授权启动
sudo chmod 644 /opt/software/mysqlcluster/master3/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/master3/conf/my.cnf mysql_node3_master3:/etc/mysql/my.cnf

重启容器

docker restart mysql_node3_master3

进入主节点容器,命令如下:

docker exec -it mysql_node3_master3 bash

登录mysql,命令如下:

mysql -u root -pnode3master3root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装semisync_master模块,通过扩展库来安装半同步复制模块,需要指定扩展库的文件名,命令如下:

install plugin rpl_semi_sync_master soname 'semisync_master.so';

查看系统全局参数,命令如下:

show global variables like 'rpl_semi%';

输出结果如下:

mysql> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

rpl_semi_sync_master_timeout就是半同步复制时等待应答的最长等待时间,默认是10秒,可以根据情况自行调整。rpl_semi_sync_master_wait_point其实表示一种半同步复制的方式。半同步复制有两种方式,一种是我们现在看到的这种默认的AFTER_SYNC方式。这种方式下,主库把日志写入binlog,并且复制给从库,然后开始等待从库的响应。从库返回成功后,主库再提交事务,接着给客户端返回一个成功响应。而另一种方式是叫做AFTER_COMMIT方式。他不是默认的。这种方式,在主库写入binlog后,等待binlog复制到从库,主库就提交自己的本地事务,再等待从库返回给自己一个成功响应,然后主库再给客户端返回响应。

打开半同步复制的开关,命令如下:

set global rpl_semi_sync_master_enabled=ON;

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node3master3root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node3master3root';
FLUSH PRIVILEGES;

查看master节点状态

show master status;

输出结果:

mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000005 |      196 |              |                  | 2f0d2880-e12d-11ee-9b42-0242ac1b0002:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql> 

配置三个主节点互为主从,主从同步配置

在master1上配置master3为主节点
CHANGE MASTER TO
MASTER_HOST='192.168.80.103',
MASTER_PORT=33063,
MASTER_USER='root',
MASTER_PASSWORD='node3master3root',
MASTER_LOG_FILE='mysql-bin.000005',
MASTER_LOG_POS=196;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.103
                  Master_User: root
                  Master_Port: 33063
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000005
          Read_Master_Log_Pos: 196
               Relay_Log_File: 2c79ab730c50-relay-bin.000007
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000005
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 196
              Relay_Log_Space: 708
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1030
                  Master_UUID: 2f0d2880-e12d-11ee-9b42-0242ac1b0002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 7410e8b2-e12b-11ee-9499-0242ac160002:1-3
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

在master2上配置master1为主节点
CHANGE MASTER TO
MASTER_HOST='192.168.80.101',
MASTER_PORT=33061,
MASTER_USER='root',
MASTER_PASSWORD='node1master1root',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=196;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.101
                  Master_User: root
                  Master_Port: 33061
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 196
               Relay_Log_File: 1535e4aba6d5-relay-bin.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 196
              Relay_Log_Space: 540
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1010
                  Master_UUID: 7410e8b2-e12b-11ee-9499-0242ac160002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 0b986205-e1b3-11ee-adae-0242ac170002:1-3
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

在master3上配置master2为主节点
CHANGE MASTER TO
MASTER_HOST='192.168.80.102',
MASTER_PORT=33062,
MASTER_USER='root',
MASTER_PASSWORD='node2master2root',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=196;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.102
                  Master_User: root
                  Master_Port: 33062
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 196
               Relay_Log_File: 5393cf023082-relay-bin.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 196
              Relay_Log_Space: 540
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1020
                  Master_UUID: 0b986205-e1b3-11ee-adae-0242ac170002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 2f0d2880-e12d-11ee-9b42-0242ac1b0002:1-3
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

三主三从,互为主从节点。master1作为master2的主节点,master2作为master3的主节点,master3作为master1的主节点,接下来,就是将从节点进行扩容。

部署node1节点的slave1

docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir /var/lib/mysqlslave
ls -ld /var/lib/mysqlslave/
chmod 755 /var/lib/mysqlslave/
ls -ld /var/lib/mysqlslave/
mkdir /opt/software/mysqlcluster/slave1
cd /opt/software/mysqlcluster/slave1
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node1_slave1  # 指定容器名称为mysql_node2_slave1
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33064:3309"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node1slave1root  # 设置root用户的密码  
    volumes:  # 定义数据卷
      - /var/lib/mysqlslave:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode1slave1root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir /opt/software/mysqlcluster/slave1/conf
vi /opt/software/mysqlcluster/slave1/conf/my.cnf
my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1011  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3309  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
relay_log = relay-log  # 开启中继日志
relay_log_index = slave-relay-bin.index  # 设置中继日志索引的文件名
read_only = ON # 启用只读属性
relay_log_purge = 0 # 是否自动清空不再需要中继日志
log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = semisync_slave.so  # 半同步复制
rpl_semi_sync_slave_enabled = 1 # 开启半同步复制
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时
授权启动
sudo chmod 644 /opt/software/mysqlcluster/slave1/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/slave1/conf/my.cnf mysql_node1_slave1:/etc/mysql/my.cnf

重启容器

docker restart mysql_node1_slave1

进入主节点容器,命令如下:

docker exec -it mysql_node1_slave1 bash

登录mysql,命令如下:

mysql -u root -pnode1slave1root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装smeisync_slave模块,命令如下:

install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
set global rpl_semi_sync_slave_enabled = on;

查看效果,命令如下:

show global variables like 'rpl_semi%';

输出结果:

mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

rpl_semi_sync_slave_enabled为ON表示设置成功。

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node1slave1root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node1slave1root';
FLUSH PRIVILEGES;

重启从节点1的mysql服务,命令如下:

docker restart mysql_node1_slave1

部署node2节点的slave2

docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir /var/lib/mysqlslave
ls -ld /var/lib/mysqlslave/
chmod 755 /var/lib/mysqlslave/
ls -ld /var/lib/mysqlslave/
mkdir /opt/software/mysqlcluster/slave2
cd /opt/software/mysqlcluster/slave2
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node2_slave2  # 指定容器名称为mysql_node3_slave2
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33065:3310"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node2slave2root  # 设置root用户的密码  
    volumes:  # 定义数据卷
      - /var/lib/mysqlslave:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode2slave2root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir /opt/software/mysqlcluster/slave2/conf
vi /opt/software/mysqlcluster/slave2/conf/my.cnf
my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1021  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3310  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
relay_log = relay-log  # 开启中继日志
relay_log_index = slave-relay-bin.index  # 设置中继日志索引的文件名
read_only = ON # 启用只读属性
relay_log_purge = 0 # 是否自动清空不再需要中继日志
log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = semisync_slave.so  # 半同步复制
rpl_semi_sync_slave_enabled = 1 # 开启半同步复制
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时
授权启动
sudo chmod 644 /opt/software/mysqlcluster/slave2/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/slave2/conf/my.cnf mysql_node2_slave2:/etc/mysql/my.cnf

重启容器

docker restart mysql_node2_slave2

进入主节点容器,命令如下:

docker exec -it mysql_node2_slave2 bash

登录mysql,命令如下:

mysql -u root -pnode2slave2root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装smeisync_slave模块,命令如下:

install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
set global rpl_semi_sync_slave_enabled = on;

查看效果,命令如下:

show global variables like 'rpl_semi%';

输出结果:

mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

rpl_semi_sync_slave_enabled为ON表示设置成功。

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node2slave2root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node2slave2root';
FLUSH PRIVILEGES;

重启从节点2的mysql服务,命令如下:

docker restart mysql_node2_slave2

部署node3节点的slave3

docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir /var/lib/mysqlslave
ls -ld /var/lib/mysqlslave/
chmod 755 /var/lib/mysqlslave/
ls -ld /var/lib/mysqlslave/
mkdir /opt/software/mysqlcluster/slave3
cd /opt/software/mysqlcluster/slave3
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node3_slave3  # 指定容器名称为mysql_node3_slave3  
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33066:3311"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node3slave3root  # 设置root用户的密码  
    volumes:  # 定义数据卷
      - /var/lib/mysqlslave:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode3slave3root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir /opt/software/mysqlcluster/slave3/conf
vi /opt/software/mysqlcluster/slave3/conf/my.cnf
my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1031  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3311  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
relay_log = relay-log  # 开启中继日志
relay_log_index = slave-relay-bin.index  # 设置中继日志索引的文件名
read_only = ON # 启用只读属性
relay_log_purge = 0 # 是否自动清空不再需要中继日志
log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = semisync_slave.so  # 半同步复制
rpl_semi_sync_slave_enabled = 1 # 开启半同步复制
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时
授权启动
sudo chmod 644 /opt/software/mysqlcluster/slave3/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/slave3/conf/my.cnf mysql_node3_slave3:/etc/mysql/my.cnf

重启容器

docker restart mysql_node3_slave3

进入主节点容器,命令如下:

docker exec -it mysql_node3_slave3 bash

登录mysql,命令如下:

mysql -u root -pnode3slave3root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装smeisync_slave模块,命令如下:

install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
set global rpl_semi_sync_slave_enabled = on;

查看效果,命令如下:

show global variables like 'rpl_semi%';

输出结果:

mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

rpl_semi_sync_slave_enabled为ON表示设置成功。

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node3slave3root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node3slave3root';
FLUSH PRIVILEGES;

重启从节点2的mysql服务,命令如下:

docker restart mysql_node3_slave3

配置三个从节点的主从同步配置

前文提到master1作为master2的主节点,master2作为master3的主节点,master3作为master1的主节点。

node1node2node3
master1master2master3
slave1slave2slave3

三台机器部署了六个mysql,且三个主节点也都互为主从,接下来就是规划,每个主节点下,除了已经配置好的从节点,再新增一个从节点。

主节点对应的从节点,规划如下:

master1master2master3
master2master3master1
slave3slave1slave2
在slave3上配置master1为主节点
CHANGE MASTER TO
MASTER_HOST='192.168.80.101',
MASTER_PORT=33061,
MASTER_USER='root',
MASTER_PASSWORD='node1master1root',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=196;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

[root@node3 slave3]# docker restart mysql_node3_slave3
mysql_node3_slave3
[root@node3 slave3]# docker exec -it mysql_node3_slave3 bash
root@670b9cf24960:/# mysql -u root -pnode3slave3root
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.20 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CHANGE MASTER TO
    -> MASTER_HOST='192.168.80.101',
    -> MASTER_PORT=33061,
    -> MASTER_USER='root',
    -> MASTER_PASSWORD='node1master1root',
    -> MASTER_LOG_FILE='mysql-bin.000003',
    -> MASTER_LOG_POS=196;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    47
Current database: *** NONE ***

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.101
                  Master_User: root
                  Master_Port: 33061
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 196
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 196
              Relay_Log_Space: 527
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1010
                  Master_UUID: 7410e8b2-e12b-11ee-9499-0242ac160002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: fc16cfd5-e1b8-11ee-8a7c-0242ac1c0002:1-8
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 
在slave1上配置master2为主节点
CHANGE MASTER TO
MASTER_HOST='192.168.80.102',
MASTER_PORT=33062,
MASTER_USER='root',
MASTER_PASSWORD='node2master2root',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=196;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

[root@node1 slave1]# docker exec -it mysql_node1_slave1 bash
root@561ba1f60c85:/# mysql -u root -pnode1slave1root
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.20 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CHANGE MASTER TO
    -> MASTER_HOST='192.168.80.102',
    -> MASTER_PORT=33062,
    -> MASTER_USER='root',
    -> MASTER_PASSWORD='node2master2root',
    -> MASTER_LOG_FILE='mysql-bin.000003',
    -> MASTER_LOG_POS=196;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    62
Current database: *** NONE ***

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.102
                  Master_User: root
                  Master_Port: 33062
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 196
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 196
              Relay_Log_Space: 527
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1020
                  Master_UUID: 0b986205-e1b3-11ee-adae-0242ac170002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 00d129c2-e1b8-11ee-9b95-0242ac190002:1-3
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

在slave2上配置master3为主节点
CHANGE MASTER TO
MASTER_HOST='192.168.80.103',
MASTER_PORT=33063,
MASTER_USER='root',
MASTER_PASSWORD='node3master3root',
MASTER_LOG_FILE='mysql-bin.000005',
MASTER_LOG_POS=196;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

[root@node2 slave2]# docker exec -it mysql_node2_slave2 bash
root@7afff255d566:/# mysql -u root -pnode2slave2root
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.20 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CHANGE MASTER TO
    -> MASTER_HOST='192.168.80.103',
    -> MASTER_PORT=33063,
    -> MASTER_USER='root',
    -> MASTER_PASSWORD='node3master3root',
    -> MASTER_LOG_FILE='mysql-bin.000005',
    -> MASTER_LOG_POS=196;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    56
Current database: *** NONE ***

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.103
                  Master_User: root
                  Master_Port: 33063
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000005
          Read_Master_Log_Pos: 196
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000005
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 196
              Relay_Log_Space: 527
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1030
                  Master_UUID: 2f0d2880-e12d-11ee-9b42-0242ac1b0002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: af672dc4-e1b8-11ee-8705-0242ac180002:1-3
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

如果想继续扩展从节点,重复上述操作即可。

校验三主六从集群同步是否正常

在所有master节点查看数据库,命令如下:

show databases;

输出结果如下:

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

在其中一个master节点上创建一个test数据库,命令如下:

create database test;

去其他所有节点上查看数据库是否同步过去,同步过去说明真个集群处于同步状态。

主从复制容易遇错中断

START SLAVE; 命令用于启动 MySQL 的主从复制功能。如果配置的时候主从,但是在同步过程中出现异常错误,则会打断主从同步,并且需要重新手动重新配置,而这个过程需要每隔一段时间监听,使用SHOW SLAVE STATUS\G; 命令来查看从服务器的复制状态,这可能就需要通过手写程序或者使用某云产品来实现。

高可用架构MMM

MySQL的Master-Master复制管理器——MMM(Master-Master Replication Manager for MySQL)乃是一款灵活实用、精心打造的脚本程序,它基于Perl语言开发,旨在对MySQL的复制功能进行全面可靠的监控及故障转移处理,以及高效管理MySQL的Master-Master复制配置(保证在同一时间段内仅有一个节点处在可写状态)。

围绕MMM的核心技术,主要有三个关键组件:mmm_mond、mmm_agentd以及mmm_controller。其中,mmm_mond的任务是做为监控进程,全权负责所有有关监控工作的决策制定与实际操作;mmm_agentd作为运行在每一个MySQL服务器之上的代理进程,负责完成监控环境中的探测工作,以及实时执行简单的远程服务设置;而mmm_controller则是为我们带来便捷管理mmm_mond进程所需的一组简洁明了的指令。

为了令MMM的各个环节得以顺利运作,特意设计了mysql-mmm的监管端系统,它能够提供丰富多样的虚拟IP(VIP)资源,其中包含一个处于可写状态的VIP,以及若干个处于可读状态的VIP。通过这套严密的监管机制,能够将IP与可用的MySQL服务器相链接,从而充分发挥它们的作用。当任一MySQL服务器意外崩溃时,我们便可利用监管端的强大功能,迅速调整VIP的绑定方向,使得其他健康的MySQL服务器能够继续承担服务重任。后面将规划虚拟IP地址(VIP):192.168.80.211为写,192.168.80.212和192.168.80.213为读。

在整个监管流程中,为了确保安全稳定的运营环境,我们还需在MySQL数据库当中新增相关的授权用户,以适应当前的需求。具体来说,我们需要创建两个重要的授权用户,分别为mmm_monitor和mmm_agent,此外,如若您需要使用MMM的备份工具,还需额外增加一位mmm_tools用户。

需要注意的是监控节点需要单独部署,这个和MHA有点类似,如果大家想知道怎么搭建的,可以去看我之前的文章:使用Docker-Compose部署MySQL一主二从同步高可用MHA集群

数据库同步需要的用户:

  • monitor user:mmm监控用于对mysql服务器进程健康检查,权限:REPLICATION CLIENT
  • agent user:mmm代理用来更改只读模式,复制的主服务器等,权限:SUPER, REPLICATION CLIENT, PROCESS
  • replication user:用于复制,权限:REPLICATION SLAVE

CentOS默认没有mysql-mmm软件包,官方推荐使用epel的网络源,都安装epel:

rpm -ivh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

monitor节点安装

yum -y install mysql-mmm-monitor

其他db节点安装

yum -y install mysql-mmm-agent

在db节点授权monitor访问

GRANT REPLICATION SLAVE ON *.* TO 'replication'@'192.168.0.%' IDENTIFIED BY 'replication';
GRANT REPLICATIONCLIENT ON *.* TO 'mmm_monitor'@'192.168.0.%' IDENTIFIED BY 'monitor';                   
GRANT SUPER,REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'192.168.0.%' IDENTIFIED BY'agent';
flush privileges;

修改mmm_common.conf文件(所有机器相同)

[root@monitor ~]# vi /etc/mysql-mmm/mmm_common.conf
active_master_role      writer
<host default>
    cluster_interface       eth0
    pid_path               /var/run/mysql-mmm/mmm_agentd.pid
    bin_path                /usr/libexec/mysql-mmm/
    replication_user        replication
    replication_password    replication
    agent_user              mmm_agent
    agent_password          agent
</host>
<host db1>
    ip     192.168.80.101
    mode   master
    peer   db2
</host>
<host db2>
    ip     192.168.80.102
    mode   master
    peer   db1
</host>
<host db3>
    ip     192.168.80.103
    mode   slave
</host>
<role writer>
    hosts  db1, db2
    ips    192.168.80.211
    mode   exclusive    #只有一个host可以writer,一般写操作是这个模式
</role>
<role reader>
    hosts  db3, db4
    ips    192.168.80.212,192.168.80.213
    mode   balanced     #多个host可以reader,一般读操作是这个模式
</role>

修改db代理端mmm_agent.conf文件

vi /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1   #分别修改为本机的主机名,即db1、db2、db3和db4

修改管理端mmm_mon.conf文件

vi /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
    ip                  127.0.0.1
    pid_path            /var/run/mysql-mmm/mmm_mond.pid
    bin_path            /usr/libexec/mysql-mmm
    status_path         /var/lib/mysql-mmm/mmm_mond.status
    ping_ips            192.168.80.101,192.168.80.102,192.168.80.103
#真实数据库IP,来检测网络是否正常
    auto_set_online     10  #恢复后自动设置在线的时间
</monitor>
<host default>
    monitor_user        mmm_monitor
    monitor_password    monitor
</host>
debug 0

启动MySQL-MMM

db代理端启动

/etc/init.d/mysql-mmm-agent start
chkconfigmysql-mmm-agent on

monitor管理端启动

/etc/init.d/mysql-mmm-monitor start
chkconfigmysql-mmm-monitor on

查看集群状态

mmm_control show

MMM故障处理机制

MySQL-MMM 故障排除与恢复策略解析

  1. 整个系统中,提供读写服务的虚拟 IP 均由 Monitor 程序负责协调控制。倘若 Monitor 未按计划启动,则 DB 服务器将无法获得虚拟 IP 地址的分配权。然而,若已成功分配给某个服务器虚拟 IP 地址,即使 Monitor 程序逐渐退出且不再控制该虚拟 IP 地址,相关外部应用程序仍可继续正常访问该服务器(前提是网络环境未进行重启,保证虚拟 IP 地址尚未失效)。由此可见,较高的 Monitor 运行稳定性将有助于降低系统故障发生率。然而,当某个 DB 服务器出现故障导致停机,则 Monitor 程序确难以对其进行快速有效的故障转移管理。在此情况下,原有虚拟 IP 地址将继续保持不变,而故障服务器所对应的虚拟 IP 地址会变为不可用,致使外部应用程序无法继续访问失去服务能力的 DB 服务器。

  2. Agent 程序作为 Monitor 程序的下属组件,协助完成诸如写服务替换从库之类的操作。在 Monitor 进程超出负荷或退出运行后,Agent 进程将丧失协调功能,无法自行应对突发状况。

  3. Monitor 程序主要承担着对 MySQL 数据库以及服务器运行状况的实时监控责任,同时还需关注复制线程运行状况、数据同步延期现象等重要指标。此外,Monitor 程序还通过控制 Agent 程序实现对多种类型故障的及时处置。

  4. Monitor 程序以每数秒一次的频率对整个集群的 DB 服务器运行状态进行监测,一旦识别出某台日志服务器已经成功从故障状态恢复至正常运行状态,便会在指定时间内自动将其状态调整至 Online(默认为 60 秒,亦可根据实际需求予以调整)。

  5. Monitor 程序通常采用默认机制,即指导 MMM-Agent 程序将 writer /写入器/服务器 的 read_only /只读属性变更为 OFF,以便于数据同步过程的顺利开展。然而,为了精准把控各项数据操作权限,建议在所有服务器的 my.cnf 文件中添加 read_only =1 这一字段,交由 Monitor 程序统一调度控制 Writer 和 Read 功能。特别需要注意的是,root 账户及复制账户并不受 read_only 参数的限制,确保系统具有足够灵活性。
    CSDN

📢文章总结

对本篇文章进行总结:

🔔以上就是今天要讲的内容,阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。

以梦为马,不负韶华

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

🚀🎉希望各位读者大大多多支持用心写文章的博主,现在时代变了,🚀🎉 信息爆炸,酒香也怕巷子深🔥,博主真的需要大家的帮助才能在这片海洋中继续发光发热🎨,所以,🏃💨赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

📥博主目标

探寻内心世界,博主分享人生感悟与未来目标

  • 🍋程序开发这条路不能停,停下来容易被淘汰掉,吃不了自律的苦,就要受平庸的罪,持续的能力才能带来持续的自信。我本是一个很普通的程序员,放在人堆里,除了与生俱来的盛世美颜,就剩180的大高个了,就是我这样的一个人,默默写博文也有好多年了。
  • 📺有句老话说的好,牛逼之前都是傻逼式的坚持,希望自己可以通过大量的作品、时间的积累、个人魅力、运气、时机,可以打造属于自己的技术影响力。
  • 💥内心起伏不定,我时而激动,时而沉思。我希望自己能成为一个综合性人才,具备技术、业务和管理方面的精湛技能。我想成为产品架构路线的总设计师,团队的指挥者,技术团队的中流砥柱,企业战略和资本规划的实战专家。
  • 🎉这个目标的实现需要不懈的努力和持续的成长,但我必须努力追求。因为我知道,只有成为这样的人才,我才能在职业生涯中不断前进并为企业的发展带来真正的价值。在这个不断变化的时代,我们必须随时准备好迎接挑战,不断学习和探索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。

🔔有需要对自己进行综合性评估,进行职业方向规划,我可以让技术大牛帮你模拟面试、针对性的指导、传授面试技巧、简历优化、进行技术问题答疑等服务。

可访问:https://java_wxid.gitee.io/tojson/

开发人员简历优化、面试突击指导、技术问题解答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员廖志伟

赏我包辣条呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值