使用 MHA 和 HAProxy 部署高可用 MySQL

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 使用 MHA 和 HAProxy 部署高可用 MySQL

MySQL-MariaDBGaleraClusterPerconaXtraDBClusterMySQLClusterCGEMHA[1]HAProxy[2]keepalivedVRRP[3]使MHA使OracleMariaPerconaSQLGTID


MHAMasterHighAvailabilityManagerandtoolsforMySQLPerlMySQLIPssh-ingMySQLscp-ingssh


-MHAHAProxyMySQL使GTID[4]


GTID


[root@mysql-n01 ~] cat /etc/mysql/conf.d/replication.cnf
[mysqld]
server_id = 1
report-host = 1
report-port = 1
read_only = 0
# binary logs
log_bin = /var/log/mysql/replica-1-bin
expire_logs_days = 3
max_binlog_size = 1G
log_slave_updates = 1
sync-binlog = 0
binlog_format = MIXED
# GTID
gtid_mode = ON
enforce-gtid-consistency
# Relay logs
relay_log = /var/log/mysql/replica-1-relay
relay_log_purge = 1
relay_log_recovery  = 1
relay_log_space_limit = 5G
[root@mysql-n01 ~] mysql
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicationuser'@'%' IDENTIFIED BY 'somepassword'
mysql> FLUSH PRIVILEGES; 
[root@mysql-n02 ~] cat /etc/mysql/conf.d/replication.cnf
[mysqld]
server_id = 2
report-host = 1
report-port = 1
read_only = 1
# binary logs
log_bin = /var/log/mysql/replica-2-bin
expire_logs_days = 3
max_binlog_size = 1G
log_slave_updates = 1
sync-binlog = 0
binlog_format = MIXED
# GTID
gtid_mode = ON
enforce-gtid-consistency
# Relay logs
relay_log = /var/log/mysql/replica-2-relay
relay_log_purge = 1
relay_log_recovery  = 1
relay_log_space_limit = 5G
[root@mysql-n02 ~] mysql
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicationuser'@'%' IDENTIFIED BY 'somepassword'
mysql> FLUSH PRIVILEGES;

mysql> change master to master_host=<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="62" data-index-1691639741453="1853" data-index-len-1691639741453="1853" class="character" style="max-width: 100%;">"10.188.50.124<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="62" data-index-1691639741453="1867" data-index-len-1691639741453="1867" class="character" style="max-width: 100%;">", master_user=<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="62" data-index-1691639741453="1882" data-index-len-1691639741453="1882" class="character" style="max-width: 100%;">"replicationuser<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="62" data-index-1691639741453="1898" data-index-len-1691639741453="1898" class="character" style="max-width: 100%;">", master_password=<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="62" data-index-1691639741453="1917" data-index-len-1691639741453="1917" class="character" style="max-width: 100%;">"somepassword<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="62" data-index-1691639741453="1930" data-index-len-1691639741453="1930" class="character" style="max-width: 100%;">", master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.14 sec)
mysql> start slave;
Query OK, 0 rows affected (0.06 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.188.50.124
                  Master_User: replicationuser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: replica-2-bin.000004
          Read_Master_Log_Pos: 231
               Relay_Log_File: replica-1-relay.000002
                Relay_Log_Pos: 369
        Relay_Master_Log_File: replica-2-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 231
              Relay_Log_Space: 573
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: ebc53c30-5de6-11e4-ac82-0018518bc543
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: e443c439-5de6-11e4-ac82-0018511fca0b:1-6,
ebc53c30-5de6-11e4-ac82-0018518bc543:1-3
                Auto_Position: 1
1 row in set (0.00 sec)

 MHA 

[root@mysql-n01 ~] wget https://mysql-master-ha.googlecode.com/files/mha4mysql-node_0.54-0_all.deb
[root@mysql-n01 ~] apt-get install libdbd-mysql-perl
[root@mysql-n01 ~] dpkg --install mha4mysql-node_0.54-0_all.deb

MHAHAProxykeepalivedMHA

[root@manager-n01 ~] apt-get install libdbd-mysql-perl
[root@manager-n01 ~] apt-get install libconfig-tiny-perl
[root@manager-n01 ~] apt-get install liblog-dispatch-perl
[root@manager-n01 ~] apt-get install libparallel-forkmanager-perl
[root@manager-n01 ~] wget https://mysql-master-ha.googlecode.com/files/mha4mysql-manager_0.55-0_all.deb
[root@manager-n01 ~] wget https://mysql-master-ha.googlecode.com/files/mha4mysql-node_0.54-0_all.deb
[root@manager-n01 ~] dpkg --install mha4mysql-node_0.54-0_all.deb
[root@manager-n01 ~] dpkg --install mha4mysql-manager_0.55-0_all.deb
[root@manager-n01 ~] apt-get install haproxy keepalived

sshMHA使sshMHAHAProxykeepalived

[root@manager-n01 ~] cat /etc/app1.cnf
[server default]
# User that will ssh from the manager nodes to the database nodes
user=mhamanager
password=somepassword
ssh_user=root
# working directory on the manager
manager_workdir=/var/log/masterha/app1
# working directory on MySQL servers
remote_workdir=/var/log/masterha/app1
master_ip_failover_script=/usr/bin/master_ip_failover
[server1]
hostname=10.188.49.114
[server2]
hostname=10.188.50.124
[root@manager-n01 ~] cat /usr/bin/master_ip_failover
#!/bin/bash
COMMAND=$1
OLD_MASTER_IP=$(echo $4 | cut -d<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="370" data-index-1691639741453="5753" data-index-len-1691639741453="5753" class="character" style="max-width: 100%;">"=<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="370" data-index-1691639741453="5755" data-index-len-1691639741453="5755" class="character" style="max-width: 100%;">" -f2)
NEW_MASTER_IP=$(echo $7 | cut -d<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="377" data-index-1691639741453="5793" data-index-len-1691639741453="5793" class="character" style="max-width: 100%;">"=<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="377" data-index-1691639741453="5795" data-index-len-1691639741453="5795" class="character" style="max-width: 100%;">" -f2)
if [ <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="381" data-index-1691639741453="5806" data-index-len-1691639741453="5806" class="character" style="max-width: 100%;">"$(echo $COMMAND | grep start)<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="383" data-index-1691639741453="5836" data-index-len-1691639741453="5836" class="character" style="max-width: 100%;">" != <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="385" data-index-1691639741453="5841" data-index-len-1691639741453="5841" class="character" style="max-width: 100%;">"<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="385" data-index-1691639741453="5842" data-index-len-1691639741453="5842" class="character" style="max-width: 100%;">" ]
then
  logger <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="389" data-index-1691639741453="5858" data-index-len-1691639741453="5858" class="character" style="max-width: 100%;">"Failover detected. Changing HAProxy config file<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="389" data-index-1691639741453="5906" data-index-len-1691639741453="5906" class="character" style="max-width: 100%;">"
  logger <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="391" data-index-1691639741453="5916" data-index-len-1691639741453="5916" class="character" style="max-width: 100%;">"Failed Master IP: $OLD_MASTER_IP, New Master IP: $NEW_MASTER_IP<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="395" data-index-1691639741453="5980" data-index-len-1691639741453="5980" class="character" style="max-width: 100%;">"
  MASTER_STANZA=$(cat /etc/haproxy/haproxy.cfg | grep <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="397" data-index-1691639741453="6035" data-index-len-1691639741453="6035" class="character" style="max-width: 100%;">"server mysql-master<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="397" data-index-1691639741453="6055" data-index-len-1691639741453="6055" class="character" style="max-width: 100%;">")
  sed -i <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="400" data-index-1691639741453="6066" data-index-len-1691639741453="6066" class="character" style="max-width: 100%;">"s/${MASTER_STANZA}/    server mysql-master ${NEW_MASTER_IP}:3306/<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="404" data-index-1691639741453="6132" data-index-len-1691639741453="6132" class="character" style="max-width: 100%;">" /etc/haproxy/haproxy.cfg
  logger <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="407" data-index-1691639741453="6167" data-index-len-1691639741453="6167" class="character" style="max-width: 100%;">"Restarting HAProxy<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="407" data-index-1691639741453="6186" data-index-len-1691639741453="6186" class="character" style="max-width: 100%;">"
  /etc/init.d/haproxy restart
fi
[root@manager-n01 ~] cat /etc/haproxy/haproxy.cfg
global
    log 127.0.0.1 local1
    log-tag haproxy
    maxconn 4096
    user haproxy
    group haproxy
    daemon
    stats socket /var/run/haproxy.sock mode 600 level admin
    stats timeout 2m
    tune.ssl.default-dh-param 2048
defaults
    log global
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option dontlognull
    option tcplog
    option logasap
frontend mysql_master
    bind 10.188.50.121:3306
    default_backend mysql_master
frontend mysql_slave
    bind 10.188.50.121:3307
    default_backend mysql_slaves
backend mysql_master
    server mysql-master 10.188.50.100:3306
backend mysql_slaves
    server mysql-slaves 10.188.50.110:3306 check
[root@manager-n01 ~] cat /etc/keepalived/keepalived.conf
vrrp_instance management_network {
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 100
  virtual_ipaddress {
    10.188.50.121/20 dev eth0 label eth0:0
  }
  nopreempt
  notify /usr/local/bin/mha_manager.sh
}
[root@manager-n01 ~] cat /usr/local/bin/mha_manager.sh
#!/bin/bash
TYPE=$1
NAME=$2
STATE=$3
case $STATE in
        <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="481" data-index-1691639741453="7331" data-index-len-1691639741453="7331" class="character" style="max-width: 100%;">"MASTER<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="481" data-index-1691639741453="7338" data-index-len-1691639741453="7338" class="character" style="max-width: 100%;">") /etc/init.d/haproxy start && /usr/bin/masterha_manager --conf=/etc/app1.cnf
                  exit 0
                  ;;
        <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="488" data-index-1691639741453="7468" data-index-len-1691639741453="7468" class="character" style="max-width: 100%;">"BACKUP<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="488" data-index-1691639741453="7475" data-index-len-1691639741453="7475" class="character" style="max-width: 100%;">") /etc/init.d/haproxy stop && /usr/bin/masterha_stop --conf=/etc/app1.cnf
                  exit 0
                  ;;
        <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="495" data-index-1691639741453="7601" data-index-len-1691639741453="7601" class="character" style="max-width: 100%;">"FAULT<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="495" data-index-1691639741453="7607" data-index-len-1691639741453="7607" class="character" style="max-width: 100%;">")  /etc/init.d/haproxy stop && /usr/bin/masterha_stop --conf=/etc/app1.cnf
                  exit 0
                  ;;
        *)        echo <span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="504" data-index-1691639741453="7749" data-index-len-1691639741453="7749" class="character" style="max-width: 100%;">"unknown state<span data-raw-text-1691639741453="" "="" data-textnode-index-1691639741453="504" data-index-1691639741453="7763" data-index-len-1691639741453="7763" class="character" style="max-width: 100%;">"
                  exit 1
                  ;;
esac

MHA11masterHAProxy13-17MySQLMHAmasterslave

keepalived88MHAkeepalived-haproxyMHA

MHA

[root@manager-n01 ~] /usr/bin/masterha_manager --conf=/etc/app1.cnf
[root@manager-n01 ~] /usr/bin/masterha_check_status --conf=/etc/app1.cnf
[root@manager-n01 ~] /usr/bin/masterha_stop --conf=/etc/app1.cnf

MySQLMHAHAProxy


[1]https://code.google.com/p/mysql-master-ha/

[2]http://www.haproxy.org/

[3]http://www.keepalived.org/

[4]http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-howto.html

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 SQL 关系型数据库
Mysql高可用架构方案
本文阐述了Mysql高可用架构方案,介绍了 主从模式,MHA模式,MMM模式,MGR模式 方案的实现方式,没有哪个方案是完美的,开发人员在选择何种方案应用到项目中也没有标准答案,合适的才是最好的。
164 3
Mysql高可用架构方案
|
17天前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
93 26
|
26天前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
45 5
|
3月前
|
关系型数据库 MySQL 数据安全/隐私保护
docker应用部署---MySQL的部署配置
这篇文章介绍了如何使用Docker部署MySQL数据库,包括搜索和拉取MySQL镜像、创建容器并设置端口映射和目录映射、进入容器操作MySQL,以及如何使用外部机器连接容器中的MySQL。
docker应用部署---MySQL的部署配置
|
2月前
|
关系型数据库 MySQL 数据库
使用Docker部署的MySQL数据库,数据表里的中文读取之后变成问号,如何处理?
【10月更文挑战第1天】使用Docker部署的MySQL数据库,数据表里的中文读取之后变成问号,如何处理?
78 3
|
2月前
|
关系型数据库 MySQL 数据库
使用Docker部署的MySQL数据库如何设置忽略表名大小写?
【10月更文挑战第1天】使用Docker部署的MySQL数据库如何设置忽略表名大小写?
324 1
|
3月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
3月前
|
存储 关系型数据库 MySQL
使用Docker快速部署Mysql服务器
本文介绍了如何使用Docker快速部署MySQL服务器,包括下载官方MySQL镜像、启动容器、设置密码、连接MySQL服务器以及注意事项。
627 18
|
2月前
|
存储 关系型数据库 MySQL
【MySQL精装典藏版】MySQL的安装与部署
【MySQL精装典藏版】MySQL的安装与部署
57 0
|
2月前
|
关系型数据库 MySQL 数据库
如何使用Docker部署MySQL数据库?
【10月更文挑战第1天】如何使用Docker部署MySQL数据库?
249 0