DBA数据库笔记之(十)双主+keepalived,Orches
2024-01-25 本文已影响0人
Mr培
MySQL主流高可用方案
主从或主主+Keepalived
主从或主主+Keepalived.jpgMHA
MHA.jpgPXC
PXC.jpgInnoDB Cluster
InnoDB Cluster.jpgXenon
Xenon.jpgOrchestrator
Orchestrator.jpg双主+keepalived部署
环境准备
- 修改参数
# 161,162两台机器作为双主
# 第一台机器修改配置文件
vim /data/mysql/conf/my.conf
# 查看binlog是否开启,需要开启
# 查看server_id是否配置,需要配置
# 第二台机器修改配置文件
vim /data/mysql/conf/my.conf
# 查看binlog是否开启,server_id需要不一样
#两台机器修改参数,机器内存的60%~80%
innodb_buffer_pool_size = 1G
# 开启两台机器的GTID
gtid_mode=on
# 不允许事务违反gtid一致性
enforce_gtid_consistency=on
# 重启两台MySQL
/etc/init.d/mysql.server restart
# 关闭两台机器的防火墙
systemctl stop firewalld
# 开启禁用防火墙
systemctl disable firewalld
# 查看SELinux是否关闭,如果开启启动keepalived将执行不了校验脚本,双主+keepalived部署需要关闭SELinux
sestatus
# 编辑配置文件
vim /etc/selinux/config
SELINUX=disabled
# 再两台重启机器
- 创建用户并赋予权限
# 在两台MySQL内执行
# 创建复制的用户
create user 'repl'@'%' identified with mysql_native_password by '123456';
grant replication slave on *.* to 'repl'@'%';
# 创建心跳检测的用户
create user 'keepalived_r'@'%' identified with mysql_native_password by '123456';
grant select slave on *.* to 'keepalived_r'@'%';
- 让主从数据一致
# 随便一台机器执行
cd /data/backup/
# 执行备份语句
mysqldump -uroot -p --single-transaction --all-databases --master-data=2 --set-gtid-purged=on > alldb_bak_for_gtid.sql
# 将备份传到从库
scp alldb_bak_for_gtid.sql 192.168.12.162:/data/backup
# 在从库
#清空master
reset master;
# 再导入备份
cd /data/backup/
mysql -uroot -p < alldb_bak_for_gtid.sql
建立双主复制关系
- 建立A到B的复制关系
# 在B(从)上
stop slave;
reset slave;
# 新建复制关系
change master to master_host='192.168.12.161',master_user='repl',master_password='123456',master_auto_position=1;
# 开启复制
start slave;
# 查看复制状态
show slave status\G;
- 建立B到A的复制关系
# 在A(主)上
stop slave;
reset slave;
change master to master_host='192.168.12.162',master_user='repl',master_password='123456',master_auto_position=1;
# 开启复制
start slave;
# 查看复制状态
show slave status\G;
# 双向复制创建成功,数据测试
... ...
安装配置keepalived
- 安装keepalived
# 在两台机器安装
yum install -y keepalived
# 将keepalived添加到开机启动里面
systemctl enable keepalived.server
- 在A机器上修改keepalived文件
vim /etc/keepalived/keepalived.conf
# 删除默认配置,粘贴新配置
global_defs {
# 本机的ip地址
router_id 192.168.12.161
}
# keepalived用来校验MySQL的脚本
vrrp_script check_mysql {
script "/home/mysql/bin/checkmysql.sh /tmp/mysql.sock"
# 每隔3秒执行一次脚本
interval 3
weight 2
}
vrrp_instance MYSOL_MM2{
state BACKUP
# 网卡的名字,与机器一致
interface ens33
# 建议设置为vip的位数,主从需要一样
virtual_router_id 100
priority 99
nopreempt
advert_int 2
authentication{
auth_type PASS
auth_pass xxx
}
track_script {
check_mysql
}
unicast_peer {
# 同一组另外一台机器的ip地址
192.168.12.162
}
virtual_ipaddress{
# 虚拟ip,同一网段随便设置,且未被使用
192.168.12.100
}
# ens33 网卡名字,192.168.12.100虚拟ip,192.168.12.2网关
notify_master "/sbin/arping -I ens33 -c3 -s192.168.12.100 192.168.12.1 > /tmp/arping.log;"
}
# 查看网卡名字
ip a
# 查看网关
route -n
- 在B机器上修改keepalived文件
vim /etc/keepalived/keepalived.conf
# 删除默认配置,粘贴新配置
global_defs {
# 本机的ip地址
router_id 192.168.12.162
}
# keepalived用来校验MySQL的脚本
vrrp_script check_mysql {
script "/home/mysql/bin/checkmysql.sh"
# 每隔3秒执行一次脚本
interval 3
weight 2
}
vrrp_instance MYSOL_MM2{
state BACKUP
# 网卡的名字,与机器一致
interface ens33
# 建议设置为vip的位数,主从需要一样
virtual_router_id 100
priority 99
nopreempt
advert_int 2
authentication{
auth_type PASS
auth_pass xxx
}
track_script {
check_mysql
}
unicast_peer {
# 同一组另外一台机器的ip地址
192.168.12.161
}
virtual_ipaddress{
# 虚拟ip,同一网段随便设置,且未被使用
192.168.12.100
}
# ens33 网卡名字,192.168.12.100虚拟ip,192.168.12.2网关
notify_master "/sbin/arping -I ens33 -c3 -s192.168.12.100 192.168.12.2 > /tmp/arping.log;"
}
配置检测脚本
- 编写脚本
# 在两台机器执行
mkdir -p /home/mysql/bin
mkdir -p /home/mysql/log/
# 编辑校验脚本
vim /home/mysql/bin/checkmysql.sh
PATH=$PATH:/usr/local/mysql/bin
if [[ -n $1]]
then
MYSQL_SOCK="$1"
else
MYSQL_SOCK="/tmp/mysql.sock"
fi
MYSQL_USERNAME="keepalived_r"
MYSQL_PASSWORD="123456"
for i in 1 2 3
do
alivel=`mysqladmin -S $MYSQL_SOCK -u$MYSQL_USERNAME -p$MYSQL_PASSWORD ping | grep -c alive `
if [$alivel -eq 1]
then
echo "alive"
exit 0;
else
if [[$i -eq 3]]
then
systemctl restart keepalived
echo "$(date + "%Y%m%d %H:%M:%S") keepalived restart" >> /home/mysql/log/keepalived.log
else
sleep 0.9
fi
fi
done
# 保存退出,赋予执行权限
chmod 700 /home/mysql/bin/checkmysql.sh
- 启动keepalived
# 两台机器启动keepalived
# 优先作为主库的机器就先启动keepalived
service keepalived start
# 查看是否生成了vip(虚拟ip)
ip a
- 测试通过VIP连接MySQL
上线前测试高可用是否正常,比如关闭一台机器看keepalived是否正常切换
双主+keepalived测试
编写持续写入MySQL数据的Go程序
- 创建测试用户测试表
create user 'go_rw'@'%' identified with mysql_native_password by '123456';
grant insert,delete,select,update on martin.* to 'go_rw'@'%';
create table user_info(
id int auto_increment primary key,
name varchar(255),
age int,
create_at datetime not null default current_timestamp
);
# 查看两台机器复制状态是否正常
show slave status\G;
- 通过ChatGPT编写MySQL数据写入的程序
MySQL的IP为:192.168.12.100,用户名是go_rw,密码是xxx,
编写一个Go程序,每隔一秒往MySQL的martin库user_info写入一行数据,
并输出当前时间和写入成功
user_info表结构如下:
create table user_info(
id int auto_increment primary key,
name varchar(255),
age int,
create_at datetime not null default current_timestamp
);
- 运行程序
# 查看MySQL数据是否写入成功
use martin;
select * from user_info;
停MySQL服务测试高可用
- 停掉有VIP的MySQL实例A
ip a
/etc/init.d/mysql.server stop
# 观察程序写入是否正常
# 在两台机器查看虚拟ip是否完成切换
ip a
- 启动A上的MySQL
/etc/init.d/mysql.server start
- 停掉新主的MySQL实例B
/etc/init.d/mysql.server stop
# 观察程序写入是否正常
# 在两台机器查看虚拟ip是否完成切换
ip a
重启MySQL所在的机器测试高可用
- 重启有VIP的MySQL机器A
ip a
reboot
# 观察程序写入是否正常
# 查看服务器是否启动,mysql,keepalived是否启动正常
ps -ef | grep mysql
ps -ef | grep keepalived
- 重启新主的MySQL机器B
ip a
reboot
# 观察程序写入是否正常
# 查看服务器是否启动,mysql,keepalived是否启动正常
ps -ef | grep mysql
ps -ef | grep keepalived
Orchestrator
Orchestrator的优势
- 可视化
- 复杂拓扑管理
- 拓扑发现
- 自身高可用
- 灵活的恢复选项
- 安全
- 精准
- 高效
- 快速
- API接口
Orchestrator集群的快速部署
Orch常用架构介绍
Orch常用架构介绍.jpg要部署的架构介绍
要部署的架构介绍.jpg安装和配置Orch
- 安装Orch
# 在三台机器操作
cd /usr/src/
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator-3.2.6-1.x86_64.rpm
yum install orchestrator-3.2.6-1.x86_64.rpm -y
# 查看是否安装成功
rpm -qa | grep orch
# 每一台安装orch的机器都要安装一台MySQL
- 配置Orch的元数据库
# 在每一台MySQL创建orch的用户
create user 'orc_server_user'@'127.0.0.1' identified by '123456';
grant all privileges on `orchestrator`.* to 'orc_server_user'@'127.0.0.1';
- 配置Orch
# 在每一台机器
cd /usr/local/orchestrator/
mkdir -p {log,conf,raftdata}
# 复制配置文件
cp orchestrator-sample.conf.json ./conf/orchestrator.conf.json
# 编辑配置文件
vim ./conf/orchestrator.conf.json
# 需要修改的参数
"MySQLTopologyUser":"orc_client_user",
"MySQLTopologyPassword":"123456",
"MySOLOrchestratorHost": "127.0.0.1",
"MySOLOrchestratorPort":3306,
"MySOLOrchestratorDatabase":"orchestrator",
"MySQLOrchestratorUser":"orc_server_user",
"MySQLOrchestratorPassword":"123456",
# 配置认证方式,开启orchestrator页面和命令行,api都需要通过用户密码才能访问,一般建议开启
"AuthenticationMethod":"basic",
"HTTPAuthUser":"admin",
"HTTPAuthPassword":"123456",
# 在这下面添加参数
“RaftEnabled":true,
"RaftDataDir":"/usr/local/orchestrator/raftdata",
# 本机的ip地址
"RaftBind":"192.168.12.161",
"DefaultRaftPort":10008,
# orchestrator三个节点的ip
"RaftNodes":[
"192.168.12.161"
"192.168.12.162"
"192.168.12.163"
],
# 修改参数
# 如果再次发生故障,多少秒之内不会再次转移
"RecoveryPeriodBlockSeconds":60,
# 恢复会忽略的主机
"RecoveryIgnoreHostnameFilters":[],
# 表示只在匹配正则表达式模式集群上进行主 恢复
"RecoverMasterClusterFilters":["*"],
"RecoverIntermediateMasterClusterFilters":["*"]
部署测试高可用的MySQL拓扑
- 启动三个新的MySQL
- 从主库备份数据传到从库
# 在主库
cd /data/backup/
# 执行备份语句
mysqldump -uroot -p --single-transaction --all-databases --master-data=2 --set-gtid-purged=on > alldb_bak_for_gtid.sql
# 将备份传到从库
scp alldb_bak_for_gtid.sql 192.168.12.166:/data/backup
scp alldb_bak_for_gtid.sql 192.168.12.167:/data/backup
# 在两台从库上
reset master;
cd /data/backup/
# 导入数据
mysql -uroot -p < alldb_bak_for_gtid.sql
- 配置一主两从架构
# 保证三台机器server-id不一致
vim /data/mysql/conf/my.cnf
# 一般建议为ip的后两段
server-id=12165
# 删除三台机器的cnf
rm /data/mysql/data/auto.cnf
# 重启三台机器的MySQL
/etc/init.d/mysql.server restart
# 在第二台,第三台机器建立复制关系
stop slave;
reset slave;
change master to master_host='192.168.12.166',master_user='repl',master_password='123456',master_auto_position=1;
# 开启复制
start slave;
# 查看复制状态
show slave status\G;
将测试高可用的MySQL配置到Orch中
- 在测试高可用的MySQL中创建Orch连接用户
# 也就是
# "MySQLTopologyUser":"orc_client_user",
# "MySQLTopologyPassword":"123456",
# 这个账号和密码
# 在主库上创建用户
create user 'orc_client_user'@'192.168.12.%' identified by '123456';
grant super,process,replication slave,reload on *.* to 'orc_client_user'@'192.168.12.%';
grant select on mysql.slave_master_info to 'orc_client_user'@'192.168.12.%';
# 在三台Orch机器和三台测试高可用的MySQL上增加host信息
vim /etc/hosts
# 三台机器都需要增加参数 ip 机器名字
192.168.12.165 martin-05
192.168.12.166 martin-06
192.168.12.167 martin-07
- 启动Orch
# 在三台机器操作
cd /usr/local/orchestrator
/usr/local/orchestrator/orchestrator -config /usr/local/orchestrator/conf/orchestrator.conf.json http >> /usr/local/orchestrator/log/orchestrator.log 2 > &1 &
# 判断是否启动成功
ps -ef | grep orch
# 游览器登录管理界面
192.168.12.161:3000
# 查看密码
cat /usr/local/orchestrator/conf/orchestrator.conf.json
"HTTPAuthUser":"admin",
"HTTPAuthPassword":"123456",
- 将业务MySQL添加到Orch中
管理界面点击 cluster -> discover
输入要监控的MySQL拓扑的随便一个实例
查看集群的拓扑,点击cluster -> Dashboard
Orchestrator实现MySQL故障切换实验
故障切换演示:关闭主实例
- 关闭主实例
/etc/init.d/mysql.server stop
- 在管理页面上确定是否发生了拓扑切换
- 在MySQL里面验证复制关系
show slave status\G
旧主恢复之后的拓扑
- 启动原来的主实例
/etc/init.d/mysql.server start
- 在管理页面上确定新的拓扑
- 在MySQL里面验证复制关系
show slave status\G
- 再到页面上把复制关系改成一主两从
在管理页面上拓扑关系,直接拖拽的方式修改
故障切换演示:关闭主实例所在的机器
- 关闭主实例所在的机器
power
- 在管理页面上确定拓扑是否发生了切换
- 在MySQL里面验证复制关系
# 有一个连接不上主
show slave status\G
- 启动机器,查看MySQL是否正常开机启动
- 再到页面上把复制关系改成一主两从
Orch常见命令行操作
安装配置Orchestrator客户端命令
- 下载客户端
cd /usr/src/
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator-client-3.2.6-1.x86_64.rpm
# 安装
yum install orchestrator-client-3.2.6-1.x86_64.rpm -y
- 配置环境变量
export ORCHESTRATOR_API="192.168.12.161:3000/api 192.168.12.162:3000/api 192.168.12.163:3000/api"
export ORCHESTRATOR_AUTH_USER=admin
export ORCHESTRATOR_AUTH_PASSWORD=123456
- 测试客户端命令
# 查看当前集群
orchestrator-client -c clusters
使用客户端命令进行实例管理
- 查看当前管理的所有实例
orchestrator-client -c all-instances
- 删除一个实例
# martin-07:3306 实例名称
orchestrator-client -c forget -i martin-07:3306
- 新增一个实例
orchestrator-client -c discover -i martin-07:3306
使用客户端命令进行集群拓扑管理
- 查看某个集群的拓扑结构
# martin-05:3306 集群名字
orchestrator-client -c topology -i martin-05:3306
- 主从切换自动选主
orchestrator-client -c graceful-master-takeover-auto -i martin-05:3306
- 指定新主,切换后不启动旧主的复制线程
# martin-07:3306 新主
orchestrator-client -c graceful-master-takeover -i martin-06:3306 -d martin-07:3306
# 查看集群拓扑信息
orchestrator-client -c topology -i martin-05:3306
- 指定新主,切换后启动旧主的复制线程
orchestrator-client -c graceful-master-takeover-auto -i martin-06:3306 -d martin-07:3306
# 查看集群拓扑信息
orchestrator-client -c topology -i martin-05:3306
- 把一个实例接到另外一个实例下进行复制
# martin-07:3306 接到 martin-06:3306 下复制,就会变成级联架构
orchestrator-client -c relocate -i martin-07:3306 -d martin-06:3306
# 查看拓扑信息
orchestrator-client -c topology -i martin-05:3306
- 设置节点读写
orchestrator-client -c set-writeable -i martin-06:3306
# 查看拓扑信息
orchestrator-client -c topology -i martin-05:3306
# 设置节点只读
orchestrator-client -c set-read-only -i martin-06:3306
Orchestrator Hook
准备
- 修改参数
# 三个节点都要修改
vim /usr/local/orchestrator/conf/orchestrator.conf.json
# 线上建议设置为true
"MasterFailoverDetachReplicaMasterHost":true
- 在主库上添加VIP
ip addr add 192.168.12.200/24 dev ens33
# 查看网卡名字
ip a
- 建立Orch到业务MySQL机器的互信
# 生成公式钥
ssh-keygen
# martin-05业务MySQL/测试MySQL拓扑三台机器的ip,查看vim /etc/hosts
ssh-copy-id root@martin-05
# 测试,在三台机器都测试一下
ssh root@martin-05 "ls"
ssh root@martin-05 "ip a"
ssh root@martin-06 "ip a"
ssh root@martin-07 "ip a"
增加Hook配置
- 修改配置文件
# 在三台机器都需要修改
vim /usr/local/orchestrator/conf/orchestrator.conf.json
# 需要在 PostFailoverProcesses 里添加一行配置
"PostFailoverProcesses":[
"默认配置,不动",
"/usr/local/orchestrator/shell/orch_hook.sh {failureType} {failureClusterAlias} {failedHost} {successorHost} >> /tmp/orch.log"
]
- 重启Orch
# 在三台机器重启
ps -ef | grep orch
kill -9 4366
/usr/local/orchestrator/orchestrator -config /usr/local/orchestrator/conf/orchestrator.conf.json http >> /usr/local/orchestrator/log/orchestrator.log 2 > &1 &
- 编辑Hook脚本
# 在三台机器
mkdir -p /usr/local/orchestrator/shell/
vim /usr/local/orchestrator/shell/orch_hook.sh
#!/bin/bash
# 脚本接收的参数
FAILURE_TYPE=$1
CLUSTER_ALIAS=$2
FAILED_HOST=$3
SUCCESSOR_HOST=$4
# VIP 地址和网络接口配置
VIP='192.168.12.200' # 替换为您的 VIP 地址
INTERFACE='ens33' # 替换为您的网络接口名称
# 日志文件路径,自定义
LOG_FILE="/tmp/vip_migration.log"
# 函数:在指定主机上添加或删除 VIP
update_vip(){
local host=$1
local action=$2 #"add"或"del"
echo "$(date): Updating VIp ($VIP) on $host: $action" >> $LOG_FILE
# SSH 到指定主机执行 IP 地址的添加或删除
ssh root@$host "ip addr $action $VIP/24 dev $INTERFACE" 2>>$LOG_FILE
if [ $? -eq 0 ]; then
echo "$(date): VIp $action operation successful on $host" >> $LOG_FILE
else
echo "$(date): Error during VIP $action operation on $host" >> $LOG_FILE
fi
}
# 主逻辑
echo "$(date):0rchestrator hook triggered" >> $LOG_FILE
echo "$(date): Failure Type: $FAILURE_TYPE,Cluster:$CLUSTER_ALIAS,Failed Host: $FAILED_HOST,Successor Host: $SUCCESSOR_HOST" >> $LOG_FILE
# 检查是否为主库故障转移
if [ "$FAILURE_TYPE" == "DeadMaster"]; then
# 从失败的主机删除 VIP
update_vip $FAILED_HOST "del"
# 在后续主机上添加VIP
update_vip $SUCCESSOR_HOST "add"
else
echo "$(date):No action taKen, Not a master failure." >> $LOG_FILE
fi
# 赋予可执行权限
chmod +x orch_hook.sh
测试高可用
- 程序连接VIP写数据
运行之前的程序,一直往数据库写入数据
- 关闭主库,查看高可用性
/etc/init.d/mysql.server stop
# 查看程序是否写入正常
# 查看拓扑信息
orchestrator-client -c topology -i martin-05:3306
orchestrator-client -c topology -i martin-06:3306
# 启动
/etc/init.d/mysql.server start
# 手动把启动的MySQL添加到集群,在MySQL内
stop slave;
reset slave;
change master to master_host='192.168.12.167',master_user='repl',master_password='123456',master_auto_position=1;
start slave;
show slave status\G
- 页面修改拓扑,查看VIP是否切换
在管理页面直接拖拽修改主库,然后查看主库是否有VIP
ip a
Orch故障恢复及选主逻辑
- 切换逻辑
- Orch连不上主
- Orch能连上从,并且这写从也不能连上主
- 发起选主
- 选主逻辑
- binlog位置靠前的优先
- 打开了log_slave_updates的优先
- 新的2MySQL版本优先
- Binlog格式:row>mixed>statement
- 同机房优先
- 无gtid_errant优先
- 通过参数DetectPromotionRuleQuery指定的
- 有些情况不会进行恢复
- 这个集群不在自动恢复的列表里面
- 管理员制定了,不应该在特定服务器上进行恢复
- 管理员用户已全局禁用恢复
- 集群内部不久前刚完成了一次恢复
- 故障类型被认为不需要恢复
-
给定拓扑中主实例如何发现从实例
给定拓扑中主实例如何发现从实例.jpg