MySQL高可用方案:Master High Active(MHA) (一)
MySQL High Availability目前常见有以下解决方案:
● MySQL Replication (99.9%)
● MHA/Orchestrator by Github and MySQL Replication (99.99%)
● Percona XtraDB Cluster/Galera (99.999%)
● MySQL InnoDB Cluster MGR (99.999%)
● MySQL NDB Cluster (99.999%)
1,背景
随着MySQL的推广使用越来越广泛, MySQL的高可用性变得越来越重要, 本篇主要介绍MySQL基于一个方案MHA, MHA 是有当时日本DeNA公司youshimaton于2011年首次公开,目前作者在facebook。MHA是一套优秀的作为MySQL高可用性环境下,能做到30秒内自动故障切换和主从提升的高可用软件(同样也支持手动切换)。 以Perl语言编程的方式监控和故障转移管理, 补齐中继日志最大程度保证数据完整. 尽管当前版本还在0.几,但当前这套解决方案仍然广泛采用。
MHA 也是和之前的MMM(http://mysql-mmm.org)类似, 基于MySQL复制的冗余,复制无法保证实时的数据同步和零数据的丢失,MHA是复制管理器,同样也是一套脚本集,MHA不会重建现有的replication link, 只是做master和slave的reconfigure, 是只负责failover,但是也有能力增加自定议脚本是应用程序处理变化,如切换VIP或修改全局文件等。MHA同样在生产环境中还会与半自动同步和KeepAlive、由RenéCannaò创建的ProxySQL 等共用提高可用性,把MySQL组合在一起,可以在不修改应用程序的情况下将流量定向到特定的服务器。 下一个出现的重要解决方案是Shlomi Noach的Orchestrator,它是可用于复制管理需求的可用选项菜单的最新成员。为了使事情更直观,它包括一个图形Web界面。有很多很棒的解决方案可以帮助您在发生故障时保持MySQL环境正常运行。如果您尚未实施GTID并且还不太愿意使用它或伪GTID,请考虑MHA。如果你运行GTID一个系统,你可以考虑Orchestrator的。
MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上,生产环境中多数单独部署。 MHA Node运行在每个MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将判断最新数据的slave提升为新的master,并将所有其他的slave重新指向新的master。
在一个Master node CRASH时,MHA 负责Master-Slave Auto-failover,默认情况下,MySQL复制是异步的。MHA试图从宕机的主服务器上保存二进制日志,通过ssh补齐日志,所以需要root用户,同时负载启停VIP. 如果主服务器崩溃,则它已提交的事务可能尚未传输到任何从服务器。因此,在这种情况下从主服务器到从服务器的故障转移可能导致事务丢失,所以通常还需要使用半同步替代异步,与半同步复制相结合,可以降低由于主硬件故障导致数据丢失的风险。
MHA进行Failover过程:
1)MHA MGR检测到Master异常,进行多项判断校验Master宕掉;
2)根所配置信息,确认出当前架构中所有节点的状态;
3)根据预定义的脚本处理故障的Master,VIP漂移或者停止mysqld服务;
4)所有当前的Slave节点比较位点,选出位点最新的Slave,再与Master比较并获得binlog的差异,copy到管理节点;
5)从候选节点中选择新的Master,新的Master会和位点最新的Slave进行比较并获得relay log的差异;
6)管理节点把binlog的差异copy到新Master,新Master应用binlog差异和relaylog差异,最后获得位点信息,并接受写请求(read_only=0);
7)其他Slave与位点最新的Slave进行比较,并获得relaylog的差异,copy到对应的Slave;
8)管理节点把binlog的差异copy到每个Slave,比较Exec_Master_Log_Pos和Read_Master_Log_Pos,获得差异日志;
9)每个Slave应用所有差异日志,然后reset slave并重新指向新Master;
10)新Master reset slave来清除Slave信息
MHA 的前提条件:
1) MySQL Replication必须已在运行。 MHA管理复制并对其进行监控,但它不是部署工具。
2) 所有主机都应该能够使用公共SSH密钥相互连接。
3) 所有节点都需要能够连接到彼此的MySQL服务器。
4) 所有节点都应具有相同的replication user 和password。
5) 在 multi-master 情况下,只允许一个可写节点。
6) MySQL版本必须为5.0或更高版本。
7) Master故障转移的候选者应启用binary log。 replication user 也必须存在。
8) 所有服务器上的二进制日志过滤变量应该相同(replicate-wild%,binlog-do-db …)。
9) 禁用自动relay-log清理并定期从cron任务执行。 您可以使用名为“purge_relay_logs”的MHA包含的脚本。
这里我们在VM环境安装MHA, MHA管理放到第1个slave1主机上。同时会配置半同步。
2, MySQL 编译安装
1, 安装MySQL ON OEL7
[root@master ~]# cat /etc/hosts 127.0.0.1 localhost master ::1 localhost master 192.168.56.200 master 192.168.56.201 slave1 192.168.56.202 slave2 192.168.56.201 mha_mgr vi /etc/selinux/config SELINUX=disabled 禁用防火墙,否则后期slave无法连接master [root@master ~]# systemctl disable firewalld.service Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. --下载 MySQL 5.7.26 安装介质 # wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-el7-x86_64.tar.gz [root@master ~]# ls anaconda-ks.cfg mysql-5.7.26-el7-x86_64.tar.gz [root@master ~]# tar zxvf mysql-5.7.26-el7-x86_64.tar.gz -C /usr/local/ # groupadd mysql # useradd -r -g mysql -s /bin/false mysql # tar zxvf mysql-5.7.14-linux-glibc2.5-x86_64.tar.gz -C /usr/local/ # cd /usr/local/ # ln -s /usr/local/mysql-5.7.14-linux-glibc2.5-x86_64 mysql # cd mysql # mkdir data # chmod 750 data # chown -R mysql . # chgrp -R mysql . # bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data # [Note] A temporary password is generated for root@localhost: A1Qw;meU*Nd1 # bin/mysql_ssl_rsa_setup # chown -R root . # chown -R mysql data # cp support-files/mysql.server /etc/init.d/mysql # cp support-files/mysql.server /etc/init.d/mysql # chkconfig --add mysql -- 配置环境变量 # vi .bash_profile # PATH=$PATH:$HOME/bin:/usr/local/mysql/bin/ #export PATH # vi /etc/my.conf [mysqld] character_set_server=utf8 port=3306 basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/tmp/mysql.sock user=mysql #replication options server-id=200 log-bin=mysql-bin log-bin-index=mysql-bin.index binlog_format=mixed skip-name-resolve expire_logs_days=14 skip-slave-start relay-log-purge=0 relay-log=mysql-relay-bin relay-log-index=mysql-relay-bin.index # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [mysqld_safe] log-error=/usr/local/mysql/data/mysqld.log pid-file=/usr/local/mysql/data/master.pid -- change mysql root password to anbob; # mysqladmin -u root -h127.0.0.1 -p password "anbob" -- 启动MySQL # /etc/init.d/mysql start OR [root@master ~]# service mysql start Starting MySQL. SUCCESS!
3, 配置主从同步和半自动同步
配置SSH 互信
–on master 192.168.56.22
ssh-keygen -t rsa ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.56.201 ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.56.202 其它从库一样copy到其它node。
配置主从同步
[root@master ~]# mysql -u root -p Enter password: mysql> grant replication slave on *.* to 'rpl'@'192.168.56.%' identified by 'mysql'; Query OK, 0 rows affected, 1 warning (0.08 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec) --or mysql> SELECT @@log_bin; mysql> SHOW BINARY LOGS -> ; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 154 | | mysql-bin.000002 | 154 | | mysql-bin.000003 | 177 | | mysql-bin.000004 | 154 | +------------------+-----------+ 4 rows in set (0.00 sec) -- 从Master导出数据库 mysqldump -uroot -p --master-data=2 --single-transaction --default-character-set=utf8 -R --triggers -A >all.sql -- 检查日志位置 [root@master ~]# head -n 30 all.sql|grep -i "CHANGE MASTER TO" -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=154; [root@master ~]# scp all.sql root@192.168.56.201:/root [root@master ~]# scp all.sql root@192.168.56.202:/root [root@master ~]# scp /etc/my.cnf root@192.168.56.201:/etc [root@master ~]# scp /etc/my.cnf root@192.168.56.202:/etc
Note: 并修改SLAVE的server-id 分别为201和202. 启动slave上的MySQL 数据库服务,
如果是slave 主机是clone的master主机,同样还要修改$data_dir/auto.cnf 文件中的UUID, 删除掉可以自动生成
[root@master data]# cd /usr/local/mysql/data
[root@master data]# mv auto.cnf auto.cnf.bak
在所有SLAVE数据库上创建备库
[root@slave2 ~]# mysql -uroot -p change master to master_host='192.168.56.200',master_user='rpl',master_password='mysql',master_port=3306,master_log_file='mysql-bin.000004',master_log_pos=154;
所有节点安装半同步插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; mysql> set global rpl_semi_sync_master_enabled=on ;
启动主从同步
mysql> start slave; mysql> set global read_only=1;
检查
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000016 | 1589 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID |
+-----------+------+------+-----------+--------------------------------------+
| 202 | | 3306 | 200 | 81a7ae3c-a22c-11e9-bbbf-080027032e78 |
| 201 | | 3306 | 200 | 3ccfe5d1-a22c-11e9-a10b-08002738fa8b |
+-----------+------+------+-----------+--------------------------------------+
2 rows in set (0.00 sec)
mysql> show status like 'Rpl_semi_sync_master%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 2 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
mysql> Show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.56.200
Master_User: rpl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000015
Read_Master_Log_Pos: 315
Relay_Log_File: mysql-relay-bin.000021
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000015
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Note: 如果Rpl_semi_sync_master_clients 值为0,表示半自动slave没发现,需要重启同步和半自动:
需要重启从库的复制(在从库上先stop slave然后再start slave)
然后重启主库的半同步复制(先set global rpl_semi_sync_master_enabled=off; 再set global rpl_semi_sync_master_enabled=on;)
从库一样要set global rpl_semi_sync_master_enabled=on;
有事务同步Rpl_semi_sync_master_yes_tx值会增长。
4, 配置MHA
安装依赖的环境,这里使用离线系统盘做yum源.
# mount /dev/cdrom /mnt mount: /dev/sr0 is write-protected, mounting read-only # vi /etc/yum.repos.d/public-yum-ol7.repo [oel7] name = Enterprise Linux 7.3 DVD baseurl=file:///mnt/ gpgcheck=0 enabled=1 # yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN
安装MHA NODE
# ls all.sql anaconda-ks.cfg mha4mysql-node-master.zip mysql-5.7.26-el7-x86_64.tar.gz # unzip mha4mysql-node-master.zip # cd mha4mysql-node-master # perl Makefile.PL # make && make install
对不起,这篇文章暂时关闭评论。