Mysql_MHA高可用架构搭建

Mysql_MHA高可用架构搭建

窗体顶端

窗体底端

环境及兼容包

系统环境:centos6.5

Mysql: mysql-5.5.6 数据库用源码安装,这里就不介绍了

主机分配:

Master : 192.168.0.101 node1 (主库)

Slave1 : 192.168.0.102 node2 (备用主库)

Slave2 : 192.168.0.103 node3 (从库+MHA控制节点)

MHA兼容包见附件

窗体顶端

窗体底端

添加免密码登录,互为认证

++++++++++以下操作在三台节点上都的执行#+++++++++++++

##添加hosts,并修改各自主机名

192.168.0.101node1

192.168.0.102node2

192.168.0.103node3

##添加秘钥

ssh-keygen  -t rsa

cat/root/.ssh/id_rsa.pub >/root/.ssh/authorized_keys

##将三个节点的秘钥都添加到  authorized_keys,包括自己的秘钥

##在三个节点上依次执行下列命令用以检查 ssh

ssh node1 date

ssh node2 date

ssh node3 date

##只有互为认证登录成功才能继续后续操作

窗体顶端

窗体底端

安装MHA node 包

++++++++++以下操作在三台节点上都的执行#+++++++++++++

##更新yum为阿里源

mv/etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.old

wget -O/etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo

yum clean all

yum makecache

yum update

##安装环境包

yum installperl-DBD-MySQL perl perl-devel cpan

rpm -ivhmha4mysql-node-0.56-0.el6.noarch.rpm

##mha node 安装完成后会在/usr/bin 下面生成以下四个脚本:(这些工具通常由mha manger的脚本触发,无需人工操作)

/usr/bin/save_binary_logs       ##保存和复制master的二进制日志

/usr/bin/apply_diff_relay_logs  ##识别差异的中继日志事件并将其差异的事件应用于其他slave

/usr/bin/filter_mysqlbinlog     ##去除不必要的ROLLBACK事件(MHA已经不再使用这个工具)

/usr/bin/purge_relay_logs       ##清除中继日志(不会阻塞SQL线程)

窗体顶端

窗体底端

安装MHA manager节点包

[node3]#tar xf  mha.tar.gz

[node3]# cd mha

##登陆node3尝试安装mha4mysql-manager-0.56-0.el6.noarch,果然报错缺少perl模块的包

##按安装顺序整理如下:

compat-db43-4.3.29-15.el6

perl-Mail-Sender-0.8.16-3.el6

perl-Mail-Sendmail-0.79-12.el6

perl-Config-Tiny-2.12-7.1.el6

perl-Parallel-ForkManager-0.7.9-1.el6

perl-Log-Dispatch-2.27-1.el6

#在安装perl-Log-Dispatch-2.27-1.el6包时还会遇到有模块的包需要安装,按安装顺序整理如下:

perl-TimeDate-1.16-11.1.el6

perl-MIME-Types-1.28-2.el6

perl-MailTools-2.04-4.el6

perl-Email-Date-Format-1.002-5.el6

perl-Params-Validate-0.92-3.el6

perl-MIME-Lite-3.027-2.el6

之后便可以正常安装mha4mysql-manager-0.56-0.el6.noarch

rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

##mha manager 安装完成后会在/usr/bin 下面生成一些脚本:

/usr/bin/masterha_check_repl         ##检查mysql复制状况

/usr/bin/masterha_check_ssh          ##检查MHA的ssh配置状况

/usr/bin/masterha_check_status       ##检测当前MHA运行状态

/usr/bin/masterha_conf_host          ##添加或删除配置的server信息

/usr/bin/masterha_manager            ##启动MHA

/usr/bin/masterha_master_monitor     ##监测master是否宕机

/usr/bin/masterha_master_switch      ##控制故障转移(自动或手动)

/usr/bin/masterha_secondary_check    ##也是监测master是否宕机的脚本

/usr/bin/masterha_stop               ##关闭MHA

窗体顶端

窗体底端

修改数据库为主从

##将三个数据库文件 my.cf 中 server-id =  的值依次修改为 1、2、3

[node1]#mysql-uroot

mysql> show master status;

//查看 master_log_file和 Position 值

##在三个库中都添加repl和monitor用户

mysql> GRANT REPLICATION SLAVE ON *.* TO‘repl‘@‘192.168.0.%‘ IDENTIFIED BY ‘123456‘;

mysql> grant all privileges on *.* to‘monitor‘@‘192.168.0.%‘ identified by ‘123456‘;

mysql> flush privileges;

##在node1 上执行下列语句

mysql> install plugin rpl_semi_sync_master soname‘semisync_master.so‘;

//主库安装semisync_master插件

mysql> set global rpl_semi_sync_master_enabled=1;

mysql> set globalrpl_semi_sync_master_timeout=30000;

//表示主库在某次事务中,如果等待时间超过30000毫秒,那么则降级为普通模式,不再等待备库。如果主库再次探测到,备库恢复了,则会自动再次回到Semi-sync状态。

##node2和node3上操作:

mysql> CHANGE MASTER TO

MASTER_HOST=‘192.168.0.101‘,

MASTER_PORT=3306,

MASTER_USER=‘repl‘,

MASTER_PASSWORD=‘123456‘,

MASTER_LOG_FILE=‘mysql-bin.000004‘,

MASTER_LOG_POS=0;

//MASTER_LOG_FILE=  和 MASTER_LOG_POS= 参数的值填写刚刚showmaster status查询的值

mysql> install plugin rpl_semi_sync_slave soname‘semisync_slave.so‘;

mysql> set global rpl_semi_sync_slave_enabled=1;

mysql> flush privileges;

mysql> start slave;

####从mysql5.5之后,mysql为了保证主从库数据一致性,引进了semi-sync功能,

semi-sync意思是MASTER只需要接收到其中一台SLAVE的返回信息,就会commit;否则需等待直至切换成异步再提交。

优点:

当事务返回客户端成功后,则日志一定在至少两台主机上存在。

MySQL的Semi-sync适合小事务,且两台主机的延迟又较小,则Semi-sync可以实现在性能很小损失的情况下的零数据丢失。

缺点:

完成单个事务增加了额外的等待延迟,延迟的大小取决于网络的好坏。

窗体顶端

窗体底端

Manager节点配置

[node3]#

[node3]# mkdir -p/etc/masterha  /masterha/app1    /masterha/scripts

[node3]# cd/etc/masterha/

[node3]# vimapp1.cnf

//app1.cnf 文件文末提供,在这里先把这两项参数值留空,到添加VIP 地址的时候在改成文 app1.cnf 文件中的值

master_ip_failover_script=""

master_ip_online_change_script=""

###检测配置

##检测ssh配置

[node3]# exportPERL5LIB=$PERL5LIB:/usr/lib/perl5/vendor_perl/

[node3]#masterha_check_ssh --conf=/etc/masterha/app1.cnf

##检测mysql配置

[node3]#masterha_check_repl --conf=/etc/masterha/app1.cnf

##检查MHA 的运行状态

[node3]#masterha_check_status --conf=/etc/masterha/app1.cnf

###运行MHA

[node3]# nohupmasterha_manager --conf=/etc/masterha/app1.cnf < /dev/null >/masterha/app1/manager.log 2>&1 &

[node3]# tail -f/masterha/app1/manager.log

[node3]#masterha_check_status --conf=/etc/masterha/app1.cnf

窗体顶端

窗体底端

验证

##先在master库上查看slave信息

mysql> show slave hosts;

+-----------+------+------+-----------+

| Server_id | Host | Port | Master_id |

+-----------+------+------+-----------+

|         3 |      | 3306 |         1 |

|         2 |      | 3306 |         1 |

+-----------+------+------+-----------+

##关闭 node1 上面的 master 库,然后在node2的slave库上查看是否切为主库

mysql> show slave hosts;

+-----------+------+------+-----------+

| Server_id | Host | Port | Master_id |

+-----------+------+------+-----------+

|         3 |      | 3306 |        2 |

+-----------+------+------+-----------+

##恢复高可用架构

##failover成功之后,MHA就会停了,这时候是slave1 到slave2的主从复制,假设192.168.0.101 数据库恢复了,那我们需要恢复高可用架构,让MHA启动。

##这是时候需要做的是,启动192.168.0.101数据库,在manager上面执行以下命令,找到CHANGEMASTER 执行即可。

[node1]# grep -i"All other slaves should start replication from here"/masterha/app1/manager.log

Fri Aug 2512:11:40 2017 - [info]  All other slavesshould start replication from here. Statement should

be: CHANGE MASTERTO MASTER_HOST=‘192.168.0.102‘, MASTER_PORT=3306,MASTER_LOG_FILE=‘mysql-bin.000012‘,

MASTER_LOG_POS=328, MASTER_USER=‘repl‘, MASTER_PASSWORD=‘123456‘;

//注意 MASTER_HOST= MASTER_LOG_FILE= MASTER_LOG_POS=   三个的值

[node1]# mysql-uroot

mysql> CHANGEMASTER TO MASTER_HOST=‘192.168.0.102‘, MASTER_LOG_FILE=‘mysql-bin.000012‘,MASTER_LOG_POS=328, MASTER_USER=‘repl‘, MASTER_PASSWORD=‘123456‘;

mysql> slavestart;

[node2]#mysql-uroot

mysql> showslave hosts;

+-----------+------+------+-----------+

| Server_id | Host | Port | Master_id |

+-----------+------+------+-----------+

|         3 |      | 3306 |         2 |

|         1 |      | 3306 |         2 |

+-----------+------+------+-----------+

###在开启MHA 服务,然后关闭node2 上面的mysql模拟宕机

[node3]# nohupmasterha_manager --conf=/etc/masterha/app1.cnf < /dev/null >/masterha/app1/manager.log 2>&1 &

##还需删除app1.failover.complete文件,否则会报错

[node3]# rm -f/masterha/app1/app1.failover.complete

[node2]# servicemysql3306 stop

[node1]# mysql-uroot

mysql> showslave hosts;

+-----------+------+------+-----------+

| Server_id | Host | Port | Master_id |

+-----------+------+------+-----------+

|         3 |      | 3306 |         1 |

+-----------+------+------+-----------+

##在执行上面(恢复高可用架构) 操作,将slave1 加入到集群里来

窗体顶端

窗体底端

VIP地址漂移

####注意必须所有的主机网卡信息都为 eth0

##先在 node1 上添加虚拟地址

[node1]#/sbin/ifconfig eth0:1 192.168.0.100/24

##修改app1.cnf 配置文件中

master_ip_failover_script=/etc/masterha/master_ip_failover           #master failover时执行

master_ip_online_change_script=/etc/masterha/master_ip_online_change   #master switchover时执行

##编辑master_ip_failover和 master_ip_online_change文件

[node3]# cd/etc/masterha/

[node3]# vimmaster_ip_failover

[node3]# vimmaster_ip_online_change

//配置文件内容在文档末尾

窗体顶端

窗体底端

app1.cnf 配置文件

app1.cnf

[server default]

user=monitor

password=123456

ping_interval=10

#repl_workdir=/masterha/app1

repl_user=repl

repl_password=123456

ssh_user=root

master_ip_failover_script=/etc/masterha/master_ip_failover

master_ip_online_change_script=/etc/masterha/master_ip_online_change

#report_script= /etc/masterha/send_report

shutdown_script=""

secondary_check_script=/usr/bin/masterha_secondary_check-s node2 -s node1

manager_workdir=/masterha/app1

manager_log=/masterha/app1/manager.log

#remote_workdir=/masterha/app1

[server1]

hostname=192.168.0.101

port=3306

master_binlog_dir=/data/mysql/data3306

candidate_master=1

#check_repl_delay=0

[server2]

hostname=192.168.0.102

port=3306

master_binlog_dir=/data/mysql/data3306

candidate_master=1

#check_repl_delay=0

[server3]

hostname=192.168.0.103

#port=3306

#master_binlog_dir=/data/mysql/data3306

no_master=1

#node3不参与竞选,只作从库和manager使用

read_only=1

窗体顶端

窗体底端

配置文件master_ip_failover

master_ip_failover

#!/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.0.100/24‘;

my $key = "1";

my $ssh_start_vip = "/sbin/ifconfig eth0:$key$vip";

my $ssh_stop_vip = "/sbin/ifconfig eth0:$keydown";

my $exit_code = 0;

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 SCRIPTTEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

if ( $command eq "stop" || $command eq"stopssh" ) {

#$orig_master_host, $orig_master_ip, $orig_master_port are passed.

# If youmanage master ip address at global catalog database,

#invalidate orig_master_ip here.

my$exit_code = 1;

eval {

print"\n\n\n***************************************************************\n";

print"Disabling the VIP - $vip on old master: $orig_master_host\n";

print"***************************************************************\n\n\n\n";

&stop_vip();

$exit_code = 0;

};

if ([email protected]){

warn"Got Error: [email protected]\n";

exit$exit_code;

}

exit$exit_code;

}

elsif ( $command eq "start" ) {

# allarguments are passed.

# If youmanage master ip address at global catalog database,

# activatenew_master_ip here.

# You canalso grant write access (create user, set read_only=0, etc) here.

my $exit_code = 10;

eval {

print"\n\n\n***************************************************************\n";

print"Enabling the VIP - $vip on new master: $new_master_host \n";

print"***************************************************************\n\n\n\n";

&start_vip();

$exit_code = 0;

};

if ([email protected]){

[email protected];

exit $exit_code;

}

exit$exit_code;

}

elsif ( $command eq "status" ) {

print"Checking the Status of the script.. OK \n";

`ssh$ssh_user\@$orig_master_host \" $ssh_start_vip \"`;

exit0;

}

else {

&usage();

exit1;

}

}

# A simple system call that enable the VIP on the newmaster

sub start_vip() {

`ssh $ssh_user\@$new_master_host \" $ssh_start_vip\"`;

}

# A simple system call that disable the VIP on theold_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=po

rt –new_master_host=host –new_master_ip=ip–new_master_port=port\n";

}

窗体顶端

窗体底端

配置文件master_ip_online_change

master_ip_online_change

#!/usr/bin/env perl

use strict;

use warnings FATAL =>‘all‘;

use Getopt::Long;

my $vip = ‘192.168.0.100/24‘;

my $key = "1";

my $ssh_start_vip = "/sbin/ifconfig eth0:$key$vip";

my $ssh_stop_vip = "/sbin/ifconfig eth0:$keydown";

my $exit_code = 0;

my (

$command,              $orig_master_is_new_slave,$orig_master_host,

$orig_master_ip,      $orig_master_port,        $orig_master_user,

$orig_master_password, $orig_master_ssh_user,     $new_master_host,

$new_master_ip,       $new_master_port,         $new_master_user,

$new_master_password, $new_master_ssh_user,

);

GetOptions(

‘command=s‘                => \$command,

‘orig_master_is_new_slave‘ => \$orig_master_is_new_slave,

‘orig_master_host=s‘       =>\$orig_master_host,

‘orig_master_ip=s‘         =>\$orig_master_ip,

‘orig_master_port=i‘       =>\$orig_master_port,

‘orig_master_user=s‘       =>\$orig_master_user,

‘orig_master_password=s‘   =>\$orig_master_password,

‘orig_master_ssh_user=s‘   =>\$orig_master_ssh_user,

‘new_master_host=s‘        =>\$new_master_host,

‘new_master_ip=s‘          =>\$new_master_ip,

‘new_master_port=i‘        =>\$new_master_port,

‘new_master_user=s‘        =>\$new_master_user,

‘new_master_password=s‘    => \$new_master_password,

‘new_master_ssh_user=s‘    =>\$new_master_ssh_user,

);

exit &main();

sub main {

#print "\n\nIN SCRIPTTEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

if ( $command eq "stop" || $command eq"stopssh" ) {

#$orig_master_host, $orig_master_ip, $orig_master_port are passed.

# If youmanage master ip address at global catalog database,

#invalidate orig_master_ip here.

my $exit_code = 1;

eval {

print"\n\n\n***************************************************************\n";

print"Disabling the VIP - $vip on old master: $orig_master_host\n";

print"***************************************************************\n\n\n\n";

&stop_vip();

$exit_code = 0;

};

if ([email protected]){

warn"Got Error: [email protected]\n";

exit$exit_code;

}

exit$exit_code;

}

elsif ( $command eq "start" ) {

# allarguments are passed.

# If youmanage master ip address at global catalog database,

# activatenew_master_ip here.

# You canalso grant write access (create user, set read_only=0, etc) here.

my $exit_code = 10;

eval {

print"\n\n\n***************************************************************\n";

print"Enabling the VIP - $vip on new master: $new_master_host \n";

print"***************************************************************\n\n\n\n";

&start_vip();

$exit_code = 0;

};

if ([email protected]){

[email protected];

exit$exit_code;

}

exit$exit_code;

}

elsif ( $command eq "status" ) {

print"Checking the Status of the script.. OK \n";

`ssh$orig_master_ssh_user\@$orig_master_host \" $ssh_start_vip \"`;

exit0;

}

else {

&usage();

exit1;

}

}

# A simple system call that enable the VIP on the newmaster

sub start_vip() {

`ssh $new_master_ssh_user\@$new_master_host \"$ssh_start_vip \"`;

}

# A simple system call that disable the VIP on theold_master

sub stop_vip() {

`ssh $orig_master_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=po

rt –new_master_host=host –new_master_ip=ip–new_master_port=port\n";

}

时间: 2024-08-04 20:20:50

Mysql_MHA高可用架构搭建的相关文章

drbd+heartbeat+nfs高可用架构搭建

一.客户需求 1.需求描述 有些客户有自己的存储设备,但是并没有集群文件系统服务,所以如果我们多个节点(计算节点)如果想同时使用其中的一个块且要保证高可用的话,就需要我们自己来完成类似集群文件系统的服务组合,在此我们使用的服务组合是:iscsi共享+drbd+heartbeat+nfs. 2.服务说明 Iscsi共享:这里通过iscsi共享服务将存储设备上的存储块共享出去,提供节点(NC1+NC2)使用,此处我们将在iscsi服务短创建两个镜像充当块设备. Drbd   :服务器之间镜像块设备内

基于DR模式的keepalived主从模式高可用架构搭建

一:架构图示 2.keepalived是什么? Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机 ,或工作出现故障,Keepalived将检测到,通过VRRP协议,将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器. 3.VRRP协议是什么? VRRP(Virtual Router Redundancy Protoc

13、mha高可用架构搭建

各节点架构: 192.168.1.20(mysql5.5) master主库 192.168.1.21(mysql5.5) slave1,目标:主库宕可提升为主库 192.168.1.22(mysql5.5) slave2,目标:主库宕不可提升为主库 192.168.1.25(percona5.6) slave3.mha-manager.binlog server,目标:主库宕不可提升为主库 配置各节点ssh信任,在其中一台执行: # cd ~/.ssh # cat id_rsa.pub > a

mysql5.6基于GTID模式之高可用架构搭建-MHA(mha0.56)

一.测试环境部署: mysql1:192.168.110.131   作为master mysql2:192.168.110.132   作为slave mysql3:192.168.110.130   作为slave,同时作为MHA的管理机 虚拟IP:192.168.110.100 二.mysql主从环境搭建和MHA安装 1.mysql主从搭建自行搭建(基于GTID复制,打开log_bin,复制规则默认,复制所有库表),这里不再说明. 2.安装MHA节点软件:rpm -ivh mha4mysq

maxscale配合MHA搭建读写分离的高可用架构(基于GTID replication主从架构,mysql5.6)

基于GTID的主从replication并配合MHA搭建高可用架构,请参考之前的博客:http://linzhijian.blog.51cto.com/1047212/1906434.这里只叙述如何在此基础上增加maxscale中间件,实现读写分离的功能. MaxScale是maridb开发的一个MySQL数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换.官方文档:https://mariadb.com/kb/en/mariadb-enterprise/about

Redis 实战搭建高可用架构

前言:最近在看关于redis缓存方面的知识,今天就来个 Redis sentinel 高可用架构,实战开始之前,先看看sentinel的概念 什么是redis-sentinel Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发

基于MMM搭建MySQL Replication集群高可用架构

MMM介绍 MMM是Multi-Master Replication Manager for MySQL的缩写,它是MySQL提供的一个多主复制管理器,其核心是使用perl语言编写的一组脚本.实际上MMM是比较早期甚至有点老的一种用于构建高可用MySQL架构的方式,但因其还有一定的应用场景,所以本文将会演示一下如何搭建一个MMM架构. MMM 由两个组件组成: monitor:监控集群内数据库的状态,在出现异常时发布切换命令,一般和数据库分开部署 agent:运行在每个 MySQL 服务器上的代

Oracle Compute云快速搭建MySQL Keepalived高可用架构

最近有个客户在测试Oracle Compute云,他们的应用需要使用MySQL数据库,由于是企业级应用一定要考虑高可用架构,因此有需求要在Oracle Compute云上搭建MySQL高可用集群.客户根据自身的技术储备想要使用Keepalived组件来配合MySQL实现.今天结合Oracle Compute刚刚宣布terraform支持的架构即代码方式,交付给客户一个快速搭建MySQL+Keepalived高可用架构,来帮助他们快速搭建测试环境甚至将来使用到正式环境. MySQL主主复制模式 M

企业中MySQL主流高可用架构实战三部曲之MHA

老张最近两天有些忙,一些老铁一直问,啥时更新博文,我可能做不到天天更新啊,但保证以后一有空就写一些干货知识分享给大家. 我们如果想要做好技术这项工作,一定要做到理论与实践先结合.我一个曾经被数据库虐得体无完肤的过来人给大家一些建议:就是只看书,背理论真的行不通,到时遇到棘手的问题,你还是一样抓瞎.一定要在理论理清的基础上多做实验. 给自己定个目标,3个月做够100-500个实验.然后整理在做实验过程中的各种报错,认真解读分析报错原理,做好笔记.最后再拿起书,重新阅读之前有些可能理解不了的理论知识