目录
随着数据量的不断增长和业务对数据库高可用性、高扩展性及高性能的需求日益强烈,MySQL 集群技术应运而生。它解决了传统单节点 MySQL 数据库面临的单点故障问题,通过多节点部署实现高可用性,当某个节点出现故障时,其他节点可以继续提供服务;同时解决了数据存储容量和处理能力的瓶颈问题,实现了可扩展性,能够随着业务的发展动态增加节点;还提升了数据库的性能,通过负载均衡等技术将请求分发到不同节点进行处理,提高了响应速度和吞吐量。
一、MySQL安装部署
1、MySQL源码安装
环境准备:
基于RHEL7环境的mysql源码安装
1、安装源码安装需要的软件
[root@mysql-node1 ~]# yum install cmake gcc-c++ openssl-devel -y
[root@mysql-node1 ~]# yum install ncurses-devel.x86_64 -y
[root@mysql-node1 ~]# yum install libtirpc-devel-0.2.4-0.16.el7.x86_64.rpm -y
[root@mysql-node1 ~]# tar zxf mysql-boost-5.7.44.tar.gz
[root@mysql-node1 ~]# cd mysql-5.7.44/
2、源码编译及安装
[root@mysql-node1 ~]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_EXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci -DWITH_BOOST=/root/mysql-5.7.44/boost/boost_1_59_0/
[root@mysql-node1 ~]# make -j4 && make install
2、MySQL部署
[root@mysql-node2 ~]# cd /usr/local/mysql/
[root@mysql-node2 ~]# useradd -s /sbin/nologin -M mysql
[root@mysql-node2 mysql]# mkdir /data/mysql -p
[root@mysql-node2 ~]# chown mysql.mysql -R /data/mysql
[root@mysql-node2 support-files]# cp mysql.server /etc/init.d/mysqld
[root@mysql-node2 ~]# vim /etc/my.cnf
[root@mysql-node2 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
[root@mysql-node2 ~]# vim ~/.bash_profile
[root@mysql-node2 ~]# source ~/.bash_profile
数据库初始化建立mysql基本数据
[root@mysql-node2 ~]# mysqld --user mysql --initialize
[root@mysql-node2 ~]# /etc/init.d/mysqld start
[root@mysql-node2 ~]# chkconfig mysqld on
安全初始化
[root@mysql-node2 ~]# mysql_secure_installation
二、MySQL组从复制
1、组从复制集群配置
master配置
[root@mysql-node1 ~]# vim /etc/my.cnf
[root@mysql-node1 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=10
log-bin=mysql-bin
[root@mysql-node1 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
进入数据库配置用户权限
salve配置
[root@mysql-node2 ~]# vim /etc/my.cnf
[root@mysql-node2 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2
[root@mysql-node2 ~]# /etc/init.d/mysqld restart
2、mysql主从集群slave添加及延迟回放
1、slave添加
添加第二个slave安装部署mysql
生产环境中备份时需要锁表,保证备份前后的数据一致 mysql> FLUSH TABLES WITH READ LOCK;
备份后再解锁 mysql> UNLOCK TABLES; mysqldump命令备份的数据文件,在还原时先DROP TABLE,需要合并数据时需要删除此语句
master节点备份数据
[root@mysql-node1 ~]# mysqldump -uroot -p mlh > mlh.sql
[root@mysql-node1 ~]# scp mlh.sql root@172.25.254.30:/mnt/
[root@mysql-node3 mnt]# mysql -uroot -p123 -e "CREATE DATABASE mlh;"
[root@mysql-node3 mnt]# mysql -uroot -p123 mlh < mlh.sql
CHANGE MASTER TO MASTER_HOST='172.25.254.10',MASTER_USER='repl',MASTER_PASSWORD='123',MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=154;
测试:
master
mysql> INSERT INTO mlh.userlist values('user2','123');
Query OK, 1 row affected (0.00 sec)
slave2
2、延迟复制
延迟复制指的是从服务器在复制主服务器的二进制日志时,故意设置一定的时间延迟,而不是实时同步数据。例如,主服务器上的数据发生变化后,从服务器不会立即进行同步,而是等待一段时间(如几分钟、几小时等)后再开始复制这些变化。
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE MASTER TO MASTER_DELAY=60;
Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUS\G;
3、慢查询日志
慢查询日志可以记录执行时间超过特定阈值的 SQL 语句,帮助你找出性能瓶颈,以便进行优化。在主从集群环境下,它对于分析整个系统的性能问题尤其重要。
-
性能优化:通过分析慢查询日志中的语句,可以针对性地进行索引优化、查询重写等操作,提高数据库的响应速度。
-
故障排查:如果主从同步出现延迟,慢查询日志可以帮助确定是否是由于某些耗时的查询导致从库无法及时跟上主库的写入速度。
mysql> SET GLOBAL slow_query_log=ON;
Query OK, 0 rows affected (0.00 sec)
#开启慢查询功能
测试:
mysql> SELECT SLEEP (10);
[root@mysql-node1 ~]# cat /data/mysql/mysql-node1-slow.log
#慢查询日志
4、MySQL并行复制
传统的 MySQL 主从复制是单线程的,即从库只有一个 SQL 线程来顺序地应用主库传过来的二进制日志(binlog)。而并行复制则允许多个线程同时处理不同的事务,从而加快从库的复制速度,减少主从之间的延迟。
[root@mysql-node2 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON
slave-parallel-type=LOGICAL_CLOCK #基于组提交,
slave-parallel-workers=10 #开启线程数量
master_info_repository=TABLE #master信息在表中记录,默认记录
在/data/mysql//master.info
relay_log_info_repository=TABLE #回放日志信息在表中记录,默认记录
在/data/mysql/relay-log.info
relay_log_recovery=ON #日志回放恢复功能开启
[root@mysql-node2 ~]# /etc/init.d/mysql start
5、组从复制原理
三个线程 实际上主从同步的原理就是基于 binlog 进行数据同步的。在主从复制过程中,会基于3 个线程来操作, 一个主库线程,两个从库线程。
-
二进制日志转储线程(Binlog dump thread)是一个主库线程。当从库线程连接的时候, 主库可以 将二进制日志发送给从库,当主库读取事件(Event)的时候,会在 Binlog 上加锁,读取完成之 后,再将锁释放掉。
-
从库 I/O 线程会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库 的二进制日志转储线程发送的 Binlog 更新部分,并且拷贝到本地的中继日志 (Relay log)。
-
从库 SQL 线程会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同 步。
复制三步骤
步骤1:Master将写操作记录到二进制日志(binlog)。
步骤2:Slave将Master的binary log events拷贝到它的中继日志(relay log);
步骤3:Slave重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化 的,而且重启后从接入点开始复制。
架构缺陷
主从架构采用的是异步机制,master更新完成后直接发送二进制日志到slave,但是slaves是否真正保存了数据master端不会检测,master端直接保存二进制日志到磁盘 ,当master端到slave端的网络出现问题时或者master端直接挂掉,二进制日志可能根本没有到达slave,master出现问题slave端接管master,这个过程中数据就丢失了 ,这样的问题出现就无法达到数据的强一致性,零数据丢失。
6、MySQL的GTid模式
当master出现问题后,slave2和master的数据最接近,会被作为新的master slave1指向新的master,但是他不会去检测新的master的pos id,只需要继续读取自己gtid_next即可。
#MASTER
[root@mysql-node1 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
log-bin=mysql-bin
server-id=10
slow_query_log=on
gtid_mode=ON
enforce-gtid-consistency=ON
[root@mysql-node1 ~]# /etc/init.d/mysqld restart
#Slave2
[root@mysql-node3 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=30
gtid_mode=ON
enforce-gtid-consistency=ON
[root@mysql-node3 ~]# /etc/init.d/mysqld restart
#停止slave端
[root@mysql-node2 ~]# mysql -p
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
[root@mysql-node3 ~]# mysql -p
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
#开启slave端的gtid
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='repl', MASTER_PASSWORD='123', MASTER_AUTO_POSITION=1;
mysql> start slave;
mysql> show slave status\G;
三、MySQL半同步模式
MySQL 半同步复制工作模式是一种在主从复制架构下提高数据一致性和可用性的机制。在该模式下,主库在执行完事务提交后,会等待至少一个从库接收到并写入中继日志后返回确认信息,才认为事务提交成功。这样确保了主库的数据在至少一个从库中有备份,避免了主库在事务提交后但从库还未同步数据时主库发生故障导致的数据丢失问题,提高了数据的安全性和系统的可靠性。
1、事务提交过程: 当客户端向主库发送一个写请求时,主库执行事务并将事务记录到二进制日志中。 主库将事务写入二进制日志后,会等待至少一个从库接收到事务并返回确认信息。这个等待过程是异步的,不会阻塞主库的其他操作。 当主库接收到至少一个从库的确认信息后,认为事务提交成功,并向客户端返回成功响应。
2、从库复制过程: 从库通过 I/O 线程从主库读取二进制日志,并将其写入到本地的中继日志(Relay Log)中。 从库的 SQL 线程读取中继日志中的事务,并在从库上依次执行这些事务,以保持与主库的数据同步。
3、故障处理: 如果主库在等待从库确认信息的过程中超时,主库会切换回异步复制模式,继续处理客户端的请求。此时,可能会出现主从数据不一致的情况。 当从库出现故障时,主库会继续处理客户端的请求,但不会等待从库的确认信息。当从库恢复后,会自动从主库同步数据,以保持与主库的数据一致。
MASTER配置
[root@mysql-node1 ~]# vim /etc/my.cnf
rpl_semi_sync_master_enabled=1
#先不要重启否则会报错,在mysql执行打开半同步功能命令后才能重启
安装半同步插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
查看插件情况
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
#打开半同步功能
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
#查看半同步功能状态
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
mysql> SHOW STATUS LIKE 'rpl_semi_sync%';
在slave端开启半同步功能
slave1
[root@mysql-node2 & 3 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=20
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1
#安装半同步插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
#打开半同步功能
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
#重启I/O线程半同步才会生效
测试:
在 MySQL 中,如果主库在等待从库确认信息过程中超时,会切换回异步复制模式继续处理客户端请求,此时可能出现主从数据不一致情况。当从库出现故障时,主库也会继续处理请求且不等待从库确认信息,从库恢复后会自动从主库同步数据以保持一致。如果所有从设备都关闭了半同步功能,主设备会继续正常写入数据且不会宕机,备份设备重新启动后会读取从主设备复制的数据包括之前未读取部分,因为主设备会继续记录所有事务且从设备从主设备二进制日志中复制。当从设备都关闭半同步功能时,主设备不会一直处于等待状态直到收到 ACK 后才继续读取写入数据,在 MySQL 的半同步复制模式下,主库在事务提交时会等待至少一个从库的 ACK 消息后才认为事务提交成功,但如果所有从库都关闭半同步功能,主库会自动切换回异步复制模式,在异步复制模式下,主库在事务提交后不会等待从库确认,而是立即返回给客户端事务提交成功的响应,然后继续处理后续读写请求,所以从设备都关闭半同步功能后,主设备会按照异步复制的方式工作。
四、MySQL高可用之组复制
MySQL 组复制是一种高可用、高可靠的数据库复制技术。其工作原理是多个 MySQL 服务器组成一个复制组,组内成员通过分布式的事务机制和通信协议实现数据的同步和一致性。事务在组内被广播,各成员根据一致性协议进行验证和执行,确保数据在组内的一致性。当有成员发生故障时,组内其他成员可以自动检测并进行故障恢复,保证数据库服务的持续可用。同时,新成员可以动态加入组,实现灵活的扩展和高可用性部署。
配置:
[root@mysql-node1 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.10 mysql-node1.mlh.org
172.25.254.20 mysql-node2.mlh.org
172.25.254.30 mysql-node3.mlh.org
#在一主两从主机做解析
[root@mysql-node1 ~]# /etc/init.d/mysqld stop
#清除mysql旧数据
[root@mysql-node1 ~]# rm -rf /data/mysql/*
#编辑主配置文件
[root@mysql-node1 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=10
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address="172.25.254.10:33061"
group_replication_group_seeds="172.25.254.10:33061,172.25.254.20:33061,172.25.254.30:33061"
group_replication_ip_whitelist="172.25.254.0/24,127.0.0.1/8"
group_replication_bootstrap_group=off
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
group_replication_allow_local_disjoint_gtids_join=1
[root@mysql-node1 ~]# mysqld --user=mysql --initialize #初始化mysql
[root@mysql-node1 ~]# /etc/init.d/mysqld start #启动mysql
[root@mysql-node1 ~]# mysql -uroot -p'eOoBC0Jkie)x' #登录mysql,密码为初始化生成的密码
mysql> alter user root@localhost identified by '123'; #登录后修改密码
slave主机配置同理
master-sql配置
sql
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'lee';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='lee' FOR CHANNEL
'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> SET GLOBAL group_replication_bootstrap_group=ON; #用以指定初始成员,值在第
一台主机中执行
Query OK, 0 rows affected (0.00 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.19 sec)
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
slave-sql配置
sql
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'lee';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='lee' FOR CHANNEL
-> 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (5.71 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
当三台主机都配置好后,可以发现在每台主机都有对方的信息
测试:
在主设备创建库表并插入数据,在两个slave主机能看到;
sql
mysql> CREATE DATABASE mlh;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE TABLE mlh.userlist(
-> username VARCHAR(10) PRIMARY KEY NOT NULL,
-> password VARCHAR(50) NOT NULL
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO mlh.userlist VALUES('user1','111');
Query OK, 1 row affected (0.01 sec)
效果:
在两台slave插入数据,主设备也能看到
sql
slave1:INSERT INTO mlh.userlist VALUES('user2','222');
slave2:INSERT INTO mlh.userlist VALUES('user3','333');
五、MySQL路由
bash
安装mysql-router
[root@mysql-node1 ~]# rpm -ivh mysql-router-community-8.4.0-1.el7.x86_64.rpm
配置Mysql-router文件
[root@mysql-node1 ~]# vim /etc/mysqlrouter/mysqlrouter.conf
[routing:ro]
bind_address = 0.0.0.0
bind_port = 7001
destinations = 172.25.254.20:3306,172.25.254.30:3306
routing_strategy = round-robin
[root@mysql-node1 ~]# systemctl start mysqlrouter.service
建立远程访问用户
bash
mysql> CREATE USER mlh@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all ON *.* to mlh@'%';
Query OK, 0 rows affected (0.00 sec)
测试:
bash
[root@mysql-node1 ~]# mysql -uroot -p123 -h 172.25.254.10 -P 7001
mysql router 并不能限制数据库的读写,访问分流
六、MySQL高可用集群MHA
MySQL 高可用集群 MHA(Master High Availability)主要是通过监控和管理 MySQL 主从复制架构来实现高可用性。其工作原理是持续监控 MySQL 主服务器状态,当检测到主服务器故障时,自动选择一个最优的从服务器提升为新主服务器,并将其他从服务器指向新主服务器进行数据同步。MHA 的功能包括快速故障转移,最大限度地减少数据丢失;支持在线主从切换,对应用程序影响小;可自动修复从服务器数据不一致问题,确保数据的完整性和一致性,为 MySQL 数据库提供了可靠的高可用解决方案,保障业务系统的持续稳定运行。
为什么要用MHA? Master的单点故障问题
什么是 MHA? MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用。
MHA 的组成 MHA由两部分组成:MHAManager (管理节点) MHA Node (数据库节点), MHA Manager 可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台 slave 节点上。 MHA Manager 会定时探测集群中的 master 节点。 当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的 slave 重新指向新的 master。
MHA 的特点 自动故障切换过程中,MHA从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失 使用半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日 志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数 据一致性 目前MHA支持一主多从架构,最少三台服务,即一主两从
故障切换备选主库的算法 1.一般判断从库的是从(position/GTID)判断优劣,数据有差异,最接近于master的slave,成为备选 主。 2.数据一致的情况下,按照配置文件顺序,选择备选主库。 3.设定有权重(candidate_master=1),按照权重强制指定备选主。 (1)默认情况下如果一个slave落后master 100M的relay logs的话,即使有权重,也会失效。 (2)如果check_repl_delay=0的话,即使落后很多日志,也强制选择其为备选主。
MHA工作原理 目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群必须最少有3台数据库服务器, 一主二从,即一台充当Master,台充当备用Master,另一台充当从库。 MHA Node 运行在每台 MySQL 服务器上 MHAManager 会定时探测集群中的master 节点 当master 出现故障时,它可以自动将最新数据的slave 提升为新的master 然后将所有其他的slave 重新指向新的master,VIP自动漂移到新的master。 整个故障转移过程对应用程序完全透明。
1、MHA部署
创建一个新主机172.25.254.50
bash
[root@mysql-mha ~]# unzip MHA-7.zip
[root@mysql-mha ~]# cd MHA-7/
解析
bash
[root@mysql-mha ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.50 mysql-MHA.mlh.org
172.25.254.10 mysql-node1.mlh.org
172.25.254.20 mysql-node2.mlh.org
172.25.254.30 mysql-node3.mlh.org
[root@mysql-mha ~]# scp /etc/hosts root@172.25.254.10:/etc/hosts
[root@mysql-mha ~]# scp /etc/hosts root@172.25.254.20:/etc/hosts
[root@mysql-mha ~]# scp /etc/hosts root@172.25.254.30:/etc/hosts
免密认证
bash
[root@mysql-mha ~]# ssh-keygen
[root@mysql-mha ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.254.10
[root@mysql-mha ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.254.20
[root@mysql-mha ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.254.30
[root@mysql-mha .ssh]# scp id_rsa root@172.25.254.10:/root/.ssh/
id_rsa 100% 1675 2.6MB/s 00:00
[root@mysql-mha .ssh]# scp id_rsa root@172.25.254.20:/root/.ssh/
id_rsa 100% 1675 1.3MB/s 00:00
[root@mysql-mha .ssh]# scp id_rsa root@172.25.254.30:/root/.ssh/
id_rsa 100% 1675 2.6MB/s 00:00
初始化10、20、30三台主机
登录MySQL配置
bash
#搭建主设备
mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'lee';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
mysql> SHOW STATUS LIKE 'rpl_semi_sync%';
从设备配置
bash
#配置前打开主设备log-bin=mysql-bin功能
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='repl',
MASTER_PASSWORD='lee', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)
mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;
Query OK, 0 rows affected (0.00 sec)
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
安装MHA软件
bash
[root@mysql-mha MHA-7]# yum install *.rpm -y
[root@mysql-mha MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@172.25.254.10:/root
[root@mysql-mha MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@172.25.254.20:/root
[root@mysql-mha MHA-7]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@172.25.254.30:/root
[root@mysql-node1&2&3 ~]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
bash
[root@mysql-mha ~]# masterha_manager --help
Usage:
masterha_manager --global_conf=/etc/masterha_default.cnf #全局配置文件,记录
公共设定
--conf=/usr/local/masterha/conf/app1.cnf #不同管理配置文件,记录各自配
置
See online reference
(http://code.google.com/p/mysql-master-ha/wiki/masterha_manager) for
details.
因为我们当前只有一套主从,所以我们只需要写一个配置文件即可,rpm包中没有为我们准备配置文件的模板,可以解压源码包后在samples中找到配置文件的模板文件。
bash
#生成配置文件
[root@mysql-mha ~]# mkdir /etc/masterha
[root@mysql-mha MHA-7]# tar zxf mha4mysql-manager-0.58.tar.gz
[root@mysql-mha MHA-7]# cd mha4mysql-manager-0.58/samples/conf/
[root@mysql-mha conf]# cat masterha_default.cnf app1.cnf >
/etc/masterha/app1.cnf
允许超级用户远程登登录
bash
mysql> CREATE USER root@'%' identified by '123';
mysql> grant ALL ON *.* to root@'%';
bash
#编辑配置文件
[root@mysql-mha ~]# vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/etc/masterha
manager_log=/etc/masterha/manager.log
[server1]
hostname=172.25.254.10
candidate_master=1
check_repl_delay=0
[server2]
hostname=172.25.254.20
candidate_master=1
check_repl_delay=0
[server3]
hostname=172.25.254.30
candidate_master=0
no_master=1
[server default]
user=root
password=mlh
ssh_user=root
master_binlog_dir= /data/mysql
remote_workdir=/data/tmp
secondary_check_script= masterha_secondary_check -s 172.25.254.10 -s 172.25.254.11
ping_interval=3
# master_ip_failover_script= /script/masterha/master_ip_failover
# shutdown_script= /script/masterha/power_manager
# report_script= /script/masterha/send_report
# master_ip_online_change_script= /script/masterha/master_ip_online_change
测试:
网络及免密认证检测
bash
[root@mysql-mha ]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
检测数据主从复制情况
bash
masterha_check_repl --conf=/etc/masterha/app1.cnf
2、MHA故障切换
修改主配置文件
bash
[root@mysql-mha ~]# vim /etc/masterha/app1.cnf
[server default]
user=root
password=mlh
ssh_user=root
repl_user=repl #mysql主从复制中负责认证的用户
repl_password=mlh #mysql主从复制中负责认证的用户密码
master_binlog_dir= /data/mysql
remote_workdir=/data/tmp
secondary_check_script= masterha_secondary_check -s 172.25.254.10 -s 172.25.254.11
ping_interval=3
环境检测
bash
[root@mysql-mha ]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
masterha_check_repl --conf=/etc/masterha/app1.cnf
1、无故障情况手动切换
bash
[root@mysql-mha ~]# masterha_master_switch \
> --conf=/etc/masterha/app1.cnf \
> --master_state=alive \
> --new_master_host=172.25.254.20 \
> --new_master_port=3306 \
> --orig_master_is_new_slave \
> --running_updates_limit=10000
切换成功后在从设备10、30查看效果
2、出现故障手动切换
模拟故障,关闭master主机10
bash
[root@mysql-node1 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!
[root@mysql-mha ~]# masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --dead_master_host=172.25.254.10 --dead_master_port=3306 --new_master_host=172.25.254.20 --new_master_port=3306 --ignore_last_failover
恢复故障MASTER节点
bash
[root@mysql-node1 ~]# /etc/init.d/mysqld start
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.20', MASTER_USER='repl',
-> MASTER_PASSWORD='mlh', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
#指定新master主机
mysql> start slave;
3、出现故障自动切换
删除锁文件是为了防止启动冲突和确保新的主服务器能够顺利接管服务
bash
[root@mysql-mha ~]# cd /etc/masterha/
[root@mysql-mha masterha]# rm -rf app1.failover.complete
[root@mysql-mha masterha]# masterha_manager --conf=/etc/masterha/app1.cnf
#监控程序通过指定配置文件监控master状态,当master出问题后自动切换并退出避免重复做故障切换
关闭当前master主机172.25.254.20
bash
[root@mysql-node2 ~]# /etc/init.d/mysqld stop
观察日志
bash
[root@mysql-mha masterha]# tail -f manager.log
恢复故障节点
bash
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='repl',
-> MASTER_PASSWORD='mlh', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave;
再次启动自动切换功能必须删除锁文件
bash
[root@mysql-mha masterha]# rm -rf app1.failover.complete manager.log
3、MySQL高可用集群VIP管理
VIP 功能的关键作用是确保在主服务器发生故障时,可以快速而无缝地将虚拟 IP 地址切换到新的主服务器上,从而保证应用程序可以持续访问数据库,而无需手动更新连接配置。
bash
[root@mysql-mha ~]# cp master_ip_* /usr/local/bin/
[root@mysql-mha ~]# chmod +x /usr/local/bin/master_ip_*
master_ip_failover: 主要用于故障切换时将虚拟 IP 从故障的主服务器转移到新的主服务器。 master_ip_online_change: 主要用于处理主服务器的在线更改或维护,确保虚拟 IP 能在不发生故障的情况下迁移到新的主服务器。
bash
[root@mysql-mha ~]# vim /usr/local/bin/master_ip_failover
[root@mysql-mha ~]# vim /usr/local/bin/master_ip_online_change
#配置内容,修改VIP为'172.25.254.100/24;'即可
my $vip = '172.25.254.100/24';
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";
[root@mysql-mha ~]# vim /etc/masterha/app1.cnf
在master主机手动添加vip
bash
[root@mysql-node1 ~]# ip a a 172.25.254.100/24 dev eth0
测试切换master后VIP是否迁移
bash
#清除日志和锁文件
[root@mysql-mha masterha]# rm -rf manager.log
[root@mysql-mha masterha]# rm -rf app1.failover.complete
#在MHA主机监控
[root@mysql-mha ~]# masterha_manager --conf=/etc/masterha/app1.cnf
#关闭master主机172.25.254.10
[root@mysql-node1 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS
切换成功后,VIP随master切换迁移到新的主机172.25.254.20
恢复故障主机slave172.25.254.10
sql
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.20', MASTER_USER='repl',
-> MASTER_PASSWORD='mlh', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.254.20
手动切换主服务器VIP的变化
sql
[root@mysql-mha ~]# masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=172.25.254.10 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000