案例介绍
案例环境
服务器Centos7.4(64位)manager/192.168.218.7
管理节点,安装 manager 组件
服务器Centos7.4(64位)Mysql1/192.168.218.4 Master节点,安装 node组件
服务器 Cent0S7.4(64位)Mysql2/192.168.218.5 Slave1 节点,安装 node组件
服务器 Cent0S7.4(64位)Mysql3/192.168.218.6 Slave2 节点,安装node组件
这里操作系统是Cent0S7版本,所以这里下载MHA版本是0.57版本
案例需求
本案例要求通过MA监控MySQL数据库在故障时进行自动切换,不影响业务
案例实现思路
1)安装 MySQL数据库
2)配置MySQL一主两从
3)安装MHA软件
4)配置无密码认证
5)配置MySQL MHA 高可用
6)测试:模拟master 故障切换
案例实现
安装MySQL
name | IP |
---|---|
master | 192.168.218.4 |
slave1 | 192.168.218.5 |
slave2 | 192.168.218.6 |
对以上三台服务器安装MySQL |
安装编译依赖
yum -y install ncurses-devel gcc-c++ gcc perl-Module-Install
安装cmake-2.8.6
解压cmake包,进入cmake源码目录后,编译安装cmake
./configure
gmake && gmake install
安装MySQL5.6.36
解压MySQL源码包,进入MySQL源码目录后,编译安装MySQL
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DSYSCONFDIR=/etc
make && make install
复制配置文件和服务启动脚本
# 覆盖原有的my.cnf,输入y
cp support-files/my-default.cnf /etc/my.cnf
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
添加mysqld服务
chmod +x /etc/rc.d/init.d/mysqld
chkconfig --add mysqld
添加环境变量
echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
改完文件后别忘了source一下
source /etc/profile
添加程序运行用户
groupadd mysql
useradd -M -s /sbin/nologin mysql -g mysql
chown -R mysql.mysql /usr/local/mysql
初始化数据库
/usr/local/mysql/scripts/mysql_install_db \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data \
--user=mysql
修改master配置文件/etc/my.cnf
[mysqld]
server-id = 1 //三台MySQLserver-id不能一样
log_bin = master-bin
log-slave-updates = true
修改slave1、slave2配置文件
[mysqld]
server-id = 2 //注意与slave2不能一样
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
三台MySQL服务器启动MySQL
ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
/usr/local/mysql/bin/mysqld_safe --user=mysql &
进入数据库
# 初始密码为空
mysql -u root -p
配置远程登陆
GRANT ALL ON *.* TO 'remote_user'@'%' IDENTIFIED BY 'abc123';
配置MySQL一主两从
在所有的MySQL服务器上授权两个用户
mysql_slave用于数据库主从同步
mha_manager用于manager连接MySQL
GRANT REPLICATION SLAVE ON *.* TO 'mysql_slave'@'192.168.218.%' IDENTIFIED BY 'abc123';
GRANT ALL PRIVILEGES ON *.* TO 'mha_manager'@'192.168.218.%' IDENTIFIED BY 'abc123';
FLUSH PRIVILEGES;
下面三条授权按理论是不用添加的,但是做案例实验环境时候通过检查MySOL主从有报错,报两个从库通过主机名连接不上主库,所以所有数据库加上下面的授权
GRANT ALL PRIVILEGES ON *.* TO 'mha_manager'@'master' IDENTIFIED BY 'abc123';
GRANT ALL PRIVILEGES ON *.* TO 'mha_manager'@'slave1' IDENTIFIED BY 'abc123';
GRANT ALL PRIVILEGES ON *.* TO 'mha_manager'@'slave2' IDENTIFIED BY 'abc123';
FLUSH PRIVILEGES;
在master上查看状态
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 1330 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在输出信息中有日志名称和position,保存一下,下面要用
在slave1、slave2上,配置master,参数中加入日志名称和position
CHANGE MASTER TO MASTER_HOST='192.168.218.4', MASTER_USER='mysql_slave', MASTER_PASSWORD='abc123', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=1330;
START SLAVE;
查看slave状态
mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
……省略部分……
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
……省略部分……
slave已成功开启
设置两个从库为只读模式
set global read_only=1;
flush privileges;
配置完成
安装MHA软件
安装node
node节点在MySQL以及manager都需要部署,故以下安装node操作需要在所有服务器上做
部署yum、epel源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
yum clean all
yum makecache
yum -y install epel-release --nogpgcheck
安装环境依赖
yum -y install \
perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN
解压mha-node包,进入源码目录
perl Makefile.PL
make
make install
安装manager
在MHA-manager上安装manager组件
解压manager包,进入安装目录
perl Makefile.PL
make
make install
manager 安装在/usr/local/bin 下面会生成几个工具,主要包括以下几个:
工具名 | 描述 |
---|---|
masterha_check_ssh | 检查 MHA的 SSH配置状况 |
masterha_check_repl | 检查MySQL 复制状况 |
masterha_manger | 启动 manager的脚本 |
masterha_check_status | 检测当前MHA 运行状态 |
masterha_master_monitor | 检测 master 是否宕机 |
masterha_master_switch | 控制故障转移(自动或者手动) |
masterha_conf_host | 添加或删除配置的server信息 |
masterha_stop | 关manager |
node 安装后也会在/usr/local/bin 下面会生成几个脚本(这些工具通常由MHA Manager 的脚本触发,无需人为操作)主要如下:
工具名 | 描述 |
---|---|
save_binary_logs | 保存和复制 master的二进制日志 |
apply_diff_relay_logs | 识别差异的中继日志事件并将其差异的事件应用于其他的 slave |
filter_mysalbinlog | 去除不必要的ROLLBACK事件(MHA已不再使用这个工具) |
purge_relay_logs | 清除中继日志(不会阻塞SQL线程) |
配置无密码认证
在manager上配置到所有数据库节点的无密码认证
ssh-keygen -t rsa
ssh-copy-id ip //向三个MySQL服务器发送密钥
所有MySQL数据库节点之间两两配置无密码认证,同上
配置MySQL MHA高可用
在manager节点上复制相关脚本到/usr/local/bin目录
切换到manager目录下的samples/,把scripts目录复制
cp -ra scripts/ /usr/local/bin
拷贝后有四个执行文件
/usr/local/bin/scripts/
工具 | 描述 |
---|---|
master_ip_failover | 自动切换时 VIP管理的脚本 |
master_ip_online_change | 在线切换时 vip的管理 |
power_manager | 故障发生后关闭主机的脚本 |
send_report | 因故障切换后发送报警的脚本 |
复制上述的自动切换时VIP管理的脚本到/usr/local/bin目录,这里使用脚本管理VIP
cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
创建MHA软件目录并拷贝配置文件
mkdir /etc/masterha
cp manager目录下的/samples/conf/app1.cnf /etc/masterha/
vim /etc/masterha/app1.cnf
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
my $vip = '192.168.218.100';
my $brdc = '192.168.218.255';
my $ifdev = 'ens33';
my $key = '1';
my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip";
my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
mkdir /etc/masterha
进入manager源码目录
cp samples/conf/app1.cnf /etc/masterha/
cd /etc/masterha/
cp app1.cnf app1.cnf.bak
vim编辑app1.cnf
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
user=mha_manager
password=abc123
ping_interval=1
remote_workdir=/tmp
repl_password=abc123
repl_user=mysql_slave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.218.5 -s 192.168.218.6
shutdown_script=""
ssh_user=root
[server1]
hostname=192.168.218.4
port=3306
[server2]
hostname=192.168.218.5
candidate_master=1
check_repl_delay=0
port=3306
[server3]
hostname=192.168.218.6
port=3306
测试ssh无密码认证,如果正常最后会输出successfully
masterha_check_ssh -conf=/etc/masterha/app1.cnf
测试主从同步
masterha_check_repl -conf=/etc/masterha/app1.cnf
第一次配置,需要去手动开启虚拟IP
到master上
/sbin/ifconfig ens33:1 192.168.218.100/24
到manager上,启动MHA
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
查看MHA状态,可以看到当前的master是MySQL1节点
[root@localhost bin]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:1678) is running(0:PING_OK), master:192.168.218.4
可查看/var/log/masterha/app1/manager.log
在一台客户端client上,使用mysql访问vip的数据库
mysql -h 192.168.218.100 -u root -p
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.13 sec)
MySQL [(none)]> create database manager;
Query OK, 1 row affected (0.01 sec)
在master上看
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| manager |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
在slave1上
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| manager |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
slave2上也是一样
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| manager |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.13 sec)
数据库已经同步过来了
模拟master故障切换
在manager上,启动检测观察日志记录
tail /var/log/masterha/app1/manager.log
在master上,关闭MySQL
pkill -9 mysql
等一小会,到slave1上查看网卡
ifconfig
……
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.218.100 netmask 255.255.255.0 broadcast 192.168.218.255
ether 00:0c:29:…… txqueuelen 1000 (Ethernet)
……
可以看见,vip的192.168.218.100已经转移到了slave1
在manager上查看状态
[root@localhost bin]# masterha_check_status -conf=/etc/masterha/app1.cnf
app1 (pid:36150) is running(0:PING_OK), master:192.168.218.5
master已经转移到192.168.218.5上了
说明已完成故障转移