一、环境介绍
二、MySQL安装
在两台服务器上都安装mysql
1、拉取镜像
docker pull mysql:8.0.27
2、创建挂载目录
mkdir -p /data/mysql/
3、运行容器
- 主节点
docker run \--restart=always \--name master_mysql -p 3306:3306 \-e MYSQL_ROOT_PASSWORD=123456 -d \-v /data/mysql/:/var/lib/mysql mysql:8.0.27 \--lower_case_table_names=1 \--default_authentication_plugin=mysql_native_password
- 从节点
docker run \--restart=always \--name slave_mysql -p 3306:3306 \-e MYSQL_ROOT_PASSWORD=123456 -d \-v /data/mysql/:/var/lib/mysql mysql:8.0.27 \--lower_case_table_names=1 \--default_authentication_plugin=mysql_native_password
MYSQL_ROOT_PASSWORD :设置的mysql root用户的密码
lower_case_table_names: 是否大小写敏感,1表示不区分大小写
三、配置MySQL主从同步
两个数据库如果有数据,先把两个数据库的数据导成一样的
1、同步方式
replication
GTID
双向同步
2、设置master 同步到slave
master开启binlog
#将mysql容器中的my.cnf配置文件拷贝到宿主机来修改
docker cp master_mysql:/etc/mysql/my.cnf ./
在my.cnf 中添加
[mysqld]
log-bin=mysql-bin # 开启二进制日志
server-id=1 # 设置server-id。master和每一个slave的server-id都不能一样,用于唯一标识节点
sync_binlog=1
#主从同步跳过错误
slave-skip-errors=1062,1053,1146,1007,1008,1050,1051
#从库的中继日志,主库日志写到中继日志,中继日志再重做到从库
# relay-log=myslql-relay-bin# binlog保留时间7天
expire_logs_days=7# binlog 文件的大小
max_binlog_size=1G
# 设置不要赋值的数据
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
#将修改后的文件复制到容器内
docker cp my.cnf master_mysql:/etc/mysql/
注意:需要重启master_mysql容器
master创建用于同步的用户
mysql 客户端进入控制台,执行下面命令创建用户
先进入docker 容器
docker exec -it master_mysql /bin/bash
在进入mysql 控制台:
mysql -u root -p
进入mysql控制台后,执行下面的语句:
# 创建用户,用于从机复制数据
CREATE USER 'repl'@'%' IDENTIFIED BY '123456';# 分配权限
#注意:此处 *.* 不允许更改,因为 replication slave 权限是一个全局权限,不可以指定在某一个库上
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';# 刷新权限
flush privileges;
master锁定
依然在控制台执行
FLUSH TABLE WITH READ LOCK;
master查看状态
同样还在控制台
SHOW MASTER STATUS;
记录二进制文件名和位置,例如:mysql-bin.000001、767
master解锁
同样在控制台执行
unlock tables;
slave指定同步点
slave指定从master的哪个位置开始进行同步
进入slave_mysql的容器,再进入mysql的控制台,执行下面语句:
CHANGE MASTER TOMASTER_HOST='192.168.5.136', # master ipMASTER_PORT=3306, # master portMASTER_USER='repl', # 上文 master 上创建的同步用户名MASTER_PASSWORD='123456', # 同步用户密码MASTER_LOG_FILE='mysql-bin.000001', # 使用上面的 mysql-bin.000001MASTER_LOG_POS=767; # 使用上面的 767
slave设置server-id
#将mysql容器中的my.cnf配置文件拷贝到宿主机来修改
docker cp slave_mysql:/etc/mysql/my.cnf ./
在my.cnf 中添加:
[mysqld]
server-id=2 # 设置server-id。master和每一个slave的server-id都不能一样,用于唯一标识节点
sync_binlog=1
将my.cnf 复制到容器
docker cp my.cnf slave_mysql:/etc/mysql/
注意:重启容器
slave开启复制
在slave_mysql 容器的mysql 控制台执行
start slave;
slave查看状态
同样在slave的mysql控制台
# 查看slave状态
show slave status\G;
查看结果类似如下:
主要关注红框的两个值,都为Yes表示成功,主从同步配置完成
设置salve 同步到master
将上面的操作反过来重复操作一遍
测试
分别在master 和slave 上创建数据库,创建表,插入数据,删除数据,看两个库是否会同步,注意必须执行sql,只有执行的是sql 语句才会同步。
四、keepalived 安装
安装keepalived
两台服务器都安装keepalived
yum -y install keepalived
配置keepalived
- master 节点
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalivedglobal_defs {router_id LVS_DEVEL #同一个小组要不一样
}
vrrp_script chk_mysql {script "/etc/keepalived/check_mysql.sh" #检查脚本interval 5weight -5fall 2rise 1
}
vrrp_instance VI_1 {state MASTERinterface ens192 #网卡名称unicast_src_ip 192.168.5.136unicast_peer {192.168.5.137}virtual_router_id 51 #这个同一个分组要一样priority 100advert_int 2authentication {auth_type PASSauth_pass mysql}virtual_ipaddress {192.168.5.189 #vip地址}track_script {chk_mysql
} }EOF
- slave节点
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalivedglobal_defs {router_id LVS_DEVEL2
}
vrrp_script chk_mysql {script "/etc/keepalived/check_mysql.sh"interval 5weight -5fall 2rise 1
}
vrrp_instance VI_1 {state BACKUPinterface ens192unicast_src_ip 192.168.5.137unicast_peer {192.168.5.136}virtual_router_id 51priority 80nopreemptadvert_int 2authentication {auth_type PASSauth_pass mysql}virtual_ipaddress {192.168.5.189}track_script {chk_mysql
} }EOF
- 健康检查脚本
两个服务器的一样
cat > /etc/keepalived/check_mysql.sh << EOF
#!/bin/basherr=0
for k in $(seq 1 3)
docheck_code=$(pgrep mysql)if [[ $check_code == "" ]]; thenerr=$(expr $err + 1)sleep 1continueelseerr=0breakfi
doneif [[ $err != "0" ]]; thenecho "systemctl stop keepalived"/usr/bin/systemctl stop keepalivedexit 1
elseexit 0
fi
EOF
chmod +x /etc/keepalived/check_mysql.sh
- 启动keepalived
systemctl daemon-reload
systemctl enable --now keepalived
- 查看keepalived状态, 如果是active 就表示正常
systemctl status keepalived
配置启动keepalived 的定时任务
如果当master 节点挂掉了后 ,排除故障之后,master节点的mysql 容器会被启动,启动后从节点的数据就会同步到master ,这个时候不能立即启动keepalived ,因为我们配置的是抢占式, 只要主节点的keepalived 恢复了就会抢回VIP, 这个时候可能数据还没有同步完,会造成数据库数据不同步,所以这里隔两分钟在去启动keepalived .
两个服务器都需要
mkdir -p /data/crontabsh
启动keepalived脚本
cat > /data/crontabsh/check_keepalived.sh << EOF
#!/bin/bash
check_mysql=$(pgrep mysql)
check_keepalived=$(pgrep keepalived)
if [[ $check_mysql != "" ]] && [[ $check_keepalived == "" ]]; then echo "keepalived未启动,即将执行启动命令"systemctl start keepalived
elseexit -1
fiEOF
给脚本权限
chmod +x /data/crontabsh/check_keepalived.sh
加定时任务
[root@localhost crontabsh]# crontab -e*/2 * * * * /bin/bash /data/crontabsh/check_keepalived.sh[root@localhost crontabsh]# crontab -l
*/2 * * * * /bin/bash /data/crontabsh/check_keepalived.sh
检查VIP是否漂移
通过 ip addr 查看VIP是否在该节点上
开始VIP应是在 master 上的, 停止master 上的mysql 容器 ,看VIP是否能漂移到slave 节点
当VIP在slave 节点, 启动master 上的mysql ,隔两分钟再看VIP 是否能回到master 上来。