Mha-Atlas-MySQL高可用
一、MHA简介
1、软件介绍
MHA在MySQL高可用是一个相对成熟的解决方案,是一套优秀的作为mysql高可用
环境下故障切换和主从提升的高可用软件,在MySQL故障切换过程中,
MHA能做到0~30秒内自动完成数据库的故障切换操作,并且在进行故障
切换过程中,MHA能最大程度上保证数据库的一致性,以达到真正意义上的高可用。
2、MHA组成
MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。
MHA Manager可以独立部署在一台独立的机器上管理多个Master-Slave集群,
也可以部署在一台Slave上。当Master出现故障时,它可以自动将最新数据的
Slave提升为新的Master,然后将所有其他的Slave重新指向新的Master。
3、MHA工作流程
①从宕机崩溃的master保存二进制日志时间(binlog events);
②识别含有最近更新的slave;
③应用差异的中继日志(relay log)到其他的slave;
④应用从master保存的二进制日志事件(binlog events);
⑤提升一个slave为新的master;
⑥使其它的slave连接新的master进行复制;
流程详解
1)复制主库binlog日志出来
2)找出relaylog日志最全的从库
3)将最全的relaylog日志在所有从库中同步(第一次同步数据)
4)将之前最全的从库提升为主库
5)将复制出来的binlog日志,放到新提升的主库里
6)其他所有从库重新指向新提升的主库,继续主从复制
4、MHA工具介绍
MHA软件由两部分组成:Manager工具包(管理端)和Node工具包(节点端)
(1)Manager主要包括以下几个工具:
masterha_check_ssh ==>检查MHA的SSH配置状况
masterha_check_repl ==>检查MySQL复制状况
masterha_check_status ==>检测当前MHA运行状态
masterha_master_monitor ==>检测master是否宕机
masterha_manger ==>启动MHA
masterha_master_switch ==>控制故障转移(自动或手动)
masterha_conf_host ==>添加或删除配置的server信息
masterha_secondary_check ==>试图建立TCP连接从远程服务器
masterha_stop ==>停止MHA
(2)Node主要包括以下几个工具:
save_binary_logs ==>保存和复制master的二进制日志
apply_diff_relay_logs ==>识别差异的中继日志事件
filter_mysqlbinlog ==>去除不必要的ROLLBACK事件
purge_relay_logs ==>清除中继日志
二、MHA环境准备
1、准备三台mysql虚拟机
主机名 | IP地址(NAT) | 描述 |
---|---|---|
mysql-db01 | eth0:192.168.200.51 | 系统:CentOS6.5 安装:mysql5.6 |
mysql-db02 | eth0:192.168.200.52 | 系统:CentOS6.5 安装:mysql5.6 |
mysql-db03 | eth0:192.168.200.53 | 系统:CentOS6.5 安装:mysql5.6 |
2、软件包
mha管理节点安装包
mha4mysql-manager-0.56-0.el6.noarch.rpm
mha4mysql-manager-0.56.tar.gz
mha node节点安装包
mha4mysql-nade-0.56-0.el6.noarch.rpm
mha4mysql-node-0.56.tar.gz
mysql中间件
Atlas-2.2.1.el6.x86_64.rpm
mysql源码安装包
mysql-5.6.17-linux-glibc2.5-x86_64tar
3、主机名映射
三台虚拟机,都需要映射三个IP域名
三、MySQL环境准备
三台虚拟机都需要安装MySQL
安装mysql二进制
直接解压即可:解压到/usr/local/
创建用户:
useradd -s /sbin/nologin -M mysql
进入/usr/local/mysql-5.5.32-linux/
做个软连接方便使用==>
ln -s mysql-5.5.32-linux /usr/local/mysql
复制配置文件:
/bin/cp support-files/my-small.cnf /etc/my.cnf
做初始化:
创建mysql数据文件目录==>
mkdir -p /usr/local/mysql/data
授权mysql用户管理mysql的安装目录==>
chown -R mysql.mysql /usr/local/mysql
安装初始化mysql依赖包==>
yum -y install libaio
初始化mysql数据库文件==>
/usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --user=mysql
复制mysql启动脚本到mysql的命令路径==>
cd /usr/local/mysql
cp support-files/mysql.server /etc/init.d/mysqld
加x权限,使脚本可执行==>
chmod +x /etc/init.d/mysqld
启动mysql==>
/etc/init.d/mysqld start
给mysql命令做软连接==>
ln -s /usr/local/mysql/bin/* /usr/local/bin
给mysql添加密码==>
mysqladmin -uroot password '123123'
四、配置GTID主从复制
1、GTID主从复制
自动追踪
2、GTID全局事物标识符
是一个唯一的标识符,他创建并与源服务器(主)上提交的每个事物相关联。
GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识。
3、GTID的新特性
支持多线程复制,每个库有一个单独的(sql线程)
支持启用GTID,无需再知道binlog和POS点,只需知道master的IP/端口/账号密码即可
基于Row复制只保存改变的列,大大节省磁盘空间,网络,内存等
支持把master和slave的相关信息记录在table中,增强可用性。原来是记录在文件里。
支持延迟复制。
4、先决条件
- 主库和从库都要开启binlog
- 主库和从库server-id不同
- 要有主从复制用户
5、主库配置
#修改主库配置文件/etc/my.cnf
[root@mysql-db01 mysql]# cat /etc/my.cnf
[client]
socket = /usr/local/mysql/data/mysql.sock
[mysqld]
lower_case_table_names = 1
default-storage-engine = InnoDB
port = 3306
datadir = /usr/local/mysql/data
character-set-server = utf8
socket = /usr/local/mysql/data/mysql.sock
log_bin = mysql-bin #开启binlog日志
server_id = 1 #设置server_id
innodb_buffer_pool_size = 200M
slave-parallel-workers = 8
thread_cache_size = 600
back_log = 600
slave_net_timeout = 60
max_binlog_size = 512M
key_buffer_size = 8M
query_cache_size = 64M
join_buffer_size = 2M
sort_buffer_size = 2M
query_cache_type = 1
thread_stack = 192K
#重启动MySQL服务
[root@mysql-db01 mysql]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
登录MySQL创建主从复制账号
mysql> grant replication slave on *.* to rep@'192.168.0.%' identified by '123123';
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host from mysql.user;
+------+-------------+
| user | host |
+------+-------------+
| rep | 192.168.0.% |
| root | localhost |
| root | mysql-db01 |
+------+-------------+
3 rows in set (0.00 sec)
mysql> show grants for rep@'192.168.0.%';
+--------------------------------------------------------------------------------------------------------------------------+
| Grants for rep@192.168.0.% |
+--------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'rep'@'192.168.0.%' IDENTIFIED BY PASSWORD '*E56A114692FE0DE073F9A1DD68A00EEB9703F3F1' |
+--------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
6、从库配置
#修改mysql-db02配置文件(和mysql-db01配置文件一致)
#只需要修改server-id = 5选项
[root@mysql-db02 ~]# cat /etc/my.cnf
[client]
socket = /usr/local/mysql/data/mysql.sock
[mysqld]
lower_case_table_names = 1
default-storage-engine = InnoDB
port = 3306
datadir = /usr/local/mysql/data
character-set-server = utf8
socket = /usr/local/mysql/data/mysql.sock
log_bin = mysql-bin #从binlog也要打开
server_id = 5 #仅需修改此项
innodb_buffer_pool_size = 200M
slave-parallel-workers = 8
thread_cache_size = 600
back_log = 600
slave_net_timeout = 60
max_binlog_size = 512M
key_buffer_size = 8M
query_cache_size = 64M
join_buffer_size = 2M
sort_buffer_size = 2M
query_cache_type = 1
thread_stack = 192K
[root@mysql-db02 ~]# /etc/init.d/mysqld restart #重启mysql
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
#修改mysql-db03配置文件(和mysql-db01配置文件一致)
#只需要修改server-id = 10选项
[root@mysql-db03 ~]# cat /etc/my.cnf
[client]
socket = /usr/local/mysql/data/mysql.sock
[mysqld]
lower_case_table_names = 1
default-storage-engine = InnoDB
port = 3306
datadir = /usr/local/mysql/data
character-set-server = utf8
socket = /usr/local/mysql/data/mysql.sock
log_bin = mysql-bin #从binlog也要打开
server_id = 10 #只需修改此项
innodb_buffer_pool_size = 200M
slave-parallel-workers = 8
thread_cache_size = 600
back_log = 600
slave_net_timeout = 60
max_binlog_size = 512M
key_buffer_size = 8M
query_cache_size = 64M
join_buffer_size = 2M
sort_buffer_size = 2M
query_cache_type = 1
thread_stack = 192K
[root@mysql-db03 ~]# /etc/init.d/mysqld restart #重启mysql
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
特别提示:
在以往如果是基于binlog日志的主从复制,则必须要记住主库的master状态信息。
7、开启GTID
查看gtid开没开—>在mysql里输入:
show global variables like '%gtid%'
开启gtid需要在mysql配置文件里[mysqld]模块添加三行代码(三台服务器都需要添加)
gtid_mode = ON
log_slave_updates
enforce_gtid_consistency
修改完配置文件以后重启动数据库
[root@mysql-db01 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@mysql-db02 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@mysql-db03 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
再次查看GTID状态
mysql> show global variables like '%gtid%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | enforce_gtid_consistency | ON | #执行GTID一致 | gtid_executed | | | gtid_mode | ON | #开启GTID模块 | gtid_owned | | | gtid_purged | | +--------------------------+-------+ 5 rows in set (0.00 sec)
8、配置主从复制(mysql-db02,mysql-db03)
mysql> change master to
-> master_host='192.168.0.51', #主库IP
-> master_user='rep', #主库复制用户
-> master_password='123123', #主库复制用密码
-> master_auto_position=1; #GTID位置点(自动追踪需要同步的position)
Query OK, 0 rows affected, 2 warnings (0.00 sec)
9、开启从库的主从复制功能(mysql-db02,mysql-db03)
mysql> start slave; #开启主从同步功能
Query OK, 0 rows affected, 1 warning (0.01 sec)
登录mysql输入show slave statusG
查看状态是否IO线程和SQL线程为yes
10、禁止数据库自动删除中继(relaylog)日志,mysql-db02,mysql-db03都需要添加
编辑配置文件/etc/my.cnf
在[mysql]模板下增加relay_log_purge =0永久禁用自动删除relaylog功能
重启mysql==>/etc/init.d/mysqld restart
重启MySQL服务
[root@mysql-db02 ~]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS! [root@mysql-db03 ~]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS!
五、部署MHA
1、所有节点mysql-db01,mysql-db02,mysql-db03
安装依赖包
yum -y install perl-DBD-MySQL
rpm安装node节点包
rpm -ivh mha4mysql-node-0.56-0.e16.noarch.rpm
MHA需要一个管理账号,登录mysql输入如下代码
grant all privileges on *.* to mha@'192.168.200.%' identified by '123123'
2、部署管理节点(mha-manager)
manager管理端的包不能安装在主库上,安装一个管理端
安装manager依赖包(需要公网源)
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
wget -O /etc/yum.repos.d/epel-6.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum -y install perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
createrepo -v . ==>安装当前文件内所有rpm包
安装manager包
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
创建配置文件目录
mkdir -p /etc/mha
创建日志目录
mkdir -p /var/log/mha/mha1
进入cd /etc/mha创建第一个mha配置文件==>vim /etc/mha/mha1.cnf
[server default]
manager_log=/var/log/mha/mha1/manager ==>manager管理日志存放路径
manager_workdir=/var/log/mha/mha1 ==>manager管理日志的目录路径
master_binlog_dir=/usr/local/mysql/data ==>binlog日志的存放路径
user=mha ==>管理账户
password=123123 ==>管理账户密码
ping_interval=2 ==>存活检查的间隔时间
repl_user=rep ==>主从复制的授权账户
repl_password=123123 ==>主从复制的授权账户密码
ssh_user=root ==>用于ssh连接的账户
[server1] ==>第一台服务器信息
hostname=192.168.200.51
port=3306
[server2] ==>第二台服务器信息
#candidate_master=1 ==>强制将此master提升为主库
#check_repl_delay=0 ==>暂时注释自己试验什么意思
hostname=192.168.200.52
port=3306
[server3] ==>第三台服务器信息
hostname=192.168.200.53
port=3306
特别说明:
参数:candidate_master=1
解释:设置为候选master,如果设置该参数以后,发生主从切换以后会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
参数:check_repl_delay=0
解释:默认情况下如果一个slave落后master 100M的relay logs 的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
3、配置ssh信任开始分发免秘钥(所有节点mysql-db01,mysql-db02,mysql-db03)
每台服务器都要创建秘钥对
ssh-keygen -t -P "" -f ~/.ssh/id_dsa
发送mysql-db03公钥,包括自己
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.51
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.52
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.53
发送mysql-db02公钥,包括自己
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.51
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.52
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.53
发送mysql-db01公钥,包括自己
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.51
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.52
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.200.53
4、启动检测
ssh检查命令
masterha_check_ssh --conf=/etc/mha/mha1.cnf
Tue Sep 5 03:01:40 2017 - [debug] Connecting via SSH from root@192.168.0.53(192.168.0.53:22) to root@192.168.0.52(192.168.0.52:22)..
Tue Sep 5 03:01:40 2017 - [debug] ok.
Tue Sep 5 03:01:40 2017 - [info] All SSH connection tests passed successfully. #出现这个就表示成功
主从复制检测
masterha_check_repl --conf=/etc/mha/mha1.cnf
因此在mysql-db02和mysql-db03上添加主从复制的用户即可。
grant replication slave on *.* to rep@'192.168.200.%' identified by '123123';
再次检查
5、启动MHA
nohup masterha_manager --conf=/etc/mha/mha1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/mha1/manager.log 2>&1 &
ps -ef | grep perl
nohup 启动命令
--conf 指定配置文件位置
--remove_dead_master_conf 如果有master down了,就去掉配置文件里该master的部分
六、MHA故障还原
1、将故障宕机的mysql-master的MySQL服务启动并授权进行从同步
[root@localhost .ssh]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS!
[root@localhost .ssh]# mysql -uroot -p123123
mysql> CHANGE MASTER TO MASTER_HOST='192.168.200.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1,MASTER__USER='rep', MASTER_PASSWORD='123123';
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show slave statusG
2、将mha配置文件里缺失的部分补全(管理端)
[root@localhost ~]# vim /etc/mha/mha1.cnf
[server default]
manager_log=/var/log/mha/mha1/manager
manager_workdir=/var/log/mha/mha1
master_binlog_dir=/usr/local/mysql/data
password=111111
ping_interval=2
repl_password=111111
repl_user=rep
ssh_user=root
user=mha
[server1] #补全
hostname=192.168.200.51
port=3306
[server2]
hostname=192.168.200.52
port=3306
[server3]
hostname=192.168.200.53
port=3306
3、启动mha进程(管理端)
[root@localhost ~]# nohup masterha_manager --conf=/etc/mha/mha1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/mha1/manager.log 2>&1 &
[root@localhost ~]# ps -ef | grep perl | grep -v grep
七、MHA的VIP漂移
当MHA切换主库时,VIP会发生漂移,这时IP在开发端就会发生变化
1、IP漂移的两种方式
通过keepalived的方式,管理虚拟IP的漂移
通过MHA自带脚本方式,管理虚拟IP的漂移
2、MHA脚本管理方式
获取管理脚本master_ip_failover
提示:yum安装的manager是没有这个脚本的,
我们需要从manager的源码包里复制一个
cp master_ip_failover /usr/local/bin/
which master_ip_failover
使漂移脚本在mha脚本里面认识,可识别
在mha配置文件里/etc/mha/mha1.cnf添加
vim /etc/mha/mha1.cnf
[server default]
manager_log=/var/log/mha/mha1/manager
manager_workdir=/var/log/mha/mha1
master_binlog_dir=/usr/local/mysql/data 下添加如下代码
master_ip_failover_script=/usr/local/bin/master_ip_failover ==>添加脚本位置
在master_ip_failover脚本里修改如下内容
vim /usr/local/bin/master_ip_failover第34到37行
my $vip = '192.168.200.60/24'; #定义VIP
my $key = '0'; #定义网卡后缀数值,如果是eth0就是0,如果是eth1就是1
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; #绑定VIP的命令
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; #关闭VIP的命令
重启动mha管理端
pkill perl
nohup masterha_manager --conf=/etc/mha/mha1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/mha1/manager.log 2>&1 &
ps -ef | grep perl
八、安全
主库宕机,也许会造成主库binlog复制不及时而导致数据丢失的情况出现,
因此配置binlog-server进行时时同步备份,是必要的一种安全手段
配置binlog-server备份服务器
修改mha配置文件
vim /etc/mah/mha1.cnf
在server模块下
添加[binlog1]模块
[binlog1] #添加binlog模块
no_master=1 #不允许切换为主
hostname=192.168.200.53 #存放当前IP
master_binlog_dir=/data/mysql/binlog/ #binlog存放位置优先级比全局高
创建mkdir -p /data/mysql/binlog/目录
拉取主库上的binlog日志
cd /data/mysql/binlog
which mysqlbinlog
mysqlbinlog -R --host=192.168.200.60 --user=mha --password=123123 --raw --stop-never mysql-bin.000001 &