使用Docker-Compose部署MySQL一主二从同步高可用MHA集群

发布时间:2024年01月07日

🔊博主介绍

🌟我是廖志伟,一名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一主二从同步集群

一主二从同步集群规划

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

需要安装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点击安装即可。

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

部署Master节点的docker-compose.yaml文件

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

cd /opt
mkdir mysql
cd mysql
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_master  # 指定容器名称为mysql_master
    restart: unless-stopped  # 在容器退出时自动重新启动
    command:  # 容器启动时执行的命令
      - --server-id=1  # 设置MySQL服务器的ID为1,用于复制
      - --relay_log=relay-log # 开启中继日志
      - --binlog-ignore-db=mysql  # 忽略在binlog中记录的数据库,这里为mysql
      - --skip-name-resolve  # 禁用DNS解析
      - --innodb_flush_log_at_trx_commit=1  # 每个事务提交时将日志写入磁盘
      - --sync-binlog=1  # 立即将binlog写入磁盘
      - --innodb_flush_method=O_DIRECT  # 使用直接IO刷新InnoDB缓冲区
      - --log-bin=master-log   # 开启二进制日志
      - --log_bin-index=master-bin.index  # 指定binlog索引文件名
      - --max_connections=500  # 最大的并发连接数
      - --max_connect_errors=100  # 连接错误的最大次数
      - --character-set-server=utf8  # 设置服务器的字符集为UTF-8
      - --default-storage-engine=INNODB  # 设置默认存储引擎为InnoDB
      - --default_authentication_plugin=mysql_native_password  # 设置默认身份验证插件为mysql_native_password
      - --expire-logs-days=7  # 设置binlog日志自动删除的天数为7天
      - --binlog-ignore-db=information_schema  # 忽略在binlog中记录的数据库,这里为information_schema
      - --binlog-ignore-db=performance_schema  # 忽略在binlog中记录的数据库,这里为performance_schema
      - --binlog-ignore-db=sys  # 忽略在binlog中记录的数据库,这里为sys
      - --gtid_mode=on  # 开启全局事务标识
      - --enforce_gtid_consistency=on  # 强制全局事务标识的一致性
      - --binlog_format=mixed  # 二进制日志的格式为混合模式
      - --sync_binlog=1  # 立即将binlog写入磁盘
      - --default_storage_engine=InnoDB  # 默认的存储引擎是InnoDB
      - --performance_schema_max_table_instances=400  # 性能模式中最大的表实例数
      - --table_definition_cache=400  # 表定义缓存的大小
      - --skip-external-locking  # 跳过外部锁定
      - --max_allowed_packet=100G  # 数据包的最大大小
      - --table_open_cache=512  # 表缓存的大小
      - --sort_buffer_size=2M  # 排序缓冲区的大小
      - --net_buffer_length=4K  # 网络缓冲区的长度
      - --read_buffer_size=2M  # 读缓冲区的大小
      - --read_rnd_buffer_size=256K  # 随机读缓冲区的大小
      - --thread_cache_size=64  # 线程缓存的大小
      - --tmp_table_size=64M  # 临时表的大小
      - --lower_case_table_names=1  # 表名是否区分大小写,1表示不区分大小写
      - --sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES  # SQL模式
      - --explicit_defaults_for_timestamp=true  # 如果设置为true,则对于TIMESTAMP列,使用显式DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP定义
      - --skip-name-resolve  # 跳过DNS解析
      - --open_files_limit=65535  # 可打开文件的数量限制
      - --binlog_expire_logs_seconds=600000  # 当二进制日志文件超过指定秒数时,将被自动删除
      - --slow_query_log=1  # 启用慢查询日志
      - --long_query_time=3  # 超过指定秒数的查询将被认为是慢查询
      - --log_queries_not_using_indexes=on  # 记录未使用索引的查询
      - --innodb_buffer_pool_size=512M  # InnoDB缓冲池的大小
      - --innodb_log_file_size=256M  # InnoDB日志文件的大小
      - --innodb_log_buffer_size=64M  # InnoDB日志缓冲区的大小
      - --innodb_flush_log_at_trx_commit=1  # 每次事务提交时,是否将日志缓冲区的内容刷新到磁盘
      - --innodb_lock_wait_timeout=50  # InnoDB锁等待超时时间
      - --innodb_max_dirty_pages_pct=90  # InnoDB脏页的最大百分比
      - --innodb_read_io_threads=8  # InnoDB读线程的数量
      - --innodb_write_io_threads=8  # InnoDB写线程的数量
    ports:  # 定义容器和主机之间的端口映射
      - "33061:3306"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: masterroot  # 设置MySQL的root用户密码为masterroot
      TZ: "Asia/Shanghai" #解决时区问题
    volumes:  # 定义数据卷
      - /var/lib/mysql:/var/lib/mysql  # 将本地的master目录挂载到容器的/var/lib/mysql目录中

部署MySQL从节点1的docker-compose.yml的文件

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

cd /opt
mkdir mysql
cd mysql
vi docker-compose.yaml

文件内容,代码如下:

  version: '3'
  services:
    mysql_slave1:
      image: mysql:8.0.20
      container_name: mysql_slave1
      restart: unless-stopped
      command:
        - --server-id=2  # 设置MySQL服务器的唯一标识
        - --relay-log-index=slave-relay-bin.index  # 设置中继日志索引的文件名
        - --relay-log=relay-log  # 开启中继日志
        - --log-bin=master-log  # 开启二进制日志
        - --read_only=ON # 启用只读属性
        - --relay_log_purge=0 # 是否自动清空不再需要中继日志
        - --log-slave-updates=1  # 开启从服务器记录二进制日志更新的功能
        - --max_connections=200  # 设置最大连接数
        - --max_connect_errors=10  # 设置最大连接错误数
        - --character-set-server=utf8  # 设置服务器默认字符集为utf8
        - --default-storage-engine=INNODB  # 设置默认的存储引擎为InnoDB
        - --default_authentication_plugin=mysql_native_password  # 设置默认的身份验证插件为mysql_native_password
        - --log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
        - --binlog-ignore-db=information_schema  # 忽略复制的数据库
        - --binlog-ignore-db=performance_schema  # 忽略复制的数据库
        - --binlog-ignore-db=sys  # 忽略复制的数据库
        - --binlog-ignore-db=mysql  # 忽略复制的数据库
        - --skip-name-resolve  # 禁用主机名解析
        - --innodb_flush_log_at_trx_commit=1  # 每次事务提交时刷新日志缓冲区内容到磁盘
        - --sync-binlog=1  # 立即将binlog写入磁盘
        - --innodb_flush_method=O_DIRECT  # 设置InnoDB的日志刷新方式为直接刷新
        - --gtid_mode=on  # 开启全局事务标识
        - --enforce_gtid_consistency=on  # 强制全局事务标识的一致性
        - --binlog_format=mixed  # 设置二进制日志的格式为混合模式
        - --sync_binlog=1  # 立即将binlog写入磁盘
        - --default_storage_engine=InnoDB  # 设置默认的存储引擎为InnoDB
        - --performance_schema_max_table_instances=400  # 设置性能模式中最大的表实例数
        - --table_definition_cache=400  # 设置表定义缓存的大小
        - --skip-external-locking  # 跳过外部锁定
        - --max_allowed_packet=100G  # 设置数据包的最大大小
        - --table_open_cache=512  # 设置表缓存的大小
        - --sort_buffer_size=2M  # 设置排序缓冲区的大小
        - --net_buffer_length=4K  # 设置网络缓冲区的长度
        - --read_buffer_size=2M  # 设置读缓冲区的大小
        - --read_rnd_buffer_size=256K  # 设置随机读缓冲区的大小
        - --thread_cache_size=64  # 设置线程缓存的大小
        - --tmp_table_size=64M  # 设置临时表的大小
        - --lower_case_table_names=1  # 设置表名是否区分大小写,1表示不区分大小写
        - --sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES  # 设置SQL模式
        - --explicit_defaults_for_timestamp=true  # 如果设置为true,则对于TIMESTAMP列,使用显式DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP定义
        - --skip-name-resolve  # 跳过DNS解析
        - --open_files_limit=65535  # 设置可打开文件的数量限制
        - --binlog_expire_logs_seconds=600000  # 当二进制日志文件超过指定秒数时,将被自动删除
        - --slow_query_log=1  # 启用慢查询日志
        - --long_query_time=3  # 设置超过指定秒数的查询将被认为是慢查询
        - --log_queries_not_using_indexes=on  # 记录未使用索引的查询
        - --innodb_buffer_pool_size=512M  # 设置InnoDB缓冲池的大小
        - --innodb_log_file_size=256M  # 设置InnoDB日志文件的大小
        - --innodb_log_buffer_size=64M  # 设置InnoDB日志缓冲区的大小
        - --innodb_flush_log_at_trx_commit=1  # 每次事务提交时,是否将日志缓冲区的内容刷新到磁盘
        - --innodb_lock_wait_timeout=50  # 设置InnoDB锁等待超时时间
        - --innodb_max_dirty_pages_pct=90  # 设置InnoDB脏页的最大百分比
        - --innodb_read_io_threads=8  # 设置InnoDB读线程的数量
        - --innodb_write_io_threads=8  # 设置InnoDB写线程的数量
        - --master_info_repository=TABLE #指定存储主服务器信息的文件的类型
        - --relay_log_info_repository=FILE
      ports:
        - "33062:3306"  # 将容器的3306端口映射到主机的33062端口
      environment:
        MYSQL_ROOT_PASSWORD: slaveroot # root用户密码
        MYSQL_MASTER_HOST: 198.168.80.111 # 指定主服务器的地址
        MYSQL_MASTER_PORT: 33061 # 指定主服务器的端口
        MYSQL_MASTER_USER: root # 主服务器的root用户
        MYSQL_MASTER_PASSWORD: masterroot # 主服务器的root密码
        TZ: "Asia/Shanghai"  # 设置时区
      volumes:
        - /var/lib/mysql:/var/lib/mysql  # 将本地的slave1目录挂载到容器的/var/lib/mysql目录中

部署Slave2节点的docker-compose.yaml文件

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

cd /opt
mkdir mysql
cd mysql
vi docker-compose.yaml

文件内容,代码如下:

version: '3'
services:
  mysql_slave2:
    image: mysql:8.0.20
    container_name: mysql_slave2
    restart: unless-stopped
    command:
      - --server-id=3  # 设置MySQL服务器的唯一标识
      - --relay-log-index=slave-relay-bin.index  # 设置中继日志索引的文件名
      - --relay-log=relay-log  # 开启中继日志
      - --log-bin=master-log  # 开启二进制日志
      - --read_only=ON # 启用只读属性
      - --relay_log_purge=0 # 是否自动清空不再需要中继日志
      - --log-slave-updates=1  # 开启从服务器记录二进制日志更新的功能
      - --max_connections=200  # 设置最大连接数
      - --max_connect_errors=10  # 设置最大连接错误数
      - --character-set-server=utf8  # 设置服务器默认字符集为utf8
      - --default-storage-engine=INNODB  # 设置默认的存储引擎为InnoDB
      - --default_authentication_plugin=mysql_native_password  # 设置默认的身份验证插件为mysql_native_password
      - --log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
      - --binlog-ignore-db=information_schema  # 忽略复制的数据库
      - --binlog-ignore-db=performance_schema  # 忽略复制的数据库
      - --binlog-ignore-db=sys  # 忽略复制的数据库
      - --binlog-ignore-db=mysql  # 忽略复制的数据库
      - --skip-name-resolve  # 禁用主机名解析
      - --innodb_flush_log_at_trx_commit=1  # 每次事务提交时刷新日志缓冲区内容到磁盘
      - --sync-binlog=1  # 立即将binlog写入磁盘
      - --innodb_flush_method=O_DIRECT  # 设置InnoDB的日志刷新方式为直接刷新
      - --gtid_mode=on  # 开启全局事务标识
      - --enforce_gtid_consistency=on  # 强制全局事务标识的一致性
      - --binlog_format=mixed  # 设置二进制日志的格式为混合模式
      - --sync_binlog=1  # 立即将binlog写入磁盘
      - --default_storage_engine=InnoDB  # 设置默认的存储引擎为InnoDB
      - --performance_schema_max_table_instances=400  # 设置性能模式中最大的表实例数
      - --table_definition_cache=400  # 设置表定义缓存的大小
      - --skip-external-locking  # 跳过外部锁定
      - --max_allowed_packet=100G  # 设置数据包的最大大小
      - --table_open_cache=512  # 设置表缓存的大小
      - --sort_buffer_size=2M  # 设置排序缓冲区的大小
      - --net_buffer_length=4K  # 设置网络缓冲区的长度
      - --read_buffer_size=2M  # 设置读缓冲区的大小
      - --read_rnd_buffer_size=256K  # 设置随机读缓冲区的大小
      - --thread_cache_size=64  # 设置线程缓存的大小
      - --tmp_table_size=64M  # 设置临时表的大小
      - --lower_case_table_names=1  # 设置表名是否区分大小写,1表示不区分大小写
      - --sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES  # 设置SQL模式
      - --explicit_defaults_for_timestamp=true  # 如果设置为true,则对于TIMESTAMP列,使用显式DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP定义
      - --skip-name-resolve  # 跳过DNS解析
      - --open_files_limit=65535  # 设置可打开文件的数量限制
      - --binlog_expire_logs_seconds=600000  # 当二进制日志文件超过指定秒数时,将被自动删除
      - --slow_query_log=1  # 启用慢查询日志
      - --long_query_time=3  # 设置超过指定秒数的查询将被认为是慢查询
      - --log_queries_not_using_indexes=on  # 记录未使用索引的查询
      - --innodb_buffer_pool_size=512M  # 设置InnoDB缓冲池的大小
      - --innodb_log_file_size=256M  # 设置InnoDB日志文件的大小
      - --innodb_log_buffer_size=64M  # 设置InnoDB日志缓冲区的大小
      - --innodb_flush_log_at_trx_commit=1  # 每次事务提交时,是否将日志缓冲区的内容刷新到磁盘
      - --innodb_lock_wait_timeout=50  # 设置InnoDB锁等待超时时间
      - --innodb_max_dirty_pages_pct=90  # 设置InnoDB脏页的最大百分比
      - --innodb_read_io_threads=8  # 设置InnoDB读线程的数量
      - --innodb_write_io_threads=8  # 设置InnoDB写线程的数量
      - --master_info_repository=TABLE #指定存储主服务器信息的文件的类型
      - --relay_log_info_repository=FILE
    ports:
      - "33063:3306"  # 将容器的3306端口映射到主机的33062端口
    environment:
      MYSQL_ROOT_PASSWORD: slaveroot # root用户密码
      MYSQL_MASTER_HOST: 198.168.80.111 # 指定主服务器的地址
      MYSQL_MASTER_PORT: 33061 # 指定主服务器的端口
      MYSQL_MASTER_USER: root # 主服务器的root用户
      MYSQL_MASTER_PASSWORD: masterroot # 主服务器的root密码
      TZ: "Asia/Shanghai"  # 设置时区
    volumes:
      - /var/lib/mysql:/var/lib/mysql  # 将本地的slave1目录挂载到容器的/var/lib/mysql目录中

每个节点都执行启动运行

启动运行,命令如下:

docker-compose up -d

如果需要暂停容器并删除mysql文件,命令如下:

docker-compose down
rm -rf /var/lib/mysql

master节点,配置主从同步

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

docker exec -it mysql_master bash;

登录mysql,命令如下:

mysql -u root -pmasterroot

安装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 'masterroot';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'masterroot';
CREATE USER 'mhaadmin'@'192.168.%.%' IDENTIFIED BY 'mhapass';
GRANT ALL PRIVILEGES ON *.* TO 'mhaadmin'@'192.168.%.%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

查看主节点状态,命令如下:

SHOW MASTER STATUS;

输出结果如下:

mysql> SHOW MASTER STATUS;
+-------------------+----------+--------------+-------------------------------------------------+------------------------------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set                        |
+-------------------+----------+--------------+-------------------------------------------------+------------------------------------------+
| master-log.000004 |      381 |              | mysql,information_schema,performance_schema,sys | fc36c204-acfb-11ee-9fcd-0242ac120002:1-6 |
+-------------------+----------+--------------+-------------------------------------------------+------------------------------------------+
1 row in set (0.00 sec)

需要注意的是File和Position的值,在配置从节点时需要对应上。

slave节点1和2,配置主从同步

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

docker exec -it mysql_slave1 bash

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

docker exec -it mysql_slave2 bash

登录mysql,命令如下:

mysql -u root -pslaveroot

安装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 'slaveroot';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'slaveroot';
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;

配置主从同步,命令如下:

CHANGE MASTER TO
MASTER_HOST='192.168.80.111',
MASTER_PORT=33061,
MASTER_USER='root',
MASTER_PASSWORD='masterroot',
MASTER_LOG_FILE='master-log.000004',
MASTER_LOG_POS=381;

MASTER_HOST是master节点的ip地址,MASTER_PORT是master节点对外暴露的端口,MASTER_USER是master节点的root用户,MASTER_PASSWORD是root用户对应的密码,MASTER_LOG_FILE和MASTER_LOG_POS的值是在master节点登录mysql后执行SHOW MASTER STATUS;命令输出结果File和Position的值。

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

START SLAVE;
show slave status\G;

输出的结果如下:

mysql> show slave status\G;\
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.80.111
                  Master_User: root
                  Master_Port: 33061
                Connect_Retry: 60
              Master_Log_File: master-log.000004
          Read_Master_Log_Pos: 196
               Relay_Log_File: relay-log.000005
                Relay_Log_Pos: 373
        Relay_Master_Log_File: master-log.000004
             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: 1499
              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: 1
                  Master_UUID: fc36c204-acfb-11ee-9fcd-0242ac120002
             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: 01058c88-acfc-11ee-9104-0242ac120002:1-5
                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

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

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

docker restart mysql_slave1

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

docker restart mysql_slave2

如果上述步骤,有些操作还是不知道怎么做,这里提供我操作的一个步骤视频:

校验主从同步是否正常

在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;

去二个slave1和slave2节点上查看数据库是否同步过去。

节点互通无密码登录

在每个节点都执行以下命令,代码如下:

ssh-keygen -t rsa

按三次回车,然后推送到mhamanager节点上,代码如下:

ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.80.110

在mhamanager节点上查看authorized_keys文件,代码如下:

cd /root/.ssh
cat authorized_keys 

输出如下:
authorized_keys
在mhamanager节点上推送authorized_keys文件到master节点上,代码如下:

scp authorized_keys root@192.168.80.111:/root/.ssh/

在mhamanager节点上推送authorized_keys文件到slave1节点上,代码如下:

scp authorized_keys root@192.168.80.112:/root/.ssh/

在mhamanager节点上推送authorized_keys文件到slave2节点上,代码如下:

scp authorized_keys root@192.168.80.113:/root/.ssh/

安装配置MHA

下载安装

想要安装MHA,需要准备mha4mysql-node-0.56-0.el6.noarch.rpm和mha4mysql-manager-0.56-0.el6.noarch.rpm安装包,这里提供下载地址:
链接:https://pan.baidu.com/s/17j_cJ5ukdp95RnfGWEM8gQ?pwd=2024
提取码:2024
–来自百度网盘超级会员V1的分享

在mhamanager节点将二个安装包上传,然后执行以下命令安装,代码如下:

yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
yum install -y mha4mysql-manager-0.56-0.el6.noarch.rpm

在master节点、slave1节点、slave2节点将一个安装包上传,然后执行以下命令安装,代码如下:

yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm

配置mha.cnf文件

编辑mhamanager节点的/etc/mha_master/mha.cnf配置文件,代码如下:

vi /etc/mha_master/mha.cnf

mha.cnf文件内容,代码如下:

[server default]
# 设置manager的日志
manager_log=/var/log/mha/manager/manager.log
# 设置manager的工作目录
manager_workdir=/var/log/mha/manager/workdir
# 设置master保存binlog的位置
master_binlog_dir=/var/lib/mysql
# 每个远程主机的工作目录在何处
remote_workdir=/opt/mha/mha_master/work
# mha管理用户
user=mhaadmin
# mha密码
password=mhapass
# 基于ssh的密钥认证
ssh_user=root
# slave的复制密码
repl_password=123456
# slave的复制用户
repl_user=slave
# 检查节点状态的间隔时间,默认为1秒
ping_interval=1
[server1]
# 服务器节点1
# 主机ip地址
hostname=192.168.80.111
# mysql对外暴露端口
port=33061
# 设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库
candidate_master=1
# 默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
check_repl_delay=0
[server2]
# 服务器节点2
# 主机ip地址
hostname=192.168.80.112
# mysql对外暴露端口
port=33062
# 设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库
candidate_master=1
# 默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
check_repl_delay=0
[server3]
# 服务器节点3
# 主机ip地址
hostname=192.168.80.113
# mysql对外暴露端口
port=33063
# 设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库
candidate_master=1
# 默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
check_repl_delay=0

开始校验

测试节点之间是否互通,命令如下:

masterha_check_ssh -conf=/etc/mha_master/mha.cnf

输出结果如下:

[root@mhamanager mysql]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf
Fri Jan  5 14:46:35 2024 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Jan  5 14:46:35 2024 - [info] Reading application default configuration from /etc/mha_master/mha.cnf..
Fri Jan  5 14:46:35 2024 - [info] Reading server configuration from /etc/mha_master/mha.cnf..
Fri Jan  5 14:46:35 2024 - [info] Starting SSH connection tests..
Fri Jan  5 14:47:16 2024 - [debug] 
Fri Jan  5 14:46:35 2024 - [debug]  Connecting via SSH from root@192.168.80.111(192.168.80.111:22) to root@192.168.80.112(192.168.80.112:22)..
Fri Jan  5 14:46:55 2024 - [debug]   ok.
Fri Jan  5 14:46:55 2024 - [debug]  Connecting via SSH from root@192.168.80.111(192.168.80.111:22) to root@192.168.80.113(192.168.80.113:22)..
Fri Jan  5 14:47:15 2024 - [debug]   ok.
Fri Jan  5 14:47:16 2024 - [debug] 
Fri Jan  5 14:46:35 2024 - [debug]  Connecting via SSH from root@192.168.80.112(192.168.80.112:22) to root@192.168.80.111(192.168.80.111:22)..
Fri Jan  5 14:46:55 2024 - [debug]   ok.
Fri Jan  5 14:46:55 2024 - [debug]  Connecting via SSH from root@192.168.80.112(192.168.80.112:22) to root@192.168.80.113(192.168.80.113:22)..
Fri Jan  5 14:47:16 2024 - [debug]   ok.
Fri Jan  5 14:47:17 2024 - [debug] 
Fri Jan  5 14:46:36 2024 - [debug]  Connecting via SSH from root@192.168.80.113(192.168.80.113:22) to root@192.168.80.111(192.168.80.111:22)..
Fri Jan  5 14:46:56 2024 - [debug]   ok.
Fri Jan  5 14:46:56 2024 - [debug]  Connecting via SSH from root@192.168.80.113(192.168.80.113:22) to root@192.168.80.112(192.168.80.112:22)..
Fri Jan  5 14:47:16 2024 - [debug]   ok.
Fri Jan  5 14:47:17 2024 - [info] All SSH connection tests passed successfully.

测试主从复制是否正常,命令如下:

masterha_check_repl -conf=/etc/mha_master/mha.cnf

输出结果如下:

[root@mhamanager mysql]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
Fri Jan  5 15:12:10 2024 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Jan  5 15:12:10 2024 - [info] Reading application default configuration from /etc/mha_master/mha.cnf..
Fri Jan  5 15:12:10 2024 - [info] Reading server configuration from /etc/mha_master/mha.cnf..
Fri Jan  5 15:12:10 2024 - [info] MHA::MasterMonitor version 0.56.
Fri Jan  5 15:12:11 2024 - [info] GTID failover mode = 1
Fri Jan  5 15:12:11 2024 - [info] Dead Servers:
Fri Jan  5 15:12:11 2024 - [info] Alive Servers:
Fri Jan  5 15:12:11 2024 - [info]   192.168.80.111(192.168.80.111:33061)
Fri Jan  5 15:12:11 2024 - [info]   192.168.80.112(192.168.80.112:33062)
Fri Jan  5 15:12:11 2024 - [info]   192.168.80.113(192.168.80.113:33063)
Fri Jan  5 15:12:11 2024 - [info] Alive Slaves:
Fri Jan  5 15:12:11 2024 - [info]   192.168.80.112(192.168.80.112:33062)  Version=8.0.20 (oldest major version between slaves) log-bin:enabled
Fri Jan  5 15:12:11 2024 - [info]     GTID ON
Fri Jan  5 15:12:11 2024 - [info]     Replicating from 192.168.80.111(192.168.80.111:33061)
Fri Jan  5 15:12:11 2024 - [info]     Primary candidate for the new Master (candidate_master is set)
Fri Jan  5 15:12:11 2024 - [info]   192.168.80.113(192.168.80.113:33063)  Version=8.0.20 (oldest major version between slaves) log-bin:enabled
Fri Jan  5 15:12:11 2024 - [info]     GTID ON
Fri Jan  5 15:12:11 2024 - [info]     Replicating from 192.168.80.111(192.168.80.111:33061)
Fri Jan  5 15:12:11 2024 - [info] Current Alive Master: 192.168.80.111(192.168.80.111:33061)
Fri Jan  5 15:12:11 2024 - [info] Checking slave configurations..
Fri Jan  5 15:12:11 2024 - [info] Checking replication filtering settings..
Fri Jan  5 15:12:11 2024 - [info]  binlog_do_db= , binlog_ignore_db= information_schema,mysql,performance_schema,sys
Fri Jan  5 15:12:11 2024 - [info]  Replication filtering check ok.
Fri Jan  5 15:12:11 2024 - [info] GTID (with auto-pos) is supported. Skipping all SSH and Node package checking.
Fri Jan  5 15:12:11 2024 - [info] Checking SSH publickey authentication settings on the current master..
Fri Jan  5 15:12:16 2024 - [warning] HealthCheck: Got timeout on checking SSH connection to 192.168.80.111! at /usr/share/perl5/vendor_perl/MHA/HealthCheck.pm line 342.
Fri Jan  5 15:12:16 2024 - [info] 
192.168.80.111(192.168.80.111:33061) (current master)
 +--192.168.80.112(192.168.80.112:33062)
 +--192.168.80.113(192.168.80.113:33063)

Fri Jan  5 15:12:16 2024 - [info] Checking replication health on 192.168.80.112..
Fri Jan  5 15:12:16 2024 - [info]  ok.
Fri Jan  5 15:12:16 2024 - [info] Checking replication health on 192.168.80.113..
Fri Jan  5 15:12:16 2024 - [info]  ok.
Fri Jan  5 15:12:16 2024 - [info] Checking master_ip_failover_script status:
Fri Jan  5 15:12:16 2024 - [info]   /etc/mha/scripts/master_ip_failover    #设置自动failover时候的切换脚本 --command=status --ssh_user=root --orig_master_host=192.168.80.111 --orig_master_ip=192.168.80.111 --orig_master_port=33061 


IN SCRIPT TEST====/sbin/ifconfig eth1:1 down==/sbin/ifconfig eth1:1 192.168.80.110/24===

Checking the Status of the script.. OK 
Fri Jan  5 15:12:16 2024 - [info]  OK.
Fri Jan  5 15:12:16 2024 - [warning] shutdown_script is not defined.
Fri Jan  5 15:12:16 2024 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

启动mha服务,命令如下:

nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &

查看日志,命令如下:

tail -200 /etc/mha_master/manager.log

输出结果如下:

[root@mhamanager mysql]# tail -200 /etc/mha_master/manager.log
nohup: ignoring input
Fri Jan  5 15:30:23 2024 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Jan  5 15:30:23 2024 - [info] Reading application default configuration from /etc/mha_master/mha.cnf..
Fri Jan  5 15:30:23 2024 - [info] Reading server configuration from /etc/mha_master/mha.cnf..

查看mha主节点是否正常,命令如下:

masterha_check_status -conf=/etc/mha_master/mha.cnf

输出结果如下:

[root@mhamanager mysql]# masterha_check_status -conf=/etc/mha_master/mha.cnf
mha (pid:5236) is running(0:PING_OK), master:192.168.80.111

上面的信息中“mha (pid:5236) is running(0:PING_OK)”表示MHA服务运行OK,否则,会显示为类似“mha is stopped(1:NOT_RUNNING).”停止 MHA,则需要使用 stop,命令如下:

masterha_stop -conf=/etc/mha_master/mha.cnf

在 master 节点关闭 mysql服务,模拟主节点数据崩溃,命令如下:

docker stop mysql_master

再次查看mhamanger节点日志,命令如下:

tail -200 /etc/mha_master/manager.log

输出结果如下:

[root@manager ~]# tail -200 /etc/mha_master/manager.log
……
Sunday Jan 7 11:17:19 2024 - [info] Master failover to
192.168.80.112(192.168.80.112:33062) completed successfully.

表示 manager 检测到192.168.80.111节点故障, 而后自动执行故障转移, 将192.168.80.112提升为主节点。

故障转移完成后, manager将会自动停止, 此时使用masterha_check_status 命令检测将会遇到错误提示,输出结果如下:

[root@mhamanager mysql]# masterha_check_status -conf=/etc/mha_master/mha.cnf
mha is stopped(2:NOT_RUNNING).

故障备份恢复

如果原来的主数据库出现故障,需要设置一个新的 MySQL 节点,并将其配置为新的从节点。如果新节点是新增加的,需要将其IP地址配置为原来主节点的IP地址。如果IP地址不同,还需要修改mha.cnf文件中对应的IP地址。然后再次启动管理器,并检查其状态。

备份命令如下:

mysqldump --all-database > /backup/mysql-backup-`date +%F-%T`-all.sql

以刚刚关闭的那台主节点作为新添加的机器,来进行数据库的恢复。原本的 slave1 已经成为了新的主机器,对其进行完全备份,然后把备份的数据发送到新添加的机器上,输出结果如下:

[root@slave1 ~]# mkdir /backup
[root@slave1 ~]# mysqldump --all-database > /backup/mysql-backup-`date +%F-%T`-all.sql
[root@slave1 ~]# scp /backup/mysql-backup-2024-01-07-12\:57\:09-all.sql root@192.168.80.112:/backup

在新加的机器上进行数据恢复,这里还使用原来那台主节点(因为把容器关停了,经过MHA选举,slave1节点现在是主节点,master节点哪怕重新启动也还是作为从节点加入到集群中),输出结果如下:

[root@master ~]# mysql < mysql-backup-2024-01-07-12\:57\:09-all.sql

备份完成后,还是和前面的从节点操作一样,登录mysql,配置主从关系,然后执行show slave status\G;命令查看主节点状态。

最后再去mhamanager节点上,观察新节点提供后,执行检查操作是否正常。

总结一下,就是在生产环境中, 当你的主节点挂了后, 一定要在从节点上做一个备份, 拿着备份文件把主节点手动提升为从节点, 并指明从哪一个日志文件的位置开始复制。每一次自动完成转换后, 每一次的(replication health )检测不ok始终都是启动不了必须手动修复主节点, 除非你改配置文件。手动修复主节点提升为从节点后, 再次运行检测命令。再次运行起来就恢复成功了。
CSDN

📢文章总结

对本篇文章进行总结: 如果觉得我给的操作步骤太费事,也可以别家的:https://gitee.com/IceHL/mysql-mha/blob/master/README.md

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

以梦为马,不负韶华

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

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

📥博主目标

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

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

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

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

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

文章来源:https://blog.csdn.net/Java_programmer_liao/article/details/135437991
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。