mysql 双主+keepalived模式搭建

两台 机器 构建双主 模式  主要 是 双主 数据一致性 

192.168.0.176  (主)

192.168.0.179    (主)

两台 宿主机器 都需要创建文件夹 用于挂载

mkdir mysql

cd mysql 

mkdir config 

chmod -R +777 /home/admin1/yyx/mysql/

 

 

两台机器 同时 拉取镜像 docker pull mysql

 

192.168.0.176 机器 容器启动

docker run -d --name m1 -p 3306:3306  \
-e MYSQL_ROOT_PASSWORD=123456 -e TZ="Asia/Shanghai"  \
-v /home/admin1/yyx/mysql/config:/etc/mysql/conf.d mysql  \
--authentication_policy=mysql_native_password 

 启动后进入 容器内部

docker exec -it m1 mysql -uroot -p123456

 

需要注意的是每台上要重置一下server_uuid,否则后面的主从复制会出错,直接删掉auto.cnf让MySQL自动生成即可

rm -rf  /var/lib/mysql/auto.cnf;

查看 偏移量
show master status;

执行完毕后登陆MySQL创建同步用户
DROP USER 'repl'@'%' ;
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
flush privileges;

 

查看 插件 show plugins;

 

 可以看到插件不包含 

rpl_semi_sync_source_enabled=1
rpl_semi_sync_replica_enabled=1
两个插件
此时退出 mysql
exit
在宿主机上 config 文件夹 创建 my.cnf文件

 

文件内容如下
[mysqld]
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
log-bin=mysql-bin-master
server_id=1
log_replica_updates=1
plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled=1
rpl_semi_sync_replica_enabled=1

[client]
default-character-set=utf8mb4

server_id=1 这个配置 每台机器不一样的

og-slave-updates=1:这个参数需要注意下,互为主从的时候两台都需要写入自己从对方取到的数据到binlog里面

plugin-load=“rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so” rrpl_semi_sync_source_enabled=1
rpl_semi_sync_replica_enabled=1
主从半同步都需开启,因为是互为主

 

 

 

 

 

重启 容器 m1 

 进入 容器内部 

docker exec -it m1 mysql -uroot -p123456
查看插件
show plugins;

 

 发现个插件 已经安装上了

192.168.0.179  机器

其实步骤 与上面 一样的 

不同的是my.cnf 文件内容

[mysqld]
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
log-bin=mysql-bin-master
server_id=2
log_replica_updates=1
plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled=1
rpl_semi_sync_replica_enabled=1

[client]
default-character-set=utf8mb4

  server_id=2 这个配置不能一样的

 

 

 

===================================================分割=====================
下面来配置 互为 主从复制的 配置
192.168.0.176  (主)
进入 容器 中
查看状态 记录偏移量

 

 

将 上面的 两个值记录下下来
执行 下面
STOP SLAVE;
RESET SLAVE;

CHANGE MASTER TO
MASTER_HOST='192.168.0.179',
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_LOG_FILE='mysql-bin-master.000001',
MASTER_LOG_POS=157;

START SLAVE;

SHOW SLAVE STATUS\G;

 上面 文件的 内容 就是 176 为179的 从节点 日志文件 是   MASTER_LOG_FILE='mysql-bin-master.000001', 位置是 MASTER_LOG_POS=157;

 

查看 是否 挂载成功   SHOW SLAVE STATUS\G;

 

 

再分别看下半同步是否开启

show variables like 'rpl_semi_sync_source_enabled';
show variables like 'rpl_semi_sync_replica_enabled';

 

接下来 是 192.168.0.179 节点

步骤与上面一样

配置文件 有所不同

STOP SLAVE;
RESET SLAVE;

CHANGE MASTER TO
MASTER_HOST='192.168.0.176',
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_LOG_FILE='mysql-bin-master.000001',
MASTER_LOG_POS=157;

START SLAVE;

SHOW SLAVE STATUS\G;

上面 文件的 内容 就是 179 为176的 从节点 日志文件 是   MASTER_LOG_FILE='mysql-bin-master.000001', 位置是 MASTER_LOG_POS=157;

查看 是否 挂载成功   SHOW SLAVE STATUS\G;

 

show variables like 'rpl_semi_sync_source_enabled';
show variables like 'rpl_semi_sync_replica_enabled';

 

可以看到 两台 机器全部开启了

最后在自行测试下载Master主机上面写数据Master备机能否同步,反过来再测试下


在某一台宕机后另外一台第一次插入会等10s左右,说明半同步复制也是开启的,第二次插入就会退化了异步复制了,并且在宕机机器恢复后会自动同步缺失的数据。


show variables like 'server_id';
 

然后退出 exit

================================================分割==================================

接下来 是配置 keepalived

 

安装

注意Keepalived就安装在Docker运行的宿主机上面,安装在docker里面IP无法绑定(亲测)

两台 机器都需要安装

yum install -y keepalived

 

我们 需要 在 docker 容器外 连接 docker 容器 中的 mysql 所以 需要 安装 mysql 客户端

安装MySQL客户端

主要目的 是 需要 在容器外访问 容器内的 mysql

wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
rpm -ivh mysql80-community-release-el7-5.noarch.rpm
yum install mysql-community-client 
安装的时候 报错了

 意思就是 已经 安装了 community-release-el7-10 我们安装的 (community-release-el7-5 版本低 好吧 把我们安装的 删除掉 删除命令 yum remove community-release-el7-5.noarch 因为安装报错7-5没安装上 所以不用删除

此时修改 我这里 为了记录  修改 下载命令 为 7-10版本

wget https://dev.mysql.com/get/mysql80-community-release-el7-10.noarch.rpm
rpm -ivh mysql80-community-release-el7-10.noarch.rpm
yum install mysql-community-client

好吧 安装 以上的 命令 再 安装 一次 (其实我这里 安装 了7-10 不用再安装了 为了记录 再弄一次)

 

 

 

执行 这个 命令 再次报错  yum install mysql-community-client

 参考解决 麒麟操作系统安装MySQL报错信息_阿干tkl的博客-CSDN博客

解决 : 

执行

wget http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/compat-openssl10-1.0.2o-4.el8.x86_64.rpm


执行 

rpm -ivh compat-openssl10-1.0.2o-4.el8.x86_64.rpm --nodeps

再次执行 安装 命令  yum install mysql-community-client 又报错了

 解决 

参考 nothing provides libcrypto.so.10()(64bit) needed by mysql-community-server-8_mob649e815b1a71的技术博客_51CTO博客

安装 sudo yum install epel-release

 安装 sudo yum install openssl10

 再次 安装 yum install mysql-community-client

终于可以 了 哈哈 好艰难

 尝试登录 看看

mysql -uroot -p123456 -h192.168.0.179

 登录 成功了 哈哈哈 

我的 192.168.0.176 也出现同样的错误 了 解决方式 与上面一样 这样 就开始部署 keepalived

 

keepalived原始配置文件

! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

virtual_server 192.168.200.100 443 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.201.100 443 {
        weight 1
        SSL_GET {
            url {
              path /
              digest ff20ad2481f97b1754ef3e12ecd3a9cc
            }
            url {
              path /mrtg/
              digest 9b3a0c85a887a256d6939da88aabd8cd
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

virtual_server 10.10.10.2 1358 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    sorry_server 192.168.200.200 1358

    real_server 192.168.200.2 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.200.3 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

virtual_server 10.10.10.3 1358 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.200.4 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.200.5 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}
View Code
  • router_id:标识,两台需不一样
  • state MASTER:表明这台是Master角色
  • priority:优先级,MASTER角色比BACKUP高!
  • virtual_router_id:虚拟路由编号,两台需要一致
  • 192.168.0.100 dev ens33 label ens33:vip:这就是我们配置的VIP:192.168.0.100
  • script /etc/keepalived/chk_mysql.sh:MySQL的检测脚本,定时去检测MySQL进程是否挂掉,如果挂掉,在脚本里面重启之,定时通过interval配置,上面配置的是2s检测一次
  • notify /etc/keepalived/kpad_notify.sh:当Keepalived状态发生变化时,会调用该脚本,这也是我们实现Slave(m3)自动挂载Master的关键!!

当Keepalived从BACKUP提升为MASTER时,那么VIP就会漂移到自己身上,这个时候我们只需要将Slave挂载在自己身上即可

Slave的自动挂载Master,我们只需要实现上面这句话的逻辑即可!

好了 不啰嗦了 刚才 已经 安装了 keepalived了 下面修改 配置文件了

cd /etc/keepalived/

 

192.168.0.176 上的 keepalived.conf 配置文件修改为

 我的 网卡 是 en33

keepalived.conf 内容

! Configuration File for keepalived

global_defs {
    router_id HA-M1
}

vrrp_script chk_mysql {
    script /etc/keepalived/chk_mysql.sh
    interval 3
    fall 3
    rise 2
}

vrrp_instance VI_MYSQL {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    virtual_ipaddress {
        192.168.0.100 dev ens33 label ens33:vip
    }
    
    track_script {
        chk_mysql
    }
}

 

 

chk_mysql.sh 内容

#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.0.176
MYSQL_USER=root
MYSQL_PASSWORD=123456
CHECK_TIME=3
  
#mysql  is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
  
MYSQL_OK=1
  
function check_mysql_helth (){
    $MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
    if [ $? = 0 ] ;then
    MYSQL_OK=1
    else
    MYSQL_OK=0
    fi
    return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME -= 1"
    check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
    CHECK_TIME=0
    exit 0
fi
if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]
then
    systemctl stop keepalived
    exit 1
fi
sleep 1
done

  

 

176 机器配置完毕

测试一下  执行   systemctl start keepalived

又报错了

 

 解决 参考 keepalived启动报错 Configuration file '/etc/keepalived/keepalived.conf' is not a regular non-executable_九品神元师的博客-CSDN博客

执行  chmod 644 /etc/keepalived/keepalived.conf

再次 执行启动   systemctl start keepalived

 

176机器终于成功了 艰难坎坷 

==================================配置179

开始配置179 

yum install -y keepalived

cd /etc/keepalived/

 配置 这俩文件

179 是 备份机器

keepalived.conf 内容

! Configuration File for keepalived

global_defs {
    router_id HA-M2
    enable_script_security
    script_user admin1
}

vrrp_script chk_mysql {
    script  "/etc/keepalived/chk_mysql.sh"
    interval 3
    fall 3
    rise 2
}

vrrp_instance VI_MYSQL {
    state BACKUP
    interface ens33
    virtual_router_id 100
    nopreempt
    priority 50
    advert_int 1
    mcast_src_ip 192.168.0.179  
        
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    virtual_ipaddress {
        192.168.0.100 dev ens33 label ens33:vip
    }
        
    track_script {
        chk_mysql
    }
}

  priority 50 优先级 低于 176的

 

 

 

chk_mysql.sh 内容
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.0.179
MYSQL_USER=root
MYSQL_PASSWORD=123456
CHECK_TIME=3
  
#mysql  is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
  
MYSQL_OK=1
  
function check_mysql_helth (){
    $MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
    if [ $? = 0 ] ;then
    MYSQL_OK=1
    else
    MYSQL_OK=0
    fi
    return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME -= 1"
    check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
    CHECK_TIME=0
    exit 0
fi
if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]
then
    systemctl stop keepalived
    exit 1
fi
sleep 1
done

 

 加权限 

chmod -R  644 /etc/keepalived/

chmod 644 /etc/keepalived/chk_mysql.sh

chmod 644 /etc/keepalived/keepalived.conf

 

然后 启动

systemctl start keepalived

查看状态

 systemctl status keepalived.service

 报错 健康检查脚本忘了保存了妹的

加上再次启动  systemctl start keepalived

查看状态

 systemctl status keepalived.service

 终于成功了 

到此 176 179 mysql 客户端 和 keepalived 全部部署成功 接下来测试

杀掉Master主机上的Keepalived和mysql:

  • VIP会漂移到Master备机上,ifconfig能看到VIP信息
  • 通过/tmp/keepalived-state和日志kpad_notify.log观察Keepalived是从BACKUP状态转换为了MASTER状态
  • Master备机上做写操作,第一次写会发生半同步等待(10s左右),第二次写会退化成异步复制

启动Master上的Keepalived和mysql:

  • ifconfig看下VIP会漂移回来,并且Master备机上的VIP会消失
  • 刚才在Master备机上写入的数据同步过来了
  • Keepalived的状态是从FAULT转变为BACKUP,最后变成MASTER

新开一个窗口 176窗口 

-----执行 命令 tail -f /var/log/messages

妹的 用 navicat  开三个 mysql 连接测试一下 就行  麻烦

三个连接 100 是keepalived 的 虚拟ip 的连接 成功 ,176 179 分别是 docker 容器中的 mysql 连接

 测试 我在 100 中新建数据库 和表 176,179 查看 是否也新建了 

 

可以看到 数据库 test1 表 testtable 三台创建没有问题, 176,179 自动同步数据 

100上 新增行数据

 三台 同步 数据成功

我在 100 上删除数据

 测试 没有问题 

接下来测试 我把176 docker mysql 容器停止 看看 keepalived 是否 能 漂移

 

 navicat 已经连接不上 176了 

100 可以 连接  100 其实 连接的 179 说明keepalived 漂移到179 了 哈哈哈

 查看 179 很正常 

 此时 我将 176 机器的 docker 启动 mysql 容器 查看 数据是否 能 同步

176  哈哈 数据 同步成功 

 到此 为止 mysql 双主 +keepalived 部署和测试成功了 

 

报错 解决 参考 

如何启用:script_security? ·问题 #901 ·阿卡森/阿卡森 (github.com)

keepalived常见错误汇总 - Granding - 博客园 (cnblogs.com)

关闭selinux的命令是什么 - 问答 - 亿速云 (yisu.com)

keepalived + nginx 主备与负载均衡 之 Error exec-ing command '/etc/keepalived/nginx_check.sh'_/etc/keepalived/check_nginx.sh exited with status _傲然君的博客-CSDN博客

 这种警告 是没事的

 

 两台机器 的状态 可以 看到 很健康
 
总结 keepalived.conf 文件权限 需要 设置 644 不能设置 777 否则 启动失败
 
 WARNING - script '/etc/keepalived/chk_mysql.sh' is not executable for uid:gid 1000:1000 - disabling. 这个 1000:1000 的警告没事
 

posted on 2023-09-11 10:52  是水饺不是水饺  阅读(510)  评论(0)    收藏  举报

导航