MySQL数据库在线热备(使用MHA搭建高可用架构)

MySQL的MHA高可用架构设计

MHA简介

什么是MHA?

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在较大程度上保证数据的一致性,以达到真正意义上的高可用。

MHA工作原理:

在这里插入图片描述

  1. 当master出现故障时,通过对比slave之间I/O线程读取master上binlog的位置,选取最接近的slave做为最新的slave(latest slave)。(即对比master和其他slave的二进制日志,选取差异最小的作为latest slave)

  2. 其它slave通过与latest slave对比生成差异中继日志,并应用。(即其他slave 同步复制latest slave 上自身没有的中继日志)

  3. 在latest slave上应用从master保存的binlog,同时将latest slave提升为master。(即latest salve 会生成一个二进制文件,自身成为master)

  4. 最后在其它slave上应用相应的差异中继日志并开始从新的master开始复制。(即新master生成的二进制文件与其他slave的中继日志有差异,slave会同步复制新master的binlog到中继日志。从而完成高可用)

MHA的组件

MHA Manager(管理节点):

  • MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。

MHA Node(数据节点):

  • MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将数据最接近master的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

MHA组件介绍

MHA Manager

  • 运行一些工具,比如masterha_manager工具实现自动监控MySQL Master和实现master故障切换,其它工具手动实现master故障切换、在线mater转移、连接检查等等。一个Manager可以管理多 个master-slave集群

MHA Node

  • 部署在所有运行MySQL的服务器上,无论是master还是slave。主要有三个作用:
  1. 保存二进制日志

     如果能够访问故障master,会拷贝master的二进制日志
    
  2. 应用差异中继日志

    从拥有最新数据的slave上生成差异中继日志,然后应用差异日志。
    
  3. 清除中继日志

    在不停止SQL线程的情况下删除中继日志,即清理新master的中继日志	
    

MHA中工具介绍:

Manager工具:

工具说明
masterha_check_ssh检查MHA的SSH配置
masterha_check_repl检查MySQL复制,即MHA主从复制架构
masterha_manager启动MHA
masterha_check_status检测当前MHA运行状态
masterha_master_monitor监测master是否宕机 (系统会自动调用)
masterha_master_switch控制故障转移(自动或手动) (系统会自动调用)
masterha_conf_host添加或删除配置的server信息 (系统会自动调用)

Node工具:

  • 注意:Node这些工具通常由MHA Manager的脚本触发,无需人手操作
工具说明
save_binary_logs保存和复制master的二进制日志
apply_diff_relay_logs识别差异的中继日志事件并应用于其它slave
filter_mysqlbinlog去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs清除中继日志(不会阻塞SQL线程)

MHA 部署

目标:

  • 使用三台服务器搭建MySQL的复制组(基于GTIDs)
  • 使用MHA 管理复制组,当master 挂掉后,会立马提升一台slave作为新的master
  • VIP:MHA主要监控VIP,谁上面有VIP谁就是master;当master挂掉后,MHA就会将VIP切换到latest slave

在这里插入图片描述

部署规划:

角色IP主机名server-id功能备注
MHA-Manager10.1.1.40mha.itcast.cn管理节点
MHA-Node(Master)10.1.1.10master.itcast.cn10数据节点
MHA-Node(Slave1)10.1.1.20slave1.itcast.cn20数据节点
MHA-Node(Slave2)10.1.1.30slave2.itcast.cn30数据节点

系统和软件版本:

系统版本MySQL_glibc版本MHA版本
CentOS 7.6MySQL-5.7.31mha4mysql-manager-0.57 、 mha4mysql-node-0.57

部署目标:

安装目录数据目录套接字端口配置文件位置
/usr/local/mysql/usr/local/mysql/datatmp/mysql.sock3306/usr/local/mysql/my.cnf

系统环境初始化:

克隆机器,首先启动master,然后再依次启动slave1、slave2以及MHA

编写系统初始化脚本:

  • 虚拟机最小化安装后启动该脚本
#!/bin/bash
# Desc:安装MySQL及搭建主从复制架构
host_secure () {
	hostnamectl set-hostname $name
	systemctl stop firewalld
	systemctl disable firewalld
	setenforce 0
	sed -i.bak '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config
cat >> /etc/hosts <<EOF
10.1.1.10 master.mysql.cn
10.1.1.20 slave1.mysql.cn
10.1.1.30 slave2.mysql.cn
10.1.1.40 mha.mysql.cn
EOF
}

os () {
	case $nic_os_name in
	master)
		sed -i.bak '/^UUID=/c\UUID="af42de51-8836-44d0-8b20-1ebfa7818bc6"' $nic_name
		sed -i '4a\IPADDR=10.1.1.10' $nic_name
	;;
	slave1)
		sed -i.bak '/^UUID=/c\UUID="af42de51-8836-44d0-8b20-1ebfa7818bc7"' $nic_name
		sed -i '4a\IPADDR=10.1.1.20' $nic_name
	;;
	slave2)
		sed -i.bak '/^UUID=/c\UUID="af42de51-8836-44d0-8b20-1ebfa7818bc8"' $nic_name
		sed -i '4a\IPADDR=10.1.1.30' $nic_name
	;;
	mha)
		sed -i.bak '/^UUID=/c\UUID="af42de51-8836-44d0-8b20-1ebfa7818bc9"' $nic_name
		sed -i '4a\IPADDR=10.1.1.40' $nic_name
	;;
	esac
}

nic () {
	sed -i '/^BOOTPROTO="/c\BOOTPROTO="static"' $nic_name
	sed -i '5a\DNS2=114.114.114.114' $nic_name
	sed -i '5a\DNS1=8.8.8.8' $nic_name
	sed -i '5a\GATEWAY=10.1.1.2' $nic_name
	sed -i '5a\NETMASK=255.255.255.0' $nic_name	
	systemctl stop NetworkManager
	systemctl disable NetworkManager
	systemctl restart network
}

yum_Tencent_epel () {
  if !(rpm -q wget);then
    yum install -y wget
  fi
    tar -zcPf /etc/yum.repos.d/repo.tar.gz /etc/yum.repos.d/C*.repo
    rm -f /etc/yum.repos.d/*.repo
    wget -O /etc/yum.repos.d/CentOS-tencent-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
    yum clean all
    yum makecache
  yum install bash-completion vim net-tools ntp -y
}

main () {
nic_name=/etc/sysconfig/network-scripts/ifcfg-ens33
read -p "Host name is:" name
read -p "This is: master | slave1 | slave2 | mha:" nic_os_name
# 设置主机名,关闭防火墙和selinux,绑定ip和主机名
host_secure
# 设置网卡信息
os
nic
# 设置yum源和epel源
yum_Tencent_epel
}
main
确认是否已安装ntp:
	# rpm –qa | grep ntp		=>	若只有ntpdate而未见ntp,则需删除原有ntpdate 如:下面这些
		ntpdate-4.2.6p5-22.el7_0.x86_64
		fontpackages-filesystem-1.44-8.el7.noarch
		python-ntplib-0.3.2-1.el7.noarch


	# yum -y remove ntpdate		=>	删除已安装ntp

	# yum install -y ntp		=>	安装ntp

	# ntpdate 120.197.116.202		=>	同步时间

部署MySQL主从复制环境

MASTER主服务器

第一步:上传MySQL软件到/root目录

第二步:使用脚本安装MySQL软件

  • 进行安全配置时需要手动输入一下数据库密码 123
  • 启动脚本:source 脚本名称.sh(因为需要加载/etc/profile 文件)
#!/bin/bash
# Desc:MySQL安装脚本

# 根据版本安装
mysql_install () {
[ -f /etc/my.cnf ] && mv /etc/my.cnf /etc/my.cnf.bak
if ! (id mysql &>/dev/null);then
	useradd -r -s /sbin/nologin mysql
fi
if [ -n "$mysql_glibc" ];then 
    mkdir /usr/local/mysql && tar xf $mysql_glibc.tar.gz -C /usr/local/mysql --strip-components 1
    yum install libaio -y &> /dev/null
fi
if [ -n "$mysql_source" ];then
    mkdir ./$mysql_source 2>/dev/null && tar xf $mysql_source.tar.gz -C ./$mysql_source --strip-components 1 2>/dev/null
    yum -y install cmake ncurses-devel openssl-devel gcc-c++ libaio-devel &> /dev/null
fi
}

# 修改配置文件
mysql_cnf () {
case $mycnf in
ab|AB|a|B)
cat >> /usr/local/mysql/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/master.err
log-bin=/usr/local/mysql/data/binlog
server-id=10
character_set_server=utf8mb4
EOF
;;
gtids|GTIDs|g|G)
cat >> /usr/local/mysql/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/master.err
log-bin=/usr/local/mysql/data/binlog
server-id=10
character_set_server=utf8mb4
gtid-mode=on
log-slave-updates=1
enforce-gtid-consistency
EOF
;;
esac
}



# MySQL设置
mysql_init () {
   cd /usr/local/mysql
   mkdir mysql-files
   chown -R mysql.mysql mysql-files/
   chmod 750 mysql-files/
   chown -R mysql.mysql /usr/local/mysql
   mysql_cnf
   bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data &> /root/pass.txt
   bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data
   cp support-files/mysql.server /etc/init.d/mysqld
   echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
   source /etc/profile
   
   service mysqld start
   pass=`awk 'NR==7{print $NF}' /root/pass.txt`
   mysqladmin -uroot password '123' -p$pass
    mysql -e "flush privileges;" -uroot -p123

mysql_secure_installation <<EOF
123
No
No
Y
Y
Y
Y
EOF
chkconfig --add mysqld
chkconfig mysqld on
}

# 安装glibc版本
sql_glibc () {
if [[ $mysql_glibc = *glibc* ]];then
	mysql_init
fi
}

# 安装源码版
sql_source () {
if [[ $mysql_source = mysql* ]];then
   cd ./$mysql_source

   cmake . \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DWITH_SSL=system \
-DWITH_BOOST=boost
make && make install
mysql_init
fi
}


# 主调函数
main () {
read -p "解压的MySQL_glibc版本,如mysql-5.7.31-linux-glibc2.12-x86_64,:" mysql_glibc
read -p "解压的MySQL_源码包版本,如mysql-boost-5.7.30,:" mysql_source
read -p "需要搭建哪种主从复制,如ab | GTIDs |  :" mycnf


mysql_install
sql_glibc
sql_source
}
main

SLAVE1/SLAVE2从服务器

第一步:上传MySQL软件到/root目录

第二步:使用脚本安装MySQL软件,但是不需要进行初始化

  • 重点:slave 不需要初始化
  • 需要修改一下错误日志文件名称server-id号
  • 下面为slave1的脚本
#!/bin/bash
# Desc:MySQL安装脚本

# 根据版本安装
mysql_install () {
[ -f /etc/my.cnf ] && mv /etc/my.cnf /etc/my.cnf.bak
if ! (id mysql &>/dev/null);then
	useradd -r -s /sbin/nologin mysql
fi
if [ -n "$mysql_glibc" ];then 
    mkdir /usr/local/mysql && tar xf $mysql_glibc.tar.gz -C /usr/local/mysql --strip-components 1
    yum install libaio -y &> /dev/null
fi
if [ -n "$mysql_source" ];then
    mkdir ./$mysql_source 2>/dev/null && tar xf $mysql_source.tar.gz -C ./$mysql_source --strip-components 1 2>/dev/null
    yum -y install cmake ncurses-devel openssl-devel gcc-c++ libaio-devel &> /dev/null
fi
}

# 修改配置文件
mysql_cnf () {
case $mycnf in
ab|AB|a|B)
cat >> /usr/local/mysql/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/slave1.err
relay-log=/usr/local/mysql/data/relaylog
server-id=20
character_set_server=utf8mb4
EOF
;;
gtids|GTIDs|g|G)
cat >> /usr/local/mysql/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/slave1.err
log-bin=/usr/local/mysql/data/binlog
relay-log=/usr/local/mysql/data/relaylog
server-id=20
character_set_server=utf8mb4
gtid-mode=on
log-slave-updates=1
enforce-gtid-consistency
skip-slave-start
EOF
;;
esac
}

# MySQL设置
mysql_init () {
   cd /usr/local/mysql
   mkdir mysql-files
   chown -R mysql.mysql mysql-files/
   chmod 750 mysql-files/
   chown -R mysql.mysql /usr/local/mysql
   mysql_cnf
 
   cp support-files/mysql.server /etc/init.d/mysqld
   echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
   source /etc/profile
   
}

# 安装glibc版本
sql_glibc () {
if [[ $mysql_glibc = *glibc* ]];then
	mysql_init
fi
}

# 安装源码版
sql_source () {
if [[ $mysql_source = mysql* ]];then
   cd ./$mysql_source

   cmake . \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DWITH_SSL=system \
-DWITH_BOOST=boost
make && make install
mysql_init
fi
}

# 主调函数
main () {
read -p "解压的MySQL_glibc版本,如mysql-5.7.31-linux-glibc2.12-x86_64,:" mysql_glibc
read -p "解压的MySQL_源码包版本,如mysql-boost-5.7.30,:" mysql_source
read -p "需要搭建哪种主从复制,如ab | GTIDs |  :" mycnf
read -p "是否创建mha仓库,如 Y | N:" mha

mysql_install
sql_glibc
sql_source
}
main

第三步:使用rsync把MASTER服务器中的data数据目录同步到SLAVE1与SLAVE2

master 服务器执行:

# rm -rf /usr/local/mysql/data/auto.cnf		=>	删除MySQL的UUID,避免主从uuid号重复

# rsync -av /usr/local/mysql/data root@10.1.1.20:/usr/local/mysql/		=>	将数据目录复制到slave1
# rsync -av /usr/local/mysql/data root@10.1.1.30:/usr/local/mysql/		=>	将数据目录复制到slave2

第四步:删除master 复制过来数据目录的二进制文件,然后启动MySQL

slave 服务器执行:

# rm -rf /usr/local/mysql/data/auto.cnf			=>	再执行一遍防止没有删除到

# rm -rf /usr/local/mysql/data/binlog.*			=>	先删除一下master的二进制文件,避免影响到slave的二进制

# service mysqld start		=>	启动前确保数据目录下的 auto.cnf文件已删除

配置主从数据同步

第一步:在MASTER服务器中创建一个slave同步账号

master服务器执行:

  • 该账号用来同步binlog写入relaylog
# mysql > create user 'slave'@'10.1.1.%' identified by '123';			=>	创建slave同步账号
# mysql > grant replication slave on *.* to 'slave'@'10.1.1.%';			=>	配置权限
# mysql > flush privileges;												=>	刷新权限

第二步:创建一个mha账号(方便后期MHA监控主从同步状态)

master服务器执行:

  • 该账号给mha监控主从同步运行状态的
# mysql > create user 'mha'@'10.1.1.40' identified by '123';			=>	创建mha 监控账号
# mysql > grant all privileges on *.* to 'mha'@'10.1.1.40';				=>	配置权限
# mysql > flush privileges;												=>	刷新权限

第三步:在SLAVE1与SLAVE2中配置主从数据同步

在两台slave 服务器执行:

# mysql > change master to master_host='10.1.1.10',master_port=3306,master_user='slave',master_password='123',master_auto_position=1;
			=>	指定master 主服务器
			
# mysql > start slave;					=>	开启slave
# mysql > show slave status\G			=>	查看slave 开启状态

说明:
# mysql > change master to  
			master_host='10.1.1.10',
			master_port=3306,
			master_user='slave',
			master_password='123',
			master_auto_position=1;

到此整个一主两从配置完毕

MHA软件的安装

不同节点安装软件

四台服务器都要创建MHA的依赖仓库:

# vim /etc/yum.repos.d/mha.repo 
[mha]
name=mha soft
baseurl=file:///soft/mha/mha-yum
enabled=1
gpgcheck=0

先安装mha的依赖:

# mkdir -p /soft/mha/		
# cd /soft/mha/

上传依赖包解压:
	# tar xf mha-yum.tar.gz

安装MHA依赖:
# vim mha.sh
yum -y install perl-DBD-MySQL \
perl-Config-Tiny \
perl-Time-HiRes \
perl-Mail-Sender \
perl-Mail-Sendmail \
perl-MIME-Base32 \
perl-MIME-Charset \
perl-MIME-EncWords \
perl-Params-Classify \
perl-Params-Validate.x86_64 \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
net-tools


运行脚本:
	# sh mha.sh

开始安装mha软件(得先上传工具):

所有节点安装mha-node:
	#l [root@mha ~]# yum –y install mha4mysql-node-0.57-0.el7.noarch.rpm	
	#l [root@master ~]# yum –y install mha4mysql-node-0.57-0.el7.noarch.rpm
	#l [root@slave1 ~]# yum -y install mha4mysql-node-0.57-0.el7.noarch.rpm
	#l [root@slave2 ~]# yum –y install mha4mysql-node-0.57-0.el7.noarch.rpm

mha管理节点再安装mha-manager:
	#l [root@mha ~]# yum –y install mha4mysql-manager-0.57-0.el7.noarch.rpm

配置ssh互信(免密登录)

说明:

  1. 在生产环境中几乎都是禁止root远程登陆服务器的,所以ssh免密码登陆要在admin用户下进行配置,这是处于安全角度考虑出发。

  2. admin用户可以是任意普通用户

  3. 该普通用户用于mha的管理节点远程访问mysql复制组中的所有主机,完成一些其他工作

第一步:在所有机器上创建一个普通账号admin,密码123

所有机器都要创建:

# useradd admin
# echo 123|passwd --stdin admin

第二步:配置mha主机到其他主机的admin用户互信

mha 服务器执行:

疑问:SSH免密只需要拷贝公钥,但是以下代码是把整个.ssh目录拷贝过去了。

答:因为MHA的互信,要求不仅仅是 MHA免密到MASTER、SLAVE1、SLAVE2

  • MASTER也要免密到MHA、SLAVE1、SLAVE2
  • SLAVE1也要免密到MHA、MASTER、SLAVE2
  • SLAVE2也要免密到MHA、MASTER、SLAVE1
  • 相当于所有机器都制作了秘钥对,然后所有主机都可以基于同一对秘钥对实现免密登录
mha端:
	#l [root@mha ~]# su - admin				=>	切换到admin用户
	
	
	#l [admin@mha ~]$ ssh-keygen -P "" -f ~/.ssh/id_rsa		
			=>	admin用户制作秘钥对,-f指定秘钥文件选项有没有都可以,多回车两下也行,因为默认秘钥就是生成在~/.ssh/id_rsa
	
	
	#l [admin@mha ~]$ cd .ssh/		=>	查看生成的秘钥对
	#l [admin@mha .ssh]$ ls
		id_rsa    秘钥
		id_rsa.pub     公钥


	#l [admin@mha .ssh]$ mv id_rsa.pub authorized_keys		
			=>	将公钥更名,因为client端的公钥需要放置在server端的~/.ssh/authorized_keys中


	#l [admin@mha .ssh]$ for i in 10 20 30;do scp -r ~/.ssh/ admin@10.1.1.$i:~/;done		
			=>	mha机器的admin用户将自己的公私钥都发送给master和slave主机的然后追~/.ssh/目录下
				-r 选项针对目录
				

测试免密登录:
[admin@mha .ssh]$ ssh 10.1.1.10
[admin@mha .ssh]$ ssh 10.1.1.20
[admin@mha .ssh]$ ssh 10.1.1.30

在MASTERR和SLAVE1/2配置admin用户的sudo权限

  • VIP 需要绑定到网卡上,所以需要给admin用户sudo的权限
  • admin用户可以执行 ifconfig 和 arping 命令

master 服务器执行:

/etc/sudoers.d/ 目录下创建以连接用户为名称的文件文件:
	#l [root@master ~]# vim /etc/sudoers.d/admin		=>	切换到root用户编写
			User_Alias MYSQL_USERS = admin				
			Runas_Alias MYSQL_RUNAS = root
			Cmnd_Alias MYSQL_CMNDS = /sbin/ifconfig,/sbin/arping
			MYSQL_USERS ALL = (MYSQL_RUNAS) NOPASSWD: MYSQL_CMNDS



选项说明:
	User_Alias:表示具有sudo权限的用户列表
	Host_Alias:表示主机的列表

	Runas_Alias:表示用户以什么身份登录

	Cmnd_Alias:表示允许执行命令的列表(命令需要使用完整路径)

把这个权限分发给SLAVE1与SLAVE2一份(当故障发生时,从服务器也可以自己设置VIP)

#l [root@master ~]# for i in 20 30;do scp /etc/sudoers.d/admin root@10.1.1.$i:/etc/sudoers.d/;done

在MASTER上测试admin用户是否可以挂载VIP(只能在MASTER机器上挂载VIP)

master 服务器执行:

  • 这里设置VIP为:10.1.1.100
#l [root@master ~]# su - admin			=>	切换到admin账号

#l [admin@master ~]$ sudo /sbin/ifconfig ens33:1 10.1.1.100 broadcast 10.1.1.255 netmask 255.255.255.0
		=>	ens33:1  一张网卡可以开启接口绑定多个ip,这条命令指定将ens33网卡的1接口绑定
			"ip:10.1.1.100"  这个是VIP,重启网络就会消失
			"广播地址:10.1.1.255"	根据系统指定
			"掩码:255.255.255.0"	根据系统指定 


#l [admin@master ~]$ sudo /sbin/arping -fqc 5 -w 5 -I ens33 -s 10.1.1.100 -U 10.1.1.10
#l [admin@master ~]$ ip a 

补充:
arping:用来向局域网内的其它主机发送ARP请求的指令,可以用来测试局域网内的某个IP是否已被使用。

-f:收到第一个响应包后退出。
-q:quite模式,不显示输出。 
-c:发送指定的count个ARP REQUEST包后停止。如果指定了-w参数,则会等待相同数量的ARP REPLY包,直到超时为止。
-w:指定一个超时时间,单位为秒,arping在到达指定时间后退出,无论期间发送或接收了多少包。在这种情况下,arping在发送完指定的count(-c)个包后并不会停止,而是等待到超时或发送的count个包都进行了回应后才会退出。 
-I:指定设备名,用来发送ARP REQUEST包的网络设备的名称。
-D:重复地址探测模式,用来检测有没有IP地址冲突,如果没有IP冲突则返回0-s:设置发送ARP包的IP资源地址
-U:无理由的(强制的)ARP模式去更新别的主机上的ARP CACHE列表中的本机的信息,不需要响应。
-h:显示帮助页。 

在MHA上创建mha相关配置文件

MHA服务器:创建工作目录

#l [root@mha ~]# su - root			=>	切换回root创建工作目录
#l [root@mha ~]# mkdir /etc/mha/

#l [root@mha ~]# mkdir -p /data/mha/masterha/app1		
		=>	用于存放这套主从mha的配置文件和运行过程中产生的错误日志以及临时文件等(如果有多套主从还可以增加app2)

#l [root@mha ~]# chown -R admin.admin /data/mha			
		=>	mha后期的运行都是由admin用户操作实现的,所以要更改一下权限

MHA服务器:在工作目录下创建mha局部配置文件:

  • 需要创建一个脚本让mha程序运行起来
  • 这个脚本是官方的,根据自己需求修改就行
  • 修改1:master上创建的mha监控账号密码。用于监控主从的运行状态
  • 修改2:master上创建用于主从复制的slave账号密码
  • 修改3:设置用于ssh免密登录的账号
  • 修改4:设置master binlog的保存目录。当master发生故障会将其binlog拷贝走
  • 修改5:设置master的pid文件。主机名.pid
"[root@mha ~]# vim /etc/mha/app1.conf"


[server default]
# 设置监控用户和密码(修改1)
user=mha
password=123
# 设置复制环境中的复制用户和密码(修改2)
repl_user=slave
repl_password=123
# 设置ssh的登录用户名(修改3)
ssh_user=admin
# 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover,调用脚本切换latest slave
ping_interval=3
# 设置mha的工作目录,根据你创建的工作目录
manager_workdir=/data/mha/masterha/app1
# 设置mysql master保存binlog的目录,以便MHA可以找到master的二进制日志(修改4)
master_binlog_dir=/usr/local/mysql/data
# 设置master的pid文件(修改5)
master_pid_file=/usr/local/mysql/data/master.itcast.cn.pid
# 设置mysql master在发生切换时保存binlog的目录(在mysql master上创建这个目录)
remote_workdir=/data/mysql/mha
# 设置mha日志文件,日志名称随意(MHA遇到问题,主要看这个日志)
manager_log=/data/mha/masterha/app1/app1-3306.log
# MHA到master的监控之间出现问题,MHA Manager将会尝试从slave1和slave2登录到master上(根据实际情况更改指定值)
secondary_check_script=/usr/bin/masterha_secondary_check -s 10.1.1.20 -s 10.1.1.30 --user=admin --port=22 --master_host=10.1.1.10 --master_port=3306
# 设置自动failover时候的切换脚本,根据你具体设置的VIP(故障发生时,自动挂载VIP到SLAVE1或SLAVE2)
master_ip_failover_script="/etc/mha/master_ip_failover.sh 10.1.1.100 1"
# 设置手动切换时候的切换脚本
#master_ip_online_change_script="/etc/mha/master_ip_online_change.sh 10.1.1.100 1"
# 设置故障发生后关闭故障主机脚本
# shutdown_script="/etc/mha/power_manager"
# 以下表示主从服务器IP、各自端口,candidate_master的值等于1代表都有可能成为master服务器
[server1]
hostname=10.1.1.10
port= 3306
candidate_master=1
[server2]
hostname=10.1.1.20
port= 3306
candidate_master=1
[server3]
hostname=10.1.1.30
port= 3306
candidate_master=1

在MHA服务器上,上传相应脚本到的/etc/mha目录,然后更改配置信息,授权

master_ip_failover.sh

  • 该脚本主要在master挂掉后,实现自动failover时候的切换脚本
  • 注意:脚本内容中要修改网卡名字和连接用户为admin(根据实际情况修改)

MHA服务器:

#l [root@mha ~]# cd /etc/mha/		=》	进入到目录下上传脚本


#l [root@mha ~]# vim master_ip_failover.sh		=>	修改
	...
	38 my $interface = 'ens33';			=>	网卡名称是需要修改的(在哪块网卡设置的VIP)
	39 my $key = shift;	
	...
	109 sub stop_vip() {
	110     my $ssh_user = "admin";		=>	连接用户是需要修改的(免密的那个用户)
	111     print "=======$ssh_stop_vip==================\n";
	112     `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
	113 }


#l [root@mha ~]# chmod +x /etc/mha/master_ip_*		=>	赋予执行权限

在MHA上检测SSH互信以及MySQL主从状态

  • 在mha启动前先检测一下

MHA服务器:

#l [root@mha ~]# su - admin		=>	切换到admin


#l [admin@mha ~]$ masterha_check_ssh --conf=/etc/mha/app1.conf		=>	检测SSH互信
#l [admin@mha ~]$ masterha_check_repl --conf=/etc/mha/app1.conf		=>	检测集群状态,主从复制架构是否正常运行

在MHA上检查MHA状态,然后运行MHA(监控开始)

MHA服务器:

检查mha运行状态:
	#l [admin@mha ~]$ masterha_check_status --conf=/etc/mha/app1.conf
			app1 is stopped(2:NOT_RUNNING).			=>	当前关闭状态


开启MHA Manager监控(代表启动MHA):
	#l [admin@mha ~]$ nohup masterha_manager --conf=/etc/mha/app1.conf --remove_dead_master_conf --ignore_last_failover &
			nohup:表示把终端/会话关了依然在后台运行
			&:将命令放到后台运行


再次查看监控状态:
	#l [admin@mha ~]$ masterha_check_status --conf=/etc/mha/app1.conf
			app1 (pid:8913) is running(0:PING_OK), master:10.1.1.10		=>	代表mha启动成功


注意:
1. 如果正常,会显示”PING_OK ”,否则会显示”NOT_RUNNING ”,说明 MHA监控没有开启
2. 使用admin用户启动监控,否则会报权限拒绝
3. 手动停止监控命令:masterha_stop --conf=/etc/mha/app1.conf

到此,MHA就已经配置完毕了!

自动Failover测试

在MASTER服务器安装测试工具

  • sysbench工具可以瞬间往数据库写入几十万甚至上百万随机数据(常用于压力测试)

master 服务器:

#l [root@master ~]# yum -y install sysbench

MASTER数据库插入测试数据

master 服务器:

# mysql > create database test charset utf8mb4;			=>	master服务器上创建测试库test:

# mysql > grant all on *.* to 'mha'@'localhost' identified by '123';		=>	在本地创建一个用于测试的账号
# mysql > flush privileges;
# mysql > exit


sysbench插入随机数据:
#l [root@master ~]# sysbench /usr/share/sysbench/oltp_read_only.lua \
 --mysql-host=10.1.1.10  --mysql-port=3306  --mysql-user=mha \
 --mysql-password=123  --mysql-socket=/tmp/mysql.sock \
 --mysql-db=test  --db-driver=mysql  --tables=1 \
 --table-size=100000 --report-interval=10 --threads=128 --time=120 prepare


选项说明:
	/usr/share/sysbench/oltp_read_only.lua
	--mysql-host:插入的数据库ip
	--mysql-port:数据库端口号
	--mysql-user:哪个数据库账号执行
	--mysql-password:执行账号密码
	--mysql-socket:数据库套接字的路径
	--mysql-db:指定插入数据的数据库名称
	--db-driver:所连接的是哪种数据库(这里连接的是MySQL数据库)
	--tables:创建多少个表
	--table-size:插入多少条测试数据	

模拟MASTER服务器故障

MHA服务器:监控日志

-查看master服务故障mha日志的变化

#l [root@mha ~]# tail -f /data/mha/masterha/app1/app1-3306.log

MASTER服务器:

#l [root@master ~]# service mysqld stop

常见问题

管理节点配置文件错误

  • 有可能是mha的
[root@mha ~]# cat /etc/mha/app1.conf
[server default]
#l 设置监控用户和密码,该用户是master上创建的数据库管理账号,拥有所有权限
	user=mha
	password=123

#l 设置复制环境中的复制用户和密码,注意需要有以下权限:
	repl_user=slave
	repl_password=123

#l 设置ssh的登录用户名
	ssh_user=admin
....

#l	注意:一定要配置正确的IP和端口号
	[server1]
		hostname=10.1.1.10
		port= 3306
		candidate_master=1
	[server2]
		hostname=10.1.1.20
		port= 3306
		candidate_master=1
	[server3]
		hostname=10.1.1.30
		port= 3306
		candidate_master=1

配置MHA时数据只读设置

  • 这种情况一般比较少见
    在这里插入图片描述

解决办法:设置从服务器为只读

# mysql > set @@global.read_only=1;
	Query OK, 0 rows affected (0.00 sec)

# mysql > show variables like 'read_only';
	+---------------+-------+
	| Variable_name | Value |
	+---------------+-------+
	| read_only     | ON    |
	+---------------+-------+
	1 row in set (0.00 sec)

复制用户权限密码错误

在这里插入图片描述
原因:

  1. 复制用户slave没有相关权限,REPLICATION SLAVE和REPLICATION CLIENT
  2. 从服务器没有创建复制用户

其他错误

MHA集群至少需要2个slave,所以如果只有一台slave的话,检查也是通不过的!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值