使用 MHA 和 HAProxy 部署高可用 MySQL

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
简介: 使用 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

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
5月前
|
运维 监控 关系型数据库
MySQL高可用方案:MHA与Galera Cluster对比
本文深入对比了MySQL高可用方案MHA与Galera Cluster的架构原理及适用场景。MHA适用于读写分离、集中写入的场景,具备高效写性能与简单运维优势;而Galera Cluster提供强一致性与多主写入能力,适合对数据一致性要求严格的业务。通过架构对比、性能分析及运维复杂度评估,帮助读者根据自身业务需求选择最合适的高可用方案。
|
5月前
|
SQL 监控 关系型数据库
MySQL主从复制:构建高可用架构
本文深入解析MySQL主从复制原理与实战配置,涵盖复制架构、监控管理、高可用设计及性能优化,助你构建企业级数据库高可用方案。
|
4月前
|
存储 关系型数据库 MySQL
MySQL Docker 容器化部署全指南
MySQL是一款开源关系型数据库,广泛用于Web及企业应用。Docker容器化部署可解决环境不一致、依赖冲突问题,实现高效、隔离、轻量的MySQL服务运行,支持数据持久化与快速迁移,适用于开发、测试及生产环境。
764 4
|
6月前
|
关系型数据库 MySQL 数据库
为什么 MySQL 不推荐用 Docker 部署?
本文探讨了MySQL是否适合容器化的问题,分析了Docker容器在数据安全、性能瓶颈、状态管理及资源隔离等方面的挑战,并指出目前主流分布式数据库如TDSQL和OceanBase仍倾向于部署在物理机或KVM上。
336 0
|
9月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
474 41
|
9月前
|
开发框架 Java 关系型数据库
在Linux系统中安装JDK、Tomcat、MySQL以及部署J2EE后端接口
校验时,浏览器输入:http://[your_server_IP]:8080/myapp。如果你看到你的应用的欢迎页面,恭喜你,一切都已就绪。
604 17
|
9月前
|
Java 关系型数据库 MySQL
在Linux操作系统上设置JDK、Tomcat、MySQL以及J2EE后端接口的部署步骤
让我们总结一下,给你的Linux操作系统装备上最强的军队,需要先后装备好JDK的弓箭,布置好Tomcat的阵地,再把MySQL的物资原料准备好,最后部署好J2EE攻城车,那就准备好进军吧,你的Linux军团,无人可挡!
237 18
|
9月前
|
开发框架 关系型数据库 Java
Linux操作系统中JDK、Tomcat、MySQL的完整安装流程以及J2EE后端接口的部署
然后Tomcat会自动将其解压成一个名为ROOT的文件夹。重启Tomcat,让新“植物”适应新环境。访问http://localhost:8080/yourproject看到你的项目页面,说明“植物”种植成功。
285 10
|
存储 关系型数据库 MySQL
美团面试:MySQL为什么 不用 Docker部署?
45岁老架构师尼恩在读者交流群中分享了关于“MySQL为什么不推荐使用Docker部署”的深入分析。通过系统化的梳理,尼恩帮助读者理解为何大型MySQL数据库通常不使用Docker部署,主要涉及性能、管理复杂度和稳定性等方面的考量。文章详细解释了有状态容器的特点、Docker的资源隔离问题以及磁盘IO性能损耗,并提供了小型MySQL使用Docker的最佳实践。此外,尼恩还介绍了Share Nothing架构的优势及其应用场景,强调了配置管理和数据持久化的挑战。最后,尼恩建议读者参考《尼恩Java面试宝典PDF》以提升技术能力,更好地应对面试中的难题。
|
12月前
|
监控 关系型数据库 MySQL
云数据库:从零到一,构建高可用MySQL集群
在互联网时代,数据成为企业核心资产,传统单机数据库难以满足高并发、高可用需求。云数据库通过弹性扩展、分布式架构等优势解决了这些问题,但也面临数据安全和性能优化挑战。本文介绍了如何从零开始构建高可用MySQL集群,涵盖选择云服务提供商、创建实例、配置高可用架构、数据备份恢复及性能优化等内容,并通过电商平台案例展示了具体应用。

推荐镜像

更多