基于 MHA 高可用的 MySQL

功能

1、监控主数据库服务器是否可用 

2、当主DB不可用时,从多个从服务器中选出新的主数据库服务器 

3、提供了主从切换和故障转移功能(可以与半同步复制结合,最大程度的保证数据的完整性)

主从切换过程

1、尝试从出现故障的主数据库保存二进制日志 

2、从多个备选从服务器中选出新的备选主数据库(用户可指定不参与选择的数据库) 

3、在备选主服务器和其它从服务器之间同步差异二进制数据 

4、新主服务器应用从原主DB服务器上保存的二进制日志(若主DB的二进制保存下来)     注:重复的主键等会使MHA停止进行故障转移 

5、备选主DB服务器更新为新的主DB,并更改虚拟IP 

6、迁移集群中的其它从DB作为新的主DB的从服务器

架构(支持基于GTID的复制)

步骤

1、配置集群中所有主机的SSH免认证登录(比如故障转移过程中保存原主服务器二进制日志,配置虚拟IP地址等)
2、安装MHA-node软件包(所有节点均安装)和MHA-manager(监控节点安装)软件包
   命令:yum -y install perl-Config-Tiny.noarch 
                       perl-Time-HiRes.x86_64
                       perl-Parallel-ForkManager
                       perl-Log-Dispatch-Per.noarch
                       perl-DBD-MySQL ncftp
3、建立主从复制集群
4、配置MHA管理节点
    使用masterha_check_ssh:检查ssh免认证登录
    使用masterha_check_repl :检查复制链路
5、启动并测试MHA服务

实例

1、建立基于GTID复制的集群
2、开启ssh免登录认证  
    ssh-keygen #开启ssh密钥
    ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@192.168.71.244|223|220   #复制rsa到集群中的所有服务器(互相免登录)
    ssh root@192.168.71.244 #验证是否开启成功
3、下载node和manager安装包(wget [url])和安装perl的支持包(yum -y install perl-DBD-MySQL ncftp per-DBI.x86)
4、安装node (所有节点)
    rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
5、安装manager软件包和安装perl支持包(监控节点)
    yum -y install perl-Config-Tiny.noarch            #安装监控依赖
                       perl-Time-HiRes.x86_64
                       perl-Parallel-ForkManager
                       perl-Log-Dispatch-Per.noarch
                       perl-DBD-MySQL ncftp
    rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm  #安装监控软件
6、配置MHA (配置监控节点即可)
       mkdir -p /etc/mha                   #创建MHA配置目录
       mkdir -p /home/mysql_mha   #创建MHA的工作目录
       vim /etc/mha/mysql_mha.cnf(见附件1)            #建立配置文件
7、配置master_ip_failover(见附件2) 并chmod +x /usr/bin/master_ip_failover#变成可执行文件
8、检验ssh登录
        masterha_check_ssh --conf = /etc/mha/mysql_mha.cnf(在监控服务器中运行)
9、检验repl通道
        masterha_check_repl --conf = /etc/mha/mysql_mha.cnf(在监控服务器中运行)
10、运行mha
    nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /home/mysql_mha/manager.log 2>&1 & #放在后台运行
11、手动配置虚拟IP(在主中配置)
    ifconfig eth0:1 192.168.71.90/24   #ip addr 查看ip
12、测试(查看虚拟IP和复制链路)
    关闭主,查看从的复制链路和虚拟IP
备注:
#停止MHA
masterha_stop --conf=/etc/mha/mysql_mha.cnf [--remove_dead_master_conf ]--ignore_last_failover < /dev/null > /home/mysql_mha/manager.log 2>&1
#开始MHA
nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf [--remove_dead_master_conf] --ignore_last_failover < /dev/null > /home/mysql_mha/manager.log 2>&1 &
--remove_dead_master_conf:删除失败配置

若M宕机后,MHA会自动切换
若M重新恢复时,需要再次手动配置主动
CHANGE MASTER TO MASTER_HOST='192.168.71.244', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';

MHA常用命令

masterha_manager --conf=/etc/mha/mysql_mha.cnf         #开启MHA manager
masterha_check_status --conf=/etc/mha/mysql_mha.cnf    #检查MHA运行状态
masterha_check_repl --conf=/etc/mha/mysql_mha.cnf      #检查复制健康状态
masterha_stop --conf=/etc/mha/mysql_mha.cnf            #停止MHA manager运行
masterha_conf_host --command=add--conf=/etc/mha/mysql_mha.cnf --hostname=db101 --params="no_master=1;ignore_fail=1"                     #在配置文件中添加或移除host --block 移除
masterha_check——ssh --conf=/etc/mha/mysql_mha.cnf       #ssh认证检查

【附件1】 mysql_mha.cnf:

[server default]
    user = mha
    password = 123456
    manager_workdir = /home/mysql_mha
    manager_log = /home/mysql_mha/manager.log
    remote_workdir = /home/mysql_mha
    ssh_user = root
    repl_user = repl
    repl_password = 123456
    ping_interval =1
    master_binlog_dir = /usr/local/mysql/log/mysql-bin
    master_ip_failover_script = /usr/bin/master_ip_failover
     #master_ip_online_change_script= /usr/bin/master_ip_online_change
    secondary_check_script = /usr/bin/masterha_secondary_check -s 192.168.71.223 -s 192.168.71.244 -s 192.168.71.220
[server1]
    hostname = 192.168.71.244
    candidate_master = 1
[server2]
    hostname = 192.168.71.223
    candidate_master = 1
[server3]
    hostname = 192.168.71.220
    no_master = 1

【附件2】master_ip_failover

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
  $command,
  $orig_master_host,$orig_master_ip,$orig_master_port, $orig_master_ssh_port,
  $ssh_user,
  $new_master_host,$new_master_ip,  $new_master_port,  $new_master_user,$new_master_password,$new_master_ssh_port
);
my $vip = '192.168.71.90/24';
my $key = '1';
my $ssh_start_vip = "sudo /sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "sudo /sbin/ifconfig eth0:$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,
  'orig_master_ssh_port=i' => \$orig_master_ssh_port,
  '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_port=i'  => \$new_master_ssh_port
);
exit &main();
sub main {
  $ssh_user = defined $ssh_user ? $ssh_user : 'root';
  print "\n\nIN SCRIPT TEST ==== $ssh_user | $ssh_stop_vip == $ssh_user | $ssh_start_vip === \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_port 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 \"`;
}
# A simple system call that disable the VIP on the old_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=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
   }

【附件3】 report_script 邮箱通知

#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';

use Email::Simple;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Getopt::Long;
my ( $dead_master_host, $new_master_host, $new_slave_hosts, $subject, $body );

my $smtp='smtp.qq.com';
my $mail_from='xxx@qq.com';
my $mail_user='xxx@qq.com';
#邮箱授权码不是密码 邮箱授权码获取方式可以百度
my $mail_auth_pass='xxxxxx';
my $mail_to='xxxxxxxxxx';

GetOptions(
  'orig_master_host=s' => \$dead_master_host,
  'new_master_host=s'  => \$new_master_host,
  'new_slave_hosts=s'  => \$new_slave_hosts,
  'subject=s'          => \$subject,
  'body=s'             => \$body,
);
my $transport = Email::Sender::Transport::SMTP::TLS->new(
    host     => $smtp,
    port     => 25,
    username => $mail_user,
    password => $mail_auth_pass,
);

my $message = Email::Simple->create(
    header => [
        From           => $mail_from,
        To             => $mail_to,
        Subject        => $subject,
    ],
    body => $body,
);

sendmail( $message, {transport => $transport} );
exit 0;

【附图1】MHA的配置参数
ThinkPHP

【附图2】masterha_check_ssh --conf = /etc/mha/mysql_mha.cnf 结果:

【附图3】masterha_check_repl --conf=/etc/mha/mysql_mha.cnf 结果:

本作品采用《CC 协议》,转载必须注明作者和本文链接
来杯可乐不加糖。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!