从零开始部署MHA以及相关MHA原始脚本定制

25 篇文章 0 订阅
15 篇文章 0 订阅

从零开始部署MHA以及相关MHA原始脚本定制

近期公司要做mysql数据库的高可用,通过前期调研了主从+heartbeat,MHA,PXC三个类型的方案,也结合了当前公司的技术能力和业务情况吗,最终是选择了MHA来作为高可用的方案。

MHA的介绍

直接借用MHA作者Yoshinori Matsunobu的github的介绍就不自己描述了,Yoshinori Matsunobu是个大神 现在在Facebook。

MHA performs automating master failover and slave promotion with minimal downtime, usually within 10-30 seconds. MHA prevents replication consistency problems and saves on expenses of having to acquire additional servers. All this with zero performance degradation, no complexity (easy-to-install) and requiring no change to existing deployments.

MHA also provides scheduled online master switching, safely changing the currently running master to a new master, within mere seconds (0.5-2 seconds) of downtime (blocking writes only).

MHA provides the following functionality, and can be useful in many deployments in which high availability, data integrity and near non-stop master maintenance are required.

Automated master monitoring and failover
MHA can monitor MySQL masters in an existing replication environment, performing automatic master failover upon detection of master failure. MHA guarantees the consistency of all the slaves by identifying differential relay log events from the most current slave and applying them to all the other slaves, including those slaves which still haven't received the latest relay log events. MHA can normally perform failover in a matter of seconds: 9-12 seconds to detect master failure, optionally 7-10 seconds to power off the master machine to avoid split brain, and a few seconds to apply differential relay logs to the new master. Total downtime is normally 10-30 seconds. A specific slave can be designated as a candidate master (setting priorities) in a configuration file. Since MHA maintains consistency between slaves, any slave can be promoted to become the new master. Consistency problems, which would ordinarily cause sudden replication failure, will not occur.

Interactive (manually initiated) Master Failover
MHA can be configured for manually initiated (non-automatic), interactive failover, without monitoring the master.

Non-interactive master failover
Non-interactive, automatic master failover without monitoring the master is also supported. This feature is especially useful when MySQL master software monitoring is already in use. For example, you can use Pacemaker(Heartbeat) for detecting master failure and virtual IP address takeover, while using MHA for master failover and slave promotion.

Online switching master to a different host
It is often necessary to migrate an existing master to a different machine, like when the current master has H/W RAID controller or RAM problems, or when you want to replace it with a faster machine, etc. This is not a master crash, but scheduled master maintenance is required. Scheduled master maintenance should be done as quickly as possible, since it entails partial downtime (master writes are disabled). On the other hand, you should block/kill current running sessions very carefully because consistency problems between different masters may occur (i.e "updating master1, updating master 2, committing master1, getting error on committing master 2" will result in data inconsistency). Both fast master switch and graceful blocking writes are required.

MHA provides graceful master switching within 0.5-2 seconds of writer blockage. 0.5-2 seconds of writer downtime is often acceptable, so you can switch masters even without allocating a scheduled maintenance window. Actions such as upgrading to higher versions, faster machine, etc. become much easier.

这一部分就不多说了,具体你可以去github的wiki中慢慢看,社区里也有很多文章来描述。

MHA的恢复原理

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Phase 1: Configuration Check Phase
init_config(): 初始化配置
MHA::ServerManager::init_binlog_server: 初始化binlog server
check_settings()
	a. check_node_version(): 查看MHA的版本
	b. connect_all_and_read_server_status(): 检测确认各个Node节点MySQL是否可以连接
	c. get_dead_servers(),get_alive_servers(),get_alive_slaves():再次检测一次node节点的状态
	d. print_dead_servers(): 是否挂掉的master是否是当前的master
	e. MHA::DBHelper::check_connection_fast_util : 快速判断dead server,是否真的挂了,如果ping_type=insert,不会double check
	f. MHA::NodeUtil::drop_file_if($_failover_error_file|$_failover_complete_file): 检测上次的failover文件
	g. 如果上次failover的时间在8小时以内,那么这次就不会failover,除非配置了额外的参数
	h. start_sql_threads_if(): 查看所有slave的Slave_SQL_Running是否为Yes,若不是则启动SQL thread
	is_gtid_auto_pos_enabled(): 判断是否是GTID模式
Phase 2: Dead Master Shutdown Phase..
	force_shutdown($dead_master):
	a. stop_io_thread(): stop所有slave的IO_thread
	b. force_shutdown_internal($dead_master):
		  b_1. master_ip_failover_script: 如果有这个脚本,则执行里面的逻辑(比如:切换vip)
		  b_2. shutdown_script:如果有这个脚本,则执行里面的逻辑(比如:Power off 服务器)
Phase 3: Master Recovery Phase..
	Phase 3.1: Getting Latest Slaves Phase..
	* check_set_latest_slaves()
		  a. read_slave_status(): 获取所有show slave status 信息
		  b. identify_latest_slaves(): 找到最新的slave是哪个
		  c. identify_oldest_slaves(): 找到最老的slave是哪个
	Phase 3.2: Saving Dead Master's Binlog Phase..
		* save_master_binlog($dead_master);
		  -> 如果dead master可以ssh,那么
		       b_1_1. save_master_binlog_internal: 用node节点save_binary_logs脚本拷贝相应binlog到manager
		           diff_binary_log 生产差异binlog日志
		       b_1_2. file_copy: 将差异binlog拷贝到manager节点的 manager_workdir目录下
		  -> 如果dead master不可以ssh
		       b_1_3. 那么差异日志就会丢失
	Phase 3.3: Determining New Master Phase..
	b. 如果GTID auto_pos没有打开,调用find_latest_base_slave()
	    b_1. find_latest_base_slave_internal: 寻找拥有所有relay-log的最新slave,如果没有,则failover失败
	            b_1_1. find_slave_with_all_relay_logs:
	                    b_1_1_1. apply_diff_relay_logs: 查看最新的slave是否有其他slave缺失的relay-log
	
	c. select_new_master: 选举new master
	    c_1. MHA::ServerManager::select_new_master:
	       #If preferred node is specified, one of active preferred nodes will be new master.
	       #If the latest server behinds too much (i.e. stopping sql thread for online backups), we should not use it as a new master, but we should fetch relay log there
	       #Even though preferred master is configured, it does not become a master if it's far behind
	
	       get_candidate_masters(): 获取配置中候选节点
	       get_bad_candidate_masters(): 以下条件不能成为候选master
	           # dead server
	           # no_master >= 1
	           # log_bin=0
	           # oldest_major_version=0
	           # check_slave_delay: 检查是否延迟非常厉害(可以通过设置no_check_delay忽略)
	               {Exec_Master_Log_Pos} + 100000000 只要binlog position不超过100000000 就行
	       选举流程: 先看candidate_master,然后找 latest slave, 然后再随机挑选
	Phase 3.3(3.4): New Master Diff Log Generation Phase..
	* recover_master_internal
	         recover_relay_logs:
	               判断new master是否为最新的slave,如果不是,则生产差异relay logs,并发送给新master
	         recover_master_internal:
	               将之前生产的dead master上的binlog传送给new master
	Phase 3.4: Master Log Apply Phase..
	* apply_diff:
	       a. wait_until_relay_log_applied: 直到new master完成所有relay log,否则一直等待
	       b. 判断Exec_Master_Log_Pos == Read_Master_Log_Pos, 如果不等,那么生产差异日志:
	                   save_binary_logs --command=save
	       c. apply_diff_relay_logs --command=apply:对new master进行恢复
	                   c_1. exec_diff:Exec_Master_Log_Pos和Read_Master_Log_Pos的差异日志
	                   c_2. read_diff:new master与lastest slave的relay log的差异日志
	                   c_3. binlog_diff:lastest slave与daed master之间的binlog差异日志
	* 如果设置了master_ip_failover_script脚本,那么会执行这里面的脚本(一般用来漂移vip)
	
	* disable_read_only(): 允许new master可写
Phase 4: Slaves Recovery Phase..
	recover_slaves_internal
	
	Phase 4.1: Starting Parallel Slave Diff Log Generation Phase..
		recover_all_slaves_relay_logs: 生成Slave与New Slave之间的差异日志,并将该日志拷贝到各Slave的工作目录下
	Phase 4.2: Starting Parallel Slave Log Apply Phase..
		* recover_slave:
		    对每个slave进行恢复,跟以上Phase 3.4: Master Log Apply Phase中的 apply_diff一样
		* change_master_and_start_slave:
		    重新指向到new master,并且start slave
Phase 5: New master cleanup phase..
	reset_slave_on_new_master
	在new master上执行reset slave all;

在这里插入图片描述

Phase 1: Configuration Check Phase
	init_config(): 初始化配置
	MHA::ServerManager::init_binlog_server: 初始化binlog server
	check_settings()
		a. check_node_version(): 查看MHA的版本
		b. connect_all_and_read_server_status(): 检测确认各个Node节点MySQL是否可以连接
		c. get_dead_servers(),get_alive_servers(),get_alive_slaves():再次检测一次node节点的状态
		d. print_dead_servers(): 是否挂掉的master是否是当前的master
		e. MHA::DBHelper::check_connection_fast_util : 快速判断dead server,是否真的挂了,如果ping_type=insert,不会double check
		f. MHA::NodeUtil::drop_file_if($_failover_error_file|$_failover_complete_file): 检测上次的failover文件
		g. 如果上次failover的时间在8小时以内,那么这次就不会failover,除非配置了额外的参数
		h. start_sql_threads_if(): 查看所有slave的Slave_SQL_Running是否为Yes,若不是则启动SQL thread
	is_gtid_auto_pos_enabled(): 判断是否是GTID模式
Phase 2: Dead Master Shutdown Phase completed.
	force_shutdown($dead_master):
		a. stop_io_thread(): stop所有slave的IO_thread
		b. force_shutdown_internal($dead_master):
		  b_1. master_ip_failover_script: 如果有这个脚本,则执行里面的逻辑(比如:切换vip)
		  b_2. shutdown_script:如果有这个脚本,则执行里面的逻辑(比如:Power off 服务器)
Phase 3: Master Recovery Phase..
	Phase 3.1: Getting Latest Slaves Phase..
		* check_set_latest_slaves()
			  a. read_slave_status(): 获取所有show slave status 信息
			  b. identify_latest_slaves(): 找到最新的slave是哪个
			  c. identify_oldest_slaves(): 找到最老的slave是哪个
	Phase 3.2: Saving Dead Master's Binlog Phase.. (GTID 模式下没有这一步)
	Phase 3.3: Determining New Master Phase..
		get_most_advanced_latest_slave(): 获取最新的slave
	
	c. select_new_master: 选举new master
	    c_1. MHA::ServerManager::select_new_master:
	       #If preferred node is specified, one of active preferred nodes will be new master.
	       #If the latest server behinds too much (i.e. stopping sql thread for online backups), we should not use it as a new master, but we should fetch relay log there
	       #Even though preferred master is configured, it does not become a master if it's far behind
	
	       get_candidate_masters(): 获取配置中候选节点
	       get_bad_candidate_masters(): 以下条件不能成为候选master
	           # dead server
	           # no_master >= 1
	           # log_bin=0
	           # oldest_major_version=0
	           # check_slave_delay: 检查是否延迟非常厉害(可以通过设置no_check_delay忽略)
	               {Exec_Master_Log_Pos} + 100000000 只要binlog position不超过100000000 就行
	       选举流程: 先看candidate_master,然后找 latest slave, 然后再随机挑选
	
	Phase 3.3: New Master Recovery Phase..
		* recover_master_gtid_internal:
		    wait_until_relay_log_applied: 候选master等待所有relay-log都应用完
		    如果候选master不是最新的slave:
		        $latest_slave->wait_until_relay_log_applied($log): 最新的slave应用完所有的relay-log
		        change_master_and_start_slave : 让候选master同步到latest master,追上latest slave
		        获取候选master此时此刻的日志信息,以便后面切换
		    如果候选master是最新的slave:
		        获取候选master此时此刻的日志信息,以便后面切换
		    save_from_binlog_server:
		        如果配置了binlog server,那么在binlogsever 能连的情况下,将binlog 拷贝到Manager,并生成差异日志diff_binlog(save_binary_logs --command=save)
		    apply_binlog_to_master:
		        Applying differential binlog: 应用差异的binlog到new master

Phase 4: Slaves Recovery Phase..
	Phase 4.1: Starting Slaves in parallel..
		* recover_slaves_gtid_internal:
		    change_master_and_start_slave: 因为master已经恢复,那么slave直接change master auto_pos=1 的模式就可以恢复
		    gtid_wait:用此等待同步全部追上
Phase 5: New master cleanup phase..
	reset_slave_on_new_master
	在new master上执行reset slave all;

这里也是直接引用MySQL Master High Available 源码篇的文章信息 ,在此感谢作者的分享。
多说一句,MHA0.56版本以后就开始支持mysql GTID了,我之后说的也是这种方案。

安装MHA

MHA由perl编写,分为两部分组件

一个是MHA Node,里面的组件:
    save_binary_logs                保存和复制master的二进制日志
	apply_diff_relay_logs           识别差异的中继日志事件并将其差异的事件应用于其他的slave
	filter_mysqlbinlog              去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
	purge_relay_logs                清除中继日志(不会阻塞SQL线程)
一个是MHA Manager,里面包含很多组件:
	masterha_check_ssh              检查MHA的SSH配置状况
	masterha_check_repl             检查MySQL复制状况
	masterha_manger                 启动MHA
	masterha_check_status           检测当前MHA运行状态
	masterha_master_monitor         检测master是否宕机
	masterha_master_switch          控制故障转移(自动或者手动)
	masterha_conf_host              添加或删除配置的server信息

MHA Node是要在每一个mysql复制组内的服务器上都要安装的,而MHA Manage可以安装在任意能和复制组通信的服务器上,当然也包括复制组内的某个机器。

安装方式 RPM Or Source

RHEL/CentOS 使用rpm安装:

yum install perl-DBD-MySQL
yum install perl-Config-Tiny
yum install perl-Log-Dispatch
yum install perl-Parallel-ForkManager
rpm -ivh mha4mysql-node-X.Y-0.noarch.rpm
rpm -ivh mha4mysql-manager-X.Y-0.noarch.rpm

Source安装:

## Install DBD::mysql if not installed

## Install dependent Perl modules
# MHA Node (See above)
# Config::Tiny
## perl -MCPAN -e "install Config::Tiny"
# Log::Dispatch
## perl -MCPAN -e "install Log::Dispatch"
# Parallel::ForkManager 
## perl -MCPAN -e "install Parallel::ForkManager"
## Installing MHA Node
$ tar -zxf mha4mysql-node-X.Y.tar.gz
$ perl Makefile.PL
$ make
$ sudo make install
## Installing MHA Manager
$ tar -zxf mha4mysql-manager-X.Y.tar.gz
$ perl Makefile.PL
$ make
$ sudo make install

推荐用rpm 个人习惯问题。

MHA脚本定制 划重点,拿小本本记下来

这里有几个脚本:
在这里插入图片描述

MHA的配置文件

首先说masterha_default.conf是MHA的全局配置文件,所有公共配置都可以写到这里面 比如机器的账户 失败检测的心跳时间 master_ip_failover_script的路径等等,也就是所有的MHA进程都会共用这里的配置。
我配置的如下:

[server default]
#监控
ping_interval=3
#shutdown_script=""
report_script=/home/SendEmail.sh
#切换调用的脚本
master_ip_failover_script= /etc/masterha/master_ip_failover
master_ip_online_change_script= /etc/masterha/master_ip_online_change

接下来说App1.conf这个文件 为啥是app1呢?因为一个mha可以管理多个复制组 每个复制组都有自己的app.conf文件 所以是app1,app2,app3等等
我的配置:

[server default]
manager_log=/var/log/masterha/app1/app1.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/data/mysql/mysql3306/logs
password=123456
repl_password=123456
repl_user=repl_user
report_script=/home/SendEmail.sh
ssh_user=root
user=mysqluser

[server3]
check_repl_delay=0
hostname=192.168.*
ignore_fail=1

[server3]
check_repl_delay=0
hostname=192.168.*
ignore_fail=1

[server4]
check_repl_delay=0
hostname=192.168.*
ignore_fail=1

[binlog1]
hostname=192.168.*
master_binlog_dir=/data/mysql/mysql3306/logs/
no_master=1

这里解释下配置的含义和为啥我这么配置
首先这些配置

master_binlog_dir=/data/mysql/mysql3306/logs
user=mysqluser  ----mysql超级账户
password=123456
repl_password=123456  ----复制账户
repl_user=repl_user
ssh_user=root ----ssh账户

是一个复制组独有的 如果能保证MHA管理的多个复制组都是一样的账户一样的密码 那就可以放到全局参数里了 没必要到处写 修改的时候也方便统一修改,为啥我没有放在全局配置里 因为我们线上环境不统一 是各个产品自行维护的mysql 所以账户都不一样 故我是在app级别配置的 之后统一后转移到全局配置中。
接下来说下[binlog1]这个节点,使用0.56之前的版本是没有这个参数的,这个是为了支持GTID的,具体可以参考mysql5.6基于GTID模式之高可用架构搭建-MHA(mha0.56)MHA failover GTID 专题等,这里说下,gtid的补偿日志机制跟非gtid是有所不同的,所以配置[binlog1]是必须的,我这里直接配置的主服务的ip并且binlog存放的物理目录直接指向了实际msater mysql的binlog文件所在的目录下了 也就是并没有搭建mysqlbinlog服务器,但是这中配置方式已经通过场景测试得出结论 一旦主库所在的服务器down机或者无法通过ssh连接了,差异日志是获取不到也就是无法补偿到新的master上的。
参数解释,这里直接引用吴老师的文章吴炳锡-MHA 参数列表详解:感谢吴老师分享。

MHA 参数列表
Local : 指每一个配置块内部。 Local功能的参数需要放置在[server_xxx] 块下面
App : 参数作用于master/slave, 这些参数需要配置在[server_default]块的下面
Global : 作用于master/slave, Global级别的参数用于管理多组master/slave结构,可以统一化管理一些参数。 
hostname
配置MySQL服务器的机器名或是IP地址,这个配置项是必须的,而且只能配置在[server_xxx]这个块下面。
如:

参数名	是否必须	作用域	默认值	例子及说明
hostname	Yes	Local Only	–	hostname=mysql_server1, hostname=192.168.0.1, etc
ip
MySQL服务器的ip地址。 默认从gethostname($hostname)中获得。 默认不用配置这个参数,MHA可以通过hostname自动获取,MHA通过IP地址连接MySQL服务器及SSH连接。
如:

参数名	是否必须	作用域	默认值	例子及说明
ip	No	Local Only	通过gethostbyname($hostname)获得	ip=192.168.1.3
port
MySQL运行的端口号。 默认是3306. MHA使用IP和端口号连接MySQL
如:

参数名	是否必须	作用域	默认值	例子及说明
port	No	Local/App/Glbal	3306	port=3306
ssh_host
(从MHA 0.53后开始支持) MHA要ssh上MySQL目标服务器使用hostname 或是ip地址。这个参数主要用于在使用多个VLAN的环境中。为了安全原因ssh默认不允许。默认这个参数和hostname相同。

如:

参数名	是否必须	作用域	默认值	例子及说明
ssh_host	No	Local Only	和hostname相同	ssh_host=mysql_server1, ssh_host=192.168.0.1, etc
ssh_ip
(从MHA 0.53后开始支持) 和ssh_host作用相同。 默认是gethostname($ssh_host)获得。 

如:

参数名	是否必须	作用域	默认值	例子及说明
ssh_ip	No	Local Only	gethostbyname($ssh_host)	ssh_ip=192.168.1.3
ssh_port
(从MHA 0.53后开始支持) SSH使用的端口号,默认是22.
如:

参数名	是否必须	作用域	默认值	例子及说明
ssh_port	No	Local/App/Global	22	ssh_port=22
ssh_connection_timeout
(从MHA 0.54后支持)默认是5秒。在没添加这个参数之前ssh超时时间是写死的。
如:

参数名	是否必须	作用域	默认值	例子及说明
ssh_connection_timeout	No	Local/App/Global	5	ssh_connect_timeout=5
ssh_options
(从MHA 0.53后支持) 添加ssh命令行的支持参数,例如加上特别文件名的key的支持等。

如:

参数名	是否必须	作用域	默认值	例子及说明
ssh_options	No	Local/App/Global	“” 空的	ssh_options=”-i /root/.ssh/id_dsa2″
candidate_master
你可能对于同一组slave中有着不同的规划,有的其望在Master故障时,提升为新的Master(如: Raid1的slave比Raid0的slave更适合做Master)

这个参数的作用是当设计candidate_master = 1时,这个服务器有较高的优先级提升为新的master(还要具备: 开启binlog, 复制没有延迟)。 所以当设置了candidate_master = 1的机器在master故障时必然成为新的master. 但这是很有用的设置优先级的一个参数。

如果设置了多台机器的caddidate_master = 1 , 优先策略依赖于块名字([server_xxx]). [server_1] 优衔权高于[server_2].

如:

参数名	是否必须	作用域	默认值	例子及说明
candidate_master	No	Local Only	0	candidate_mast=1
no_master
当设置了no_master = 1的服务器,这个服务器永远不会提升为新的master. 这个参数据对于永远不期望成为master的机器很有用。 如: 你可能需要在使用raid0的机器上设置no_master = 1 或是你希望在远程的idc里运行一个slave. 注意: 当没有可以成为新master的机器是MHA就直接退出来了同时停止监控和master故障切换。

如:

参数名	是否必须	作用域	默认值	例子及说明
no_master	No	Local Only	0	no_master=1
ignore_fail
在默认情况下,MHA manager不会在slave存在故障的情况下(已经不能通过SSH/MySQL进行连接,或是SQL Thread已经停止出错,其它原因)的情况下进行Master的故障切换(当不存在slave时MHA manager也会退出)。 但有些情况下你期望在slave存在问题的情况下,也进行故障切换。 所以当设置了ignore_fail = 1时,MHA会在所有的机器有问题的时间也会进行故障切换。 默认是0.

如:

参数名	是否必须	作用域	默认值	例子及说明
ignore_fail	No	Local Only	0	ignore_fail=1
#skip_init_ssh_check#
在MHA manager启动时跳过ssh检查。

如:

参数名	是否必须	作用域	默认值	例子及说明
skip_init_ssh_check	No	Local Only	0	skip_init_ssh_check=1
skip_reset_slave
(从MHA 0.56开始支持) Master故障切换后新的master上执行RESET SLAVE(ALL).

如:

参数名	是否必须	作用域	默认值	例子及说明
skip_reset_slave	No	Local/App/Global	0	skip_reset_slave=1
user
用于管理MySQL的用户名。这个最后需要root用户,因为它需要执行:stop slave; change master to , reset slave. 默认: root

如:

参数名	是否必须	作用域	默认值	例子及说明
user	No	Local/App/Global	root	user=mysql_root
password
MySQL的管理用户的密码。 默认是空的

如:

参数名	是否必须	作用域	默认值	例子及说明
password	No	Local/App/Global	空的	password=rootpass
repl_user
MySQL用于复制的用户,也是用于生成CHANGE MASTER TO 每个slave使用的用户。 这个用户必须有REPLICATION SLAVE权限在新的Master上。默认情况下 repl_user会在将来成为master的机器上运行show slave status获取到。

如:

参数名	是否必须	作用域	默认值	例子及说明
repl_user	No	Local/App/Global	从show slave status	repl_user=repl
repl_password
MySQL中repl_user用户的密码。 默认是当前复制用的密码。  当你使用online_master_switch时,当使用–orig_master_is_new_slave(原来的Master成为新Master的一个slave)时,如果没有repl_password 开启同步就会失败了。因为当前master上用于复制的用户名和密码都是空的(MHA在原来的Master上执行change master to 时没有带复制的密码,虽然其它slave上设置了复制的密码)

如:

参数名	是否必须	作用域	默认值	例子及说明
repl_password	No	Local/App/Global	当前复制用的密码	repl_password=replpas
disable_log_bin
当设置了这个参数,在slave应用差异的relay log时不会产生二进制日志。 内部实现通过mysqlbinlog的disable-log-bin实现。

如:

参数名	是否必须	作用域	默认值	例子及说明
disable_log_bin	No	Local/App/Global	0	disable_log_bin=1
master_pid_file
指定MySQL的pid文件。 这个参数在一台服务器上运行多个MySQL服务进程时非常有用。

如:

参数名	是否必须	作用域	默认值	例子及说明
master_pid_file	No	Local/App/Global	–	master_pid_file=/var/lib/mysql/master1.pid
ssh_user
MHA Mananger, MHA node系统上的用户。 这个帐号需要在远程机器上有执行权限(Manager->MySQL),在slave成员之间复制差异的relay-log(MySQL->MySQL)

这个用户必须有读取MySQL的binary/relay日志和relay_log.info的权限,还需要对远程MySQL上remote_workdir目录的写权限。

这个用户还必须可以直接ssh到远程机顺上, 推荐使用ssh pbulic key . 一般使用的ssh_user也是运行manager那个那个用户。

如:

参数名	是否必须	作用域	默认值	例子及说明
ssh_user	No	Local/App/Global	当前使用的系统用户	ssh_user=root
remote_workdir
MHA node上工作目录的全路径名。如果不存在,MHA node会自动创建,如果不允许创建,MHA Node自动异常退出。 需要注意MHA manager 或是MHA node上需要检查空间是否可用,所以需要注意检查这个。 一般默认, remote_workdir是的”/var/tmp”

如:

参数名	是否必须	作用域	默认值	例子及说明
remote_workdir	No	Local/App/Global	/var/tmp	remote_workdir=/var/log/masterha/app1
master_binlog_dir
master上用于存储binary日志的全路径。这个参数用于当master上mysql死掉后,通过ssh连到mysql服务器上,找到需要binary日志事件。这个参数可以帮助用于无法找到master进程死掉后binary日志存储位置。

一般: master_binlog_dir是”/var/lib/mysql/, /var/log/mysql”. “/var/lib/mysql/”是大多数系统发行版本的存放位置,”/var/log/mysql”是ubuntu发行版本的存放位置。 你也可以设置多个存放位置用逗号隔开。

如:

参数名	是否必须	作用域	默认值	例子及说明
master_binlog_dir	No	Local/App/Gobal	/var/lib/mysql	master_binlog_dir=/data/mysql1,/data/mysql2
log_level
设置MHA manager记录LOG的级别。 默认是info级别而且大多数情况也是比较适合。 同样可以设置为: debug/info/warning/error.

如:

参数名	是否必须	作用域	默认值	例子及说明
log_level	No	App/Global	info	log_level=debug
manager_workdir
用于指定mha manager产生相关状态文件全路径。 如果没设置 默认是/var/tmp

如:

参数名	是否必须	作用域	默认值	例子及说明
manager_workdir	No	App	/var/tmp	manager_workdir=/var/log/masterha
manager_log
指定mha manager的绝对路径的文件名日志文件。 如果没设置MHA Manager将打印到STDOUT/STDERR。 当手工执行故障切换(交互模式切换),MHA Manager会忽略manager_log设置直接将日志输出到STDOUT/STDERR.

如:

参数名	是否必须	作用域	默认值	例子及说明
manager_log	No	App	STDERR	manager_log=/var/log/masterha/app1.log
check_repl_delay
在默认情况下,当一个slave同步延迟超过100M relay log(需要应用超过100M relay log), MHA在做故障切换时不会选择这个slave做为新的master,因为恢复需要经过很长时间.当设置了check_repl_delay = 0, MHA将忽略被选择的slave上的同步延迟。 这个选项在设置了candidate_master = 1特声明的期望这台机器成为master的情况下特别有用。

如:

参数名	是否必须	作用域	默认值	例子及说明
check_repl_delay	No	App/Golbal	1	check_repl_delay=0
check_repl_filter
在默认下情况,当master和slave设置了不同了binary log/replication 过滤规则时,MHA直接报错不会进行监控和故障切换。 这些将会导致出现一些异想不到的错误”Table not exists”。如果你100%确认不同的过滤规则不会导致恢复中的错误,设置check_repl_filter=0。 需要注意: 当使用了check_repl_filter = 0时,MHA不会检查过滤规则在应用差异的relay日志,所以有可能会出现”Table not exists”的错误。当你设置了这个参数请小心处理。

如:

参数名	是否必须	作用域	默认值	例子及说明
check_repl_filter	No	App/Global	1	check_repl_filter=0
latest_priority
在默认情况下,和Master最接近的slave(一个slave从Master上获得了最一个binlog事件)是最有优先权成为新的master。 如果你想控制一下切换的策略(如: 先选择host2,如果不行,选host3;host3不行,选host4…) 那么设置latest_priority = 0 就可以了。

如:

参数名	是否必须	作用域	默认值	例子及说明
latest_priority	No	App/Global	1	latest_priority=0
multi_tier_slave
从MHA 0.52开始, 多层复制可以支持了。在默认情况下,不支持三层或是更多层的复制配置。 如果: host2从host1上复制,host3从host2上复制。 在默认配置的情况下不支持写host{1,2,3},因为这是一个三层的复制,MHA Manager会停止报错。 当设置了multi_tier_slave, MHA Manager就不会在三层复制报错停止。 但是会忽略第三层的机器。也就是如果host1挂了,host2将会成为新的master,host3还是从host2上进行复制。

这个参数在MHA Manager 0.52后的版开始支持。

如:

参数名	是否必须	作用域	默认值	例子及说明
muli_tier_slave	No	App/Global	0	multi_tier_slave=1
ping_interval
这个参数设置MHA Manager多长时间去ping一下master(执行一些SQL语句). 当失去和master三次偿试,MHA Manager会认为MySQL Master死掉了。也就是说,最大的故障切换时间是4次ping_interval的时间,默认是3秒。

如果MHA Manager在和MySQL创建连接时都收到多连接错误或是认证错误,这个就不做重试就会认为master已经挂掉。

如:

参数名	是否必须	作用域	默认值	例子及说明
ping_interval	No	App/Global	3	ping_interval=5
ping_type
(从MHA 0.53后开始支持) 在默认情况下, MHA manager和MySQL创建一个连接执行”select 1″(ping_type=select)用于检查master是否健康。 但有一些情况: 每次检测都连接/然后断开会比较好一点,这样对于tcp方面的错误感知更快一点。设置ping_type=CONNECT 就行了。从MHA 0.56后pint_type=INSERT也被添加。

如:

参数名	是否必须	作用域	默认值	例子及说明
ping_type	No	App/Global	SELECT	ping_type=CONNECT
secondary_check_script
一般来讲, 非常推荐使用更多网络上机器是不同路由策略上的机器来检查MySQL Master是否存活。 默认情况下,只有MHA Manager通过一个路由来检查Master是否存活。这个也是不推荐的。MHA可以通过外部secondary_check_script配置的脚本来做到从多个路由策略下进行检查。

secondary_check_script = masterha_secondary_check -s remote_host1 -s remote_host2

secondary_check_script包含在MHA Manager发行包中。 MHA中内置的secondary_check_script在大多数情况下工作良好,但并不是任何地都可以使用这个脚本。

在上面的例子中, MHA Manager通过Manager->(A)->remote_host1->(B)->master_host 和Manager->(A)-remote_host2->(B)->master_host来检查MySQL master是否存活。如果在连接过程中通过A可以都成功,通过B是都失败,secondary_\check_\script返回0,而且认为master已经死掉,进行故障切换。如果通过A成功,但返回代码为: 2,则MHA manager有会认为是网络问题,则不会进行故障切换。如果A成功,B也成功,masterha_secondary_check 退出返回:3 则MHA Manager就为认为MySQL Master为存活状态, 则不会进行故障切换。

一般来讲, remote_host1和remote_host2是和MHA Manager及MySQL Server位于不同的网段中。

MHA会调用secondary_check_script声明的脚本并自动带上一些参数。 masterha_secondary_check在很多场景都是适用的,但是你也可以自已实现这个程序带有更多的功能。

–user=(在远程机器上使用的SSH用户名。 ssh_user的值将被使用)
–master_host = (master的hostname)
–master_ip = (master的ip地址)
–master_port = ( master的端口号)
注意: 内置的masterha_secondary_check脚本依赖于的Perl的IO::Socket::INET(Perl 5.6.0中是默认支持包含这个模块)。 masterha_secondary_check需要通过ssh连接到远程的机器上,所以需要manager到远程机器上建立public key信任。另外masterha_secondary_check是通过和Master建立TCP的连接测试Master是否存活,所以mysql设置的max_connections不起作用。 但每次TCP连接成功后,MySQL的Aborted_connects 值都会加1。

如:

参数名	是否必须	作用域	默认值	例子及说明
secondary_check_script	No	App/Global	null	secondary_check_script= masterha_secondary_check -s remote_dc1 -s remote_dc2
master_ip_failover_script
如:

参数名	是否必须	作用域	默认值	例子及说明
master_ip_failover_script	No	App/Global	null	master_ip_failover_script=/usr/local/custom_script/master_ip_failover
master_ip_online_changes_script
这个参数有点类似于master_ip_failover_script,但这个参数不用于master 故障转意,只使用到master在线的切换。

冻结Master写的过程:
–command=stop or stopssh 
–orig_master_host = (当前master的主机名) 
–orig_master_ip = (当前master的ip地址) 
–orig_master_port = (当前master的port端口号) 
–orig_master_user = (当前master的用户) 
–orig_master_password = (当前master的用户名) 
–orig_master_ssh_user = (从0.56支持,当前master的ssh的用户名)
–orig_master_is_new_slave =  (从 0.56 ,是否把原Master更改为新的slave)

新的Master接受写的过程:
–command=start 
–orig_master_host = ( 原master的机器名 ) 
–orig_master_ip = ( 原master的ip ) 
–orig_master_port = ( 原master的端口号 ) 
–new_master_host = (新master的机器名) 
–new_master_ip = (新master的ip) 
–new_master_port = (新master的端口号) 
–new_master_user = (新master上的用户名) 
–new_master_password = (新master上的用户名及密码) 
–new_master_ssh_user = (从0.56支持, 新master上的ssh用户)

MHA在冻结写的切换过程中会在Master上执行FlUSH TABLES WITH READ LOCK,在这个优雅的切换过程不会有任何写入的。在新的Master在开始授权写的过程中,你可以做和master_ip_failover_script一样的事情。 例如: 创建用户及权限, 执行set global read_only=0, 更新数据库路由表竺。 如果脚本执行退出码不是0 或是10, MHA Manager异常退出并发不会继续进行master切换。

默认这个参数是空的,所以MHA Manager在默认情况下什么也不做。

可以在(MHA Manager package)/samples/scripts/master_ip_online_change。里找到例子脚本。例子脚本包含于MHA Manager源文件或是GitHub的分支中。

如:

参数名	是否必须	作用域	默认值	例子及说明
master_ip_online_change_script	No	App/Global	null	master_ip_online_change_script= /usr/local/custom_script/master_ip_online_change
shutdown_script
如:

参数名	是否必须	作用域	默认值	例子及说明
shutdown_script	No	App/Global	null	shutdown_script= /usr/local/custom_script/master_shutdown
report_script
在Master故障完毕后,也许想发一个送一个报告(如email)报告一下切换完毕或是发生的错误。report_script可以完成这个工作。MHA Manager可以通过以下参数使用:

–orig_master_host = (死掉master机器名)
–new_master_host = (新的master机器名)
–new_slave_hosts = (新的slave机器名列表,用逗号隔开)
–subject = (邮件名)
–body = (正文)
默认这些参数是空的。 所以默认MHA Manager什么事情也不做。

可以在(MHA Manager package)/samples/scripts/send_report里找到例子脚本。例子脚本包含于MHA Manager源文件或是GitHub的分支中。

如:

参数名	是否必须	作用域	默认值	例子及说明
report_script	No	App/Global	null	report_script= /usr/local/custom_script/report
init_conf_load_script
这个参数用于不想设置明文在配置文件中(如:密码相关)。 只用返回”name=value”这样的值。 这个可以用来复盖global配置中的一些值。一个例子脚本如下。

#!/usr/bin/perl

print “password=$ROOT_PASS\n”;

print “repl_password=$REPL_PASS\n”;

如:

参数名	是否必须	作用域	默认值	例子及说明
init_conf_load_script	No	App/Global	null	report_script= /usr/local/custom_script/init_conf_loader

到这里配置的事就说完了。

失败后自动切换脚本(vip管理)

MHA做高可用需要用到vip,以实现切换真实数据库ip之后应用不需要手动修改真实数据库ip的作用,vip的方案有两种,一种是脚本管理vip 也就是mha推荐的,另一种是Keepalived,看了很多文章和根据实践 推荐使用脚本管理vip,避免发生mha和kp对mysql状态监测不一致问题。
直接列下我的脚本:

#!/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 $gateway = '192.168.11.1';   ---这个是网关地址
my $vip = '192.168.11.251/24'; ---vip地址
my $onlyvip = '192.168.11.251'; vip
my $key = '0'; ---网卡的别名编号
my $eth = 'ens32'; --网卡名称
my $ssh_start_vip = "/sbin/ifconfig $eth:$key $vip up;/sbin/arping -I $eth -c 3 -s $onlyvip $gateway";
my $ssh_stop_vip = "/sbin/ifconfig $eth:$key down";

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";

    print "\n\nIN Master_ip_failover_command:====$command===\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 \"`;
}
sub stop_vip() {
     return 0  unless  ($ssh_user);
    `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";
}

这个脚本实际也是在网上找到的,重点关注下这部分参数

my $gateway = '192.168.11.1';   ---这个是网关地址
my $vip = '192.168.11.251/24'; ---vip地址
my $onlyvip = '192.168.11.251'; vip
my $key = '0'; ---网卡的别名编号
my $eth = 'ens32'; --网卡名称
my $ssh_start_vip = "/sbin/ifconfig $eth:$key $vip up;/sbin/arping -I $eth -c 3 -s $onlyvip $gateway";
my $ssh_stop_vip = "/sbin/ifconfig $eth:$key down";

gateway,eth : 这里网关和网卡名字不用说了 直接用 ip addr就可以查询到本地网卡的名称是啥 直接看下网卡配置就知道网关地址是啥 vip这个就是在同一个网段
onlyvip ,vip:选择一个未使用的ip,这个ip之后是不允许再被实际机器使用的,192.168.11.251/24后面的24是啥或者怎么确定 直接去用ip addr
在这里插入图片描述
看到你要绑定的网卡的原来真是ip后面就有个数字 我们的vip就选择跟原来一样的就行 也就是24。
key :这里这个key随便写 只要不重复就行 看下我的效果

inet 192.168.103.211/24 brd 192.168.11.255 scope global ens32
...
 inet 192.168.103.251/24 brd 192.168.11.255 scope global secondary ens32:0

第一行是真是的ip,第二行是虚拟的ip大家看到最后面网卡名字后面有 ens32:0,就是个别名 不要过多关注。
/sbin/arping -I $eth -c 3 -s $onlyvip $gateway":再说下这里 这句话很多网上的脚本都没有,为啥要有 啥作用?是广播vip的 ,切换完成后vip在被绑定的机器上是立刻生效的,但是其他的机器是不会的 就需要用arping广播出去 ,vip在能立刻生效。

vip初始化或者删除脚本

初始化vip:

vip="192.168.11.251/24"
/sbin/ifconfig ens32:0 $vip up

ens32:0根据实际网卡名称改下
`删除vip:

/sbin/ifconfig ens32:0 down

在线切换master master_ip_online_change

这里就不说了 暂时没有啥研究

运行MHA

检测ssh

[root@nn ~]# masterha_check_ssh --global_conf=/etc/masterha/masterha_default.conf --conf=/etc/masterha/app1.conf
Fri Jan 11 10:11:16 2019 - [info] Reading default configuration from /etc/masterha/masterha_default.conf..
Fri Jan 11 10:11:16 2019 - [info] Reading application default configuration from /etc/masterha/app1.conf..
Fri Jan 11 10:11:16 2019 - [info] Reading server configuration from /etc/masterha/app1.conf..
Fri Jan 11 10:11:16 2019 - [info] Starting SSH connection tests..
...
Fri Jan 11 10:11:18 2019 - [info] All SSH connection tests passed successfully.
You have new mail in /var/spool/mail/root
[root@libothree ~]# 

检测复制组

 [root@nn ~]# masterha_check_ssh --global_conf=/etc/masterha/masterha_default.conf --conf=/etc/masterha/app1.conf
Sun Apr 20 18:46:08 2014 - [info] Checking replication health on 192.168.0.60..
Sun Apr 20 18:46:08 2014 - [info]  ok.
Sun Apr 20 18:46:08 2014 - [info] Checking replication health on 192.168.0.70..
Sun Apr 20 18:46:08 2014 - [info]  ok.
Sun Apr 20 18:46:08 2014 - [warning] master_ip_failover_script is not defined.
Sun Apr 20 18:46:08 2014 - [warning] shutdown_script is not defined.
Sun Apr 20 18:46:08 2014 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

启动 masterha_manager

 masterha_manager --global_conf=/etc/masterha/masterha_default.conf --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover --ignore_binlog_server_error > /var/log/masterha/app1/app1.log 2>&1 &

检测masterha_manager运行状态

[root@libothree ~]# masterha_check_status --global_conf=/etc/masterha/masterha_default.conf --conf=/etc/masterha/app1.conf

停止masterha_manager

masterha_stop --global_conf=/etc/masterha/masterha_default.conf --conf=/etc/masterha/app1.conf

基本上最常用的就是这五个命令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值