数据库写读分离(MHA实现mysql的集群管理)(二)

mysql高可用有很多方案,如mmm,mysql cluster等,但都无法真正应用到生产环境。偶然间发现mha(master high availability),目前在mysql高可用方面是一个相对成熟的解决方案,它能够在较短时间内实现自动故障检测和故障转移,通常在10~30秒内;并且在replication环境中,mha能够很好的解决复制过程中数据行一致性问题。我们可以在不改动现有环境下部署mha,安装非常简单。

mha由mha manager(管理节点)和mha node(数据节点)组成。管理节点可以单独部署在一台独立的机器上管理一个或多个master-slave集群,也可以部署在一台slave节点上。数据节点运行在每台mysql服务器上,管理节点会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将其他的slave重新指向新的master。

如何保持数据的一致性呢?主要通过mha node的以下几个工具实现,但是这些工具由mha manager触发:

save_binary_logs如果master的二进制日志可以存取的话,保存复制master的二进制日志,最大程度保证数据不丢失

apply_diff_relay_logs相对于最新的slave,生成差异的中继日志并将所有差异事件应用到其他所有的slave。

注:对比的是relay log,relay log越新就越接近于master,才能保证数据是最新的。

purge_relay_logs删除中继日志而不阻塞sql线程。

mha架构如下:

master:10.10.10.56 hostname:rd-mysql-test1server-id:1写入,数据节点

slave1:10.10.10.57 hostname:rd-mysql-test2 server-id:2读,数据节点,备选master(candicate master)

slave2:10.10.10.57 hostname:rd-mysql-test3 server-id:3读,数据节点

mha manager:10.10.10.59 hostname:rd-mysql-test4-管理节点

1.在所有节点安装mha node

#安装mha node

因为MHA是由perl语言编写的,先安装perl的依赖 :

$ yum install perl-DBD-MySQL -y

$ cd mha4mysql-node-0.56

$ perl Makefile.PL

$ make && make install

$ yum install perl-devel  解决 Can't locate ExtUtils/MakeMaker.pm in @INC 的错误

$ yum -y install perl-CPAN  解决 Can't locate CPAN.pm in @INC 的错误

$ yum -y install gcc automake autoconf libtool make 解决 -bash: make: command not found

2.安装mha manager

#安装mha manager

安装mha manager的config配置

yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes -y

$ cd mha4mysql-manager-0.56

$ perl Makefile.PL

$ make && make install

注意:1.mha manager节点也需要安装mha node

 安装完成后会在/usr/local/bin目录下生成以下脚本:

apply_diff_relay_logs
filter_mysqlbinlog
masterha_check_repl             检查MySQL复制状况
masterha_check_ssh              检查MHA的SSH配置状况
masterha_check_status           检测当前MHA运行状态
masterha_conf_host              添加或删除配置的server信息
masterha_manager                启动MHA
masterha_stop                   停止MHA
masterha_master_monitor         检测master是否宕机
masterha_master_switch          控制故障转移(自动或者手动)
masterha_secondary_check        多种线路检测master是否存活

另外在/usr/local/src/mha4mysql-manager-0.56/samples/scripts下还有以下脚本,我们将其软连接到 /usr/local/bin 下 命令

ln -s 源文件 目标文件。需要将 mysqlbinlog(/usr/local/mysql/bin/) 的脚本放在 /usr/local/bin 下。
-rwxr-xr-x 1 root root  3443 Jan  8  2012 master_ip_failover        自动切换时VIP管理脚本
-rwxr-xr-x 1 root root  9186 Jan  8  2012 master_ip_online_change   在线切换时VIP脚本
-rwxr-xr-x 1 root root 11867 Jan  8  2012 power_manager             故障发生后关闭master脚本     
-rwxr-xr-x 1 root root  1360 Jan  8  2012 send_report               故障切换发送报警脚本

3.搭建mysql主从复制

参考上一篇文章   数据库写读分离(数据库主备方式)(一)

但是请注意以下要点:

(1)、log-bin必须在candicate mater(备选主机)上必须设置,如果备选主机没有设置log-bin,

    那么在故障转移过程mha manager会检测不到log-bin,则备选主机不会成为新的master,

    即使你设置过candicate master=1, 如果所有slave没有设置log-bin,则mha manager不会启动故障转移。

(2)、备份用户必须在所有的slave上存在,否则masterha_check_repl会不成功

(3)、replication过滤规则(binlog-do-db和replicate-ignore-db等)必须在所有msyql上一致,否则masterha_check_repl会不成功

4.在所有节点上做ssh免密码登录

一、ssh-keygen -t rsa

二、ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 [email protected]

5.mha配置

(1)创建mha配置文件目录并编辑配置文件

[server default]
#manger mha工作目录,用于产生相关状态文件
manager_workdir=/data/mha/3306/log

#manger mha日志
manager_log=/data/mha/3306/log/manager.log

#mha产生日志的目录,需要足够的权限
remote_workdir=/tmp

#master保存binlog的目录,如果master故障,但是ssh能通则用于拷贝复制二进制日志,保证数据一致性
master_binlog_dir=/usr/local/mysql/log/

#mysql管理用户和密码,最好是root,以便执行所有mysqlm命令,如stop slaves,change master等
user=root
password=123456

#复制用户和密码
#repl_user=rep
#repl_password=123456

#ssh的用户名和密码,为了方便拷贝复制,我们用root用户
ssh_user=root
ssh_port=8889

#mha manager使用ping sql statement检测master的频率,如果超过3次不通则认定mysql master崩溃
ping_interval=1

#默认使用ping_type=SELECT检测,但是从0.53开始使用更可靠的CONNECT,从0.53开始使用更可靠的INSERT
ping_type=CONNECT


#故障转移使用的脚本
#master_ip_failover_script=/usr/local/bin/master_ip_failover

#在线切换脚本
#master_ip_online_change_script=/usr/local/bin/master_ip_online_change

#发送报警信息脚本
#report_script=/usr/local/bin/send_report

#通过多种网络路径检测ssh是否能够连接到master脚本,若其中一个路径不通,则会通过另一个路径ssh连接到master
#secondary_check_script=/usr/local/bin/masterha_secondary_check -s rd-mysql-test2 -s rd-mysql-test3 --user=mha --master_host=rd-mysql-test1 --master_ip=10.10.10.56 --master_po
rt=3306
#关闭master脚本防止脑裂
#shutdown_script=/usr/local/bin/power_manager

[server1]
hostname=172.18.52.69
port=3306

[server2]
hostname=172.18.52.65
port=3306

#备选master参数
candidate_master=1

#如果slave的relay log落后于master超过100M,将此选为新master时会花费较长时间,因此mha manager不会将此slave选为新的master。通过过设置此参数可以忽略这种情况
check_repl_delay=0

#[server3]
#hostname=47.96.108.75
#port=3307

注意:以上相关执行脚本命令的已经全都注释点,后面我们会通过手动执行的方式来充分了解,当我们全都弄明白了在恢复自动执行。

(2)设置relay log的清除方式

默认情况下,slave上的relay log在sql thread执行完成后会自动清除,但是这些relay log可能在恢复其他slave时仍然需要。因此我们禁用relay log自动清除功能,使用定期清除relay log的方法。然而在手动清除的时候我们需要考虑到复制延迟的问题,在ext3文件系统中,删除大文件会花费很长的时间,这会导致严重的复制延迟。为了避免这种情况,我们可以通过建立硬链接的方式来避免。

mha node用purge_relay_logs工具来实现,它会创建硬链接,执行set global relay_log_purge=1,等待几秒钟以便sql thread能够切换到新的relay log,最后执行set global log_purge=0.

具体参数如下:

?

1

2

3

4

5

6

--user mysql      用户名

--password mysql   密码

--port          端口号

--host          默认为127.0.0.1,不能为其他ip地址

--workdir        指定创建relay log的硬链接的位置,默认是/var/tmp,由于系统不同分区创建硬链接文件会失败,故需要执行硬链接具体位置,成功执行脚本后,硬链接的中继日志文件被删除

--disable_relay_log_purge         默认情况下,如果relay_log_purge=1,脚本会什么都不清理,自动退出,通过设定这个参数,当relay_log_purge=1的情况下会将relay_log_purge设置为0。清理relay log之后,最后将参数设置为OFF。

   

purge_relay_logs清除relay log不会阻塞sql thread,我们需要在所有的slave上定期执行此命令,如:

1

2

3

4

[root@rd-mysql-test2 scripts]# cat /etc/rc.local

#在此我们使用root

* 5 * * * /usr/local/bin/purge_relay_logs  --user=root  --disbale_relay_log_purge >> /var/log/masterha/purge_relay_log.log 2>&1

注意:确定使用的用户是否能够登录mysql

purge_relay_logs  --user=root  --host=127.0.0.1 --port=3306 --disable_relay_log_purge

6. 检查ssh配置是否正确

masterha_check_ssh  --conf=/data/mha/3306/log/mha.cnf 

注意: 需要 ssh登录本地 即 ssh localhost 不需要登录密码

7.检查整个复制环境的状况

masterha_check_repl  --conf=/data/mha/3306/log/mha.cnf

8.开启mha manager监控

nohup masterha_manager --conf=/data/mha/3306/log/mha.cnf --remove_dead_master_conf --ignore_last_failover  2>&1 &

  

我们可以使用nohup来使监控运行在后台。其中:

1

2

3

4

5

--remove_dead_master_conf      该参数代表当发生主从切换后,老的主库的ip将会从配置文件中移除。

--manger_log                日志存放位置

--ignore_last_failover         在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之所以这样限制是为了避免ping-pong效应。该参数代表忽略上次MHA触发切换产生的文件,默认情况下,MHA发生切换后会在日志目录,也就是上面我设置的/data产生app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为--ignore_last_failover。

注意:现在mha manager进行没有作为daemon来运行,如果故障转移成功完成或master进程意外被杀,那么监控将会停止。我们可以使用daemontools来是监控作为daemon来运行。

wget https://cr.yp.to/daemontools/daemontools-0.76.tar.gz
tar -zxvf daemontools-0.76.tar.gz
cd admin/daemontools-0.76/
./package/install
若报如下异常
./load envdir unix.a byte.a 
/usr/bin/ld: errno: TLS definition in /lib64/libc.so.6 section .tbss mismatches non-TLS reference in envdir.o
/lib64/libc.so.6: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [envdir] Error 1

####解决方法####
在src/conf-cc最后加上-include /usr/include/errno.h

gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -include /usr/include/errno.h

[root@rd-mysql-test4 daemontools-0.76]# ./package/install

最后会在/usr/local/src/admin/daemontools-0.76 先建立command目录并存放相关命令。

同时在/usr/local/bin下对上面这些命令建立了软连接方便我们执行。

另外创建监控/services目录,并在/etc/inittab下也有变化:

SV:123456:respawn:/command/svscanboot

它使用init的方式来守护自己。

1

2

3

4

5

6

7

8

9

[root@rd-mysql-test4 daemontools-0.76]#mkdir -p /service/masterha_app1

[root@rd-mysql-test4 daemontools-0.76]#vim /service/masterha_app1/run

#!bin/bash

exec masterha_manager --conf=/etc/mha/app1.cnf --wait_on_monitor_error=60 --wait_on_failover_error=60 >> /var/log/masterha/app1/app1.log 2>&1

[root@rd-mysql-test4 daemontools-0.76]#chmod 755 /service/masterha_app1/run

 

##启动monitoring

svc -u /service/masterha_app1

 

##停止monitoring

svc -d /service/masterha_app1

9.查看是否启动

masterha_check_status  --conf=/data/mha/3306/log/mha.cnf

启动后会在 /data/mha/3306/log 下生成如下两个文件 

manager.log 

master_status.health

关闭监控我们可以使用

masterha_stop  --conf=/data/mha/3306/log/mha.cnf

10.测试

一.自动failover

1.我们关闭master的mysql

[root@izwz93l5w3yargzbnesexmz support-files]# ./mysql.server stop
Shutting down MySQL...                                     [  OK  ]

我们查看/data/mha/3306/log会发现以下情况:

生成了如下两个文件

mha.failover.complete  

saved_master_binlog_from_172.18.52.92_3306_20180827141324.binlog两个文件。

mha.failover.complete  文件,说明failover已经完成;

saved_master_binlog_from_172.18.52.92_3306_20180827141324.binlog 是从master上复制过来的二进制日志。

manager.log 是复制环境状态的检查并记录了整个failover的过程,我们可以查看failover报告:

----- Failover Report -----

mha: MySQL Master failover 172.18.52.92 to 172.18.52.93 succeeded

Master 172.18.52.92 is down!

Check MHA Manager logs at izwz93l5w3yargzbnesexmz:/data/mha/3306/log/manager.log for details.

Started automated(non-interactive) failover.
The latest slave 172.18.52.93(172.18.52.93:3306) has all relay logs for recovery.
Selected 172.18.52.98 as a new master.
172.18.52.93: OK: Applying all logs succeeded.
Generating relay diff files from the latest slave succeeded.
172.18.52.98: Resetting slave info succeeded.
Master failover to 172.18.52.93(172.18.52.93:3306) completed successfully.

从报告中可以看出故障迁移是成功,我们还可以看看mysql的状态确认迁移是否成功。

整个迁移过程如下:

(1)检查配置文件阶段,检查配置文件中master存活

(2)宕机master保证应用不会连接,会使用shutdown_script配置的脚本;

    如果master_ip_failover_script设置的话,将会进行VIP漂移切换

(3)master恢复阶段,其中包括:

     获取最新的slave的二进制日志

从master上保存二进制日志并和最新的slave上的rilay log对比差异,将差异保存到slave的remote_workdir=/tmp下,然后再将其保存到mha manager上的/var/log/masterha/app1下

选出新的master,如果设置了candidate_master,则优先选为新masterha_conf_host来添加。

对比新master的relay log,生成差异并将mha manager上的日志复制到remote_workdir=/tmp下

将差异应用在新master上

(4)slaves恢复阶段,其中包括:

并行操作,对比relay log

并行操作,将mha managermha manager上的日志复制到remote_workdir=/tmp下,将差异日志应用到slave

(5)将slave提升为新的master,并将老master从配置文件中删除。

大体过程如下,总结的比较吃力,请详见manager.log。

注:1.成功完成一次故障转移后mha manager的监控会停止,若新master出现宕机时failover则不会发生,因此我们需要使用daemontools将将他作为daemon运行

2.当failover完成后,会将老的master从配置文件删除,若我们在修复好老的master后,希望将其作为slave继续使用,我们需要使用masterha_conf_host来添加,如:

#添加
masterha_conf_host --command=add --conf=--conf=/data/mha/3306/log/mha.cnf --block=server100  --hostname=test4 --params="no_master=1;ignore_fail=1"
则会在配置文件中生成:
[server100]
hostname=test4
no_master=1
ignore_fail=1
#删除
masterha_conf_host --command=add --conf=--conf=/data/mha/3306/log/mha.cnf --block=server100

 

你可能感兴趣的:(数据库)