Linux企业化运维
实验所用系统为Redhat-rhel7.6。
目录
- Linux企业化运维
- Linux企业化运维--(6)Mysql之并行复制(MTS)、延迟复制、慢查询、组复制、路由器、MHA高可用主从切换
- 一、并行复制(MTS)
- 二、延迟复制
- 三、慢查询
- 四、组复制(多主模式)
- 五、mysql路由器,服务器分离
- 六、MHA高可用主从切换
- 1、MAH高可用集群配置
- 2、手动切换
- 3、自动切换
Linux企业化运维–(6)Mysql之并行复制(MTS)、延迟复制、慢查询、组复制、路由器、MHA高可用主从切换
一、并行复制(MTS)
适用于多线程并发。基于组的并发复制,可以支持在一个database中,并发执行relaylog中的事务。相同的二进制日志组在master上提交并行应用到slave节点上,没有跨数据库的限制,并且不需要把数据分割到多个数据库。
首先,为什么会有并行复制这个概念呢?
- DBA都应该知道,MySQL的复制是基于binlog的。
- MySQL复制包括两部分,IO线程 和 SQL线程。
- IO线程主要是用于拉取接收Master传递过来的binlog,并将其写入到relay log
- SQL线程主要负责解析relay log,并应用到slave中
- 不管怎么说,IO和SQL线程都是单线程的,然后master却是多线程的,所以难免会有延迟,为了解决这个问题,多线程应运而生了。
- IO多线程? IO没必要多线程,因为IO线程并不是瓶颈啊
- SQL多线程?没错,目前5.6,5.7,8.0 都是在SQL线程上实现了多线程,来提升slave的并发度
在MySQL 5.6版本之前,Slave服务器上有两个线程I/O线程和SQL线程。I/O线程负责接收二进制日志(更准确的说是二进制日志的event),SQL线程进行回放二进制日志。如果在MySQL 5.6版本开启并行复制功能,那么SQL线程就变为了coordinator(协调者)线程,coordinator线程主要负责以前两部分的内容:
1)若判断可以并行执行,那么选择worker线程执行事务的二进制日志。
2)若判断不可以并行执行,如该操作是DDL,亦或者是事务跨schema操作,则等待所有的worker线程执行完成之后,再执行当前的日志。
这意味着coordinator线程并不是仅将日志发送给worker线程,自己也可以回放日志,但是所有可以并行的操作交付由worker线程完成。coordinator线程与worker是典型的生产者与消费者模型。
上述机制实现了基于schema的并行复制存在两个问题,首先是crash safe功能不好做,因为可能之后执行的事务由于并行复制的关系先完成执行,那么当发生crash的时候,这部分的处理逻辑是比较复杂的。从代码上看,5.6这里引入了Low-Water-Mark标记来解决该问题,从设计上看(WL#5569),其是希望借助于日志的幂等性来解决该问题,不过5.6的二进制日志回放还不能实现幂等性。另一个最为关键的问题是这样设计的并行复制效果并不高,如果用户实例仅有一个库,那么就无法实现并行回放,甚至性能会比原来的单线程更差。而单库多表是比多库多表更为常见的一种情形。
MySQL 5.7才可称为真正的并行复制,这其中最为主要的原因就是slave服务器的回放与master是一致的,即master服务器上是怎么并行执行的,那么slave上就怎样进行并行回放。不再有库的并行复制限制,对于二进制日志格式也无特殊的要求(基于库的并行复制也没有要求)。
此处实验接着上一部实验半同步的。
在server1
主机中修改配置文件,设定在mysql中创建表,数据会存在数据库中,打开半同步复制。
vim /etc/my.cnf
///
log-bin=mysql-bin
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1 ##控制打开半同步复制
master_info_repository=TABLE ##在mysql中创建表,数据会存在数据库中,
///
在server2
主机,设定配置文件。
###server2
vim /etc/my.cnf
///
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_slave_enabled=1
master_info_repository=TABLE
##有两个值,分别是file和table,该参数决定了slave记录master的状态,如果参数是file,就会创建master.info文件,磁盘频繁读取文件,会降低执行效率,如果参数值是table,就在mysql中创建slave_master_info的表,数据会存在数据库中,避免影响内存。
slave_parallel_workers=16
##可有16个SQL Thread(coordinator线程)来进行并行复制,不建议设置为1,单线程复制,但是因为要做coordinator协调线程的转发,性能比0还差,效率会更低
slave-parallel-type=LOGICAL_CLOCK
##基于组提交的并行复制方式
slave_preserve_commit_order=1
##实现更小粒度的并行复制,在多线程复制环境下,能够保证从库回放relay log事务的顺序与这些事务在relay log中的顺序完全一致,也就是与主库提交的顺序完全一致。
relay_log_info_repository=TABLE
##明文存储不安全,把relay.info中的信息记录在table中相对安全
relay_log_recovery=ON
##从库意外宕机后,同时从库的relay log也一起损坏了,而主库的日志已经传到了从库,只是从库还没有来得及应用这些日志时,从库会自动放弃所有未执行的relay log,重新生成一个relay log,并将从库的io线程的position重新指向新的relay log。并将sql线程的position退回到跟io线程的position保持一致,重新开始同步,这样在从库中事务不会丢失。
///
/etc/init.d/mysqld restart
进入数据库,查看设定是否生效。
mysql -p
> show variables like 'relay_log%'; ##查看上面的设定是否成功
> use mysql
> show tables; ##slave_master_info
> select * from slave_relay_log_info;
> show processlist;
二、延迟复制
1、mysql本身有延迟,测验延迟多少会对实验产生影响
2、如果主库出现问题,有延迟内的时间从从库恢复数据
并不记录IO延迟,只记录SQL的延迟
在server2
进入数据库,查看从库状态,当前主从延迟为0,停止从库服务。设定主从复制延迟为30s,重新开启从库服务。查看状态,设定成功。
###server2
mysql -p
> show slave status\G; ##sql_delay=0
> stop slave; ##停止服务
> change master to master_delay = 30; ##设定延迟30s复制
> start slave;
> show slave status\G; ##sql_delay=30
此时在server1
插入数据。
###server1
mysql -pwestos
> use westos;
> insert into linux values ('user9','999');
在server2查看,seconds_behind_master
会从30递减到0,30s后,数据会被同步。
###server2
> show slave status\G; ##seconds_behind_master:30 ~ 0
> select * from westos.linux; ##重复执行,直到30s后才会出现user10
> show slave status\G; ##seconds_behind_master:0
当前数据还没有同步。
seconds_behind_master
会从30逐渐递减。
数据同步成功。
三、慢查询
程序中定位一个执行慢的SQL可以根据慢查询日志,默认情况下,慢查询日志禁用,因为开启慢查询日志或多或少的会对mysql的性能产生一些影响。在慢查询日志功能开启时,只有SQL执行时间超过long_query_time参数值的的语句才会在慢查询日志中记录。long_query_time
参数,最小值和默认值分别为0 10,单位为秒。
慢查询日志参数
参数 | 含义 |
slow_query_log | 是否开启慢查询日志 |
long_query_time | 查询阈值,超过了该阈值则记录到慢查询日志中 |
log_output | 如何存储慢查询日志,可选项:FILE或者TABLE |
slow_query_log_file | 以FILE类型存储慢查询日志时的存储位置 |
默认情况下,如果没有为慢查询日志指定名称,默认为host_name-slow.log。
在server1主机中,当前慢查询为关闭状态。设定开启慢查询,慢查询记录会存放在数据目录server1-slow.log文件中。慢查询默认值为10s,设定为5s,执行select sleep(N)
语句。
###server1
> show variables like 'slow%'; ##slow_query_log为OFF
> set global slow_query_log=1; ##开启慢查询日志
> show variables like 'slow%'; ##slow_query_log为ON,慢查询记录会存放在数据目录server1-slow.log文件中
> show variables like 'long%'; ##默认10s
> set long_query_time=5;
> show variables like 'long%'; ##5s
> select sleep(10); ##执行select sleep(N)可以让此语句运行N秒钟
> exit
进入mysql数据目录,查看慢查询日志。
cd /data/mysql
ls
cat server1-slow.log
///
query_time:10.000515
select sleep(10);
四、组复制(多主模式)
底层逻辑:基于二进制日志的复制
在任何一个节点写入,都会将数据发送到其他所有节点进行校验,当任何一个节点校验失败,其他节点不会执行该操作,只有所有节点都校验成功,才会执行该操作。
容错:最起码需要有3个节点,允许一个节点出现即时故障。
组复制(group commit):通过对事务进行分组,优化减少了生成二进制日志所需的操作数。当事务同时提交时,它们将在单个操作中写入到二进制日志中。如果事务能同时提交成功,那么它们就不会共享任何锁,这意味着它们没有冲突,因此可以在Slave上并行执行。所以通过在主机上的二进制日志中添加组提交信息,这些Slave可以并行地安全地运行事务。
在server1,2,3,三台主机关闭mysql,清空数据目录。先关闭mysql,不然清空数据目录之后关闭还是会生成日志数据。
###server2 & server1 & server3
/etc/init.d/mysqld stop ##先关闭,不然清空数据目录之后关闭还是会生成日志
cd /data/mysql
rm -rf *
在server1主机,编辑mysql配置文件,初始化并开启服务。
###server1
vim /etc/my.cnf
///
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" ##不需要的引擎
server-id=1
gtid_mode=ON ##开启gitd复制
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE ##不支持binlog校验
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW ##默认日志格式
plugin_load_add='group_replication.so' ##加载组复制插件
transaction_write_set_extraction=XXHASH64
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" ##UUID号,集群中要一致
group_replication_start_on_boot=off ##不需开机自启
group_replication_local_address="server1:33061"
group_replication_group_seeds="server1:33061,server2:33061,server3:33061" ##解析
group_replication_bootstrap_group=off ##默认关闭, 防止自动创建新的Group
group_replication_ip_whitelist="172.25.24.0/24,127.0.0.1/8" ##安全白名单,默认只允许localhost,加入虚拟机网段
group_replication_single_primary_mode=OFF ##单主模式
group_replication_enforce_update_everywhere_checks=ON ##复制
///
mysqld --initialize --user=mysql ##初始化
/etc/init.d/mysqld start
进入数据库。
mysql -p
> alter user root@'localhost' identified by 'westos';
##给管理员添加密码
> show databases;
> set sql_log_bin=0;
##设为0后,在Master数据库上执行的语句都不记录binlog(想在主库上执行一些操作,但不复制到slave库上,可以通过修改参数sql_log_bin来实现)
> create user rpl_user@'%' identified by 'westos'; ##创建用于组复制的用户,当前语句不纪录binlog
> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; ##授权
> FLUSH PRIVILEGES; ##刷新授权表
> SET SQL_LOG_BIN=1; ##改回1
> CHANGE MASTER TO MASTER_USER='rpl_user',MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery';
##change master to配置和改变slave服务器用于连接master服务器的参数,以便slave服务器读取master服务器的binlog及slave服务器的relay log。同时也更新master info及relay log info信息库。执行该语句前如果从机上slave io及sql线程已经启动,需要先停止(执行stop slave)
> show plugins; ##显示有关服务器插件的信息
> SET GLOBAL group_replication_bootstrap_group=ON; ##标示以后加入集群的服务器以这台服务器为基准,以后加入的就不需要设置
> START GROUP_REPLICATION; ##开启组复制
> SET GLOBAL group_replication_bootstrap_group=OFF;
##如果报错3098,在多主模式下登陆数据库做如下操作:进入数据库,查询集群库的表名,use mysql_innodb_cluster_metadata;showdatabases;查询创建表语句,找到CONSTRAINT开头的部分,每个表都要找,show create 表名\G;(CONSTRAINT 外键名 foreign key(xxx) references xxx(id)),删除外键,多主模式集群不支持外键,删除每个有外键的表,alter table 表名 drop foreign key 外键名;再执行一遍报错的操作(ON-OFF3步)
> select * from performance_schema.replication_group_members;
##该表用于监控MySQL组成员的状态信息(online)
在server2,同样设定组复制,修改配置文件。
###server2
vim /etc/my.cnf
///
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_bin=binlog
log_slave_updates=ON
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="server2:33061"
group_replication_group_seeds="server1:33061,server2:33061,server3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="172.25.24.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
///
mysqld --initialize --user=mysql
/etc/init.d/mysqld start
进入数据库,开启组复制,并进行设定,但不需要设定加入集群的基准,因为一组只需要一个基准就可以,上面已经设定过server1主机为集群基准。
###server2
vim /etc/my.cnf
///
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_bin=binlog
log_slave_updates=ON
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="server2:33061"
group_replication_group_seeds="server1:33061,server2:33061,server3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="172.25.24.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
///
mysqld --initialize --user=mysql
/etc/init.d/mysqld start
mysql -p
> alter user root@'localhost' identified by 'westos';
> set sql_log_bin=0;
> create user rpl_user@'%' identified by 'westos';
> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
> set sql_log_bin=1;
> CHANGE MASTER TO MASTER_USER='rpl_user',MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery';
> START GROUP_REPLICATION;
但因为数据不一致,设定即使该组中缺失一些事务(joiner节点比组中的事务还要多),也允许joiner节点加入该组。所以需要进行设定,该操作可以在之前修改配置文件时,直接加入配置中。
> set global group_replication_allow_local_disjoint_gtids_join=1; ##数据不一致,设定即使该组中缺失一些事务(joiner节点比组中的事务还要多),也允许joiner节点加入该组
> START GROUP_REPLICATION;
在server1中,查看组成员是否添加成功。
###server1
> select * from performance_schema.replication_group_members; ##组成员server2
在server3中,同上,编辑配置文件。
###server3
vim /etc/my.cnf
///
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server-id=3
gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_bin=binlog
log_slave_updates=ON
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="server3:33061"
group_replication_group_seeds="server1:33061,server2:33061,server3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="172.25.24.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
group_replication_allow_local_disjoint_gtids_join=ON
///
mysqld --initialize --user=mysql
/etc/init.d/mysqld start
进入数据库,进行设定。
mysql -p
> alter user root@'localhost' identified by 'westos';
> set sql_log_bin=0;
> create user rpl_user@'%' identified by 'westos';
> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
> set sql_log_bin=1;
> CHANGE MASTER TO MASTER_USER='rpl_user',MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery';
> set global group_replication_allow_local_disjoint_gtids_join=1; ##如果报错则加上这句
> START GROUP_REPLICATION;
在server1进行查看。插入数据做测试,查看另外两台主机是否成功同步。
###server1
> select * from performance_schema.replication_group_members;
> show databases;
> create database test;
> use test
> create table t1(c1 int primary key, c2 text not null); ##主键,必须有
> insert into t1 values (1, 'Luis');
> select * from t1;
在server2和server3进行查看。
###server2
mysql -pwestos
> use test
> show tables;
> select * from t1;
###server3
> use test
> show tables;
> select * from t1;
在server2插入数据,在另外两台主机查看是否同步成功。
###server2
> insert into t1 values (2, 'zxc');
###server3 & server1
> select * from t1;
在server3插入数据,在另外两台主机查看是否同步成功。
###server3
> insert into t1 values (3, 'asd');
###server2 & server1
> select * from t1;
- 扩展
如果MySQL启用了性能监控数据库performance_schema,则在搭建组复制的时候会创建2个表:
performance_schema.replication_group_members
performance_schema.replication_group_member_stats
由复制插件创建的复制通道被命名为:
group_replication_recovery:此通道用于与分布式恢复阶段相关的复制更改
group_replication_applier:此通道用于来自组的传入更改。
这里需要关注组成员的数量已经成员状态(MEMBER_STATE):
状态 | 描述 | 组同步 |
ONLINE | 该成员可以作为一个具有所有功能的组成员,客户端可以开始连接执行事务 | 是 |
RECOVERING | 该成员正在恢复成为一个活跃的组成员 | 否 |
OFFLINE | 插件已加载但成员不属于任何组 | 否 |
ERROR | 恢复阶段或者应用更改时出现错误,server就会进入此状态 | 否 |
UNREACHABLE | 每当本地故障检测器怀疑给定服务器无法访问时(例如由于非自愿断开连接),它将显示该服务器的状态为UNREACHABLE | 否 |
五、mysql路由器,服务器分离
访问mysql路由器,然后由mysql路由器访问后端服务器server主机,确保当某一台主机宕掉后,可以迅速启用其他主机。相当于负载均衡。
基于主从复制或者组复制(多主模式)的集群,通过访问不同端口实现读写分离。
前提:组复制,多主模式三台主机均online
实验准备:
再封装一台虚拟机,hostname
为server4,ip
为172.25.24.4。详情见创建快照。
ssh连接server4。安装mysql读写分离组件。编辑配置文件,设定只读端口和读写端口,并开启服务。
lftp 172.25.254.250
> ls
> cd pub/docs/mysql
> get mysql-router-community-8.0.21-1.el7.x86_64.rpm
> exit
rpm -ivh mysql-router-community-8.0.21-1.el7.x86_64.rpm
cd /etc/mysqlrouter/
ls ##mysqlrouter.conf
vim mysqlrouter.conf
///
[routing:ro] ##只读
bind_address = 0.0.0.0
bind_port = 7001
destinations = 172.25.24.1:3306,172.25.24.2:3306,172.25.24.3:3306
routing_strategy = round-robin
[routing:rw] ##读写
bind_address = 0.0.0.0
bind_port = 7002
destinations = 172.25.24.1:3306,172.25.24.2:3306,172.25.24.3:3306
routing_strategy = first-available ##第一可用
///
systemctl start mysqlrouter.service ##开启服务
netstat -antlp ##7001,7002
在server1主机,开启mysql,查看是否有全局用户,有则授权用户,刷新授权表。
###server1
systemctl start mysql
mysql -pwestos
> select * from user; ##查看是否有全局用户;
> grant all on test.* to yun@'%' identified by 'westos'; ##授权用户
> flush privileges; ##刷新授权表
> exit
在真机使用授权用户登录7001
端口,可以看到test库即可,因为7001为只读端口。
mysql -h 172.25.24.4 -P 7001 -u yun -p ##可以登陆
> show databases; ##可以看到test库
在四台虚拟机安装lsof
,用于查看端口占用。
###server4 & 1 & 2 & 3
yum install -y lsof
在server4主机查看mysql端口,可以,看到看到250即真机与4号机相连。
###server4
netstat -antlp | grep :7001 ##可以看到250与4号机相连
在server1主机可以看到server1与server4相连,即server4只作中转调度。
###server1
lsof -i :3306
当前server2和server3主机3306端口并没有连接。
###server2 & 3
lsof -i :3306 ##为空,没有连接
此时在真机退出数据库,重新进入,此时server4会换另一台主机连接。
###真机
> exit
mysql -h 172.25.24.4 -P 7001 -u yun -p
###server2
lsof -i :3306 ##可以看到server2与server4相连
在真机退出,使用7002
端口登录,在server1查看,可以看到server1与server4相连。
###真机
> exit
mysql -h 172.25.24.4 -P 7002 -u yun -p ##7002端口
###server1
lsof -i :3306 ##可以看到server1与server4相连
在真机插入数据,在server1主机可以查看到数据。此时关闭mysql服务。
###真机
> insert into test.t1 values (4, 'qwe');
###server1
> select * from t1; ##4,qwe
> exit
/etc/init.d/mysqld stop
可以在真机看到断掉重新连接的过程,此时与server4相连的主机会变化,变成server2。
###真机
> show databases; ##lost connection
> show databases; ##trying to reconnect... ---> test
###server2
lsof -i :3306 ##可以看到server2与server4相连
实验结束,开启server1的mysql。
###server1
/etc/init.d/mysqld start
六、MHA高可用主从切换
server1为管理端,可以管理多个一主多从的复制组。
Master HA,对主节点进行监控,可实现自动故障转移至其它从节点;通过提升某一从节点为新的主节点,基于主从复制实现,还需要客户端配合实现,目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库。
MHA工作原理
1 从宕机崩溃的master保存二进制日志事件(binlog events)
2 识别含有最新更新的slave
3 应用差异的中继日志(relay log)到其他的slave
4 应用从master保存的二进制日志事件(binlog events)
5 提升一个slave为新的master
6 使其他的slave连接新的master进行复制
[注意] MHA需要基于ssh,key验证登入方法
1、MAH高可用集群配置
在server1,2,3主机关闭mysql服务,并且清空数据目录。
###server1 & 2 & 3
/etc/init.d/mysqld stop
cd /data/mysql
rm -rf *
在server1主机编辑配置mysql文件,对数据库进行安全初始化,即不需要设定密码,开启mysql。
###server1
vim /etc/my.cnf
///
server-id=1
gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
///
mysqld --initialize-insecure --user=mysql
/etc/init.d/mysqld start
进入数据库,进行用户授权。
mysql
> grant replication slave on *.* to repl@'%' identified by 'westos';
在server2主机,进行同样配置。进入数据库,设定主库为server1主机,开启从库服务。
###server2
vim /etc/my.cnf
///
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
///
mysqld --initialize-insecure --user=mysql
/etc/init.d/mysqld start
mysql
> change master to master_host='172.25.24.1', master_user='repl', master_password='westos', master_auto_position = 1;
> start slave;
> show slave status\G;
在server3进行server2相同配置。
###server3
vim /etc/my.cnf
///
server-id=3
gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
///
mysqld --initialize-insecure --user=mysql
/etc/init.d/mysqld start
mysql
> change master to master_host='172.25.24.1', master_user='repl', master_password='westos', master_auto_position = 1;
> start slave;
> show slave status\G;
在server4主机,关闭mysqlrouter
服务。安装MHA高可用的master
rpm包及其依赖性。并将MHAnode
节点rpm包复制至其他三台主机。
###server4
cd
systemctl stop mysqlrouter.service
lftp 172.25.254.250
> cd pub/docs/mysql
> mirror MHA-7
> exit
cd MHA-7/
ls
yum install mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
yum install -y *.rpm
scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server1:
scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server2:
scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server3:
在server1,2,3主机安装MAH节点rpm包。
###server1 & 2 & 3
cd
yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
在server4主机建立高可用目录,编辑配置文件。
###server4
mkdir /etc/masterha
cd MHA-7/
tar zxf mha4mysql-manager-0.58.tar.gz
ls
cd mha4mysql-manager-0.58/
ls
cd samples/conf/
cat app1.cnf ##模板
cd /etc/masterha
vim app1.conf
///
[server default]
manager_workdir=/etc/masterha #manager工作目录
manager_log=/etc/masterha/mha.log #manager日志文件
master_binlog_dir=/data/mysql #mysql主服务器的binlog目录
#master_ip_failover_script=/usr/bin/master_ip_failover #failover自动切换脚本
#master_ip_online_change_script= /usr/local/bin/master_ip_online_change #手动切换脚本
user=root #mysql主从节点的管理员用户密码,确保可以从远程登陆
password=westos
ping_interval=3 #发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp #远端mysql在发生切换时binlog的保存位置
repl_user=repl #主从复制用户密码
repl_password=westos
secondary_check_script=/usr/bin/masterha_secondary_check -s 172.25.0.2 -s 172.25.0.3
ssh_user=root #ssh用户名
///
在server1主机进入数据库,重置密码并且授权。
###server1
mysql
> alter user root@localhost identified by 'westos';
> grant all on *.* to root@'%' identified by 'westos';
此时在server2不使用密码进入数据库,是被拒绝的,因为在server1进行了密码重置。使用密码可以进入数据库,也可以登录server1主机数据库。
###server2
mysql ##被拒绝
mysql -pwestos
mysql -h 172.25.24.1 -u root -pwestos
在server4主机编辑配置文件,设定其他三台主机,当server1宕机,则server2接管master,但server3始终时slave。
###server4
vim /etc/masterha/add1.conf
///
[server1]
hostname=172.25.24.1
port=3306
[server2]
hostname=172.25.24.2
port=3306
candidate_master=1 ##指定failover时此slave会接管master,即使数据不是最新的。
check_repl_delay=0 ##默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
[server3]
hostname=172.25.24.3
port=3306
no_master=1 ##始终是slave
///
2、手动切换
在server4主机检查整个集群配置文件配置。
masterha_check_ssh --conf=/etc/masterha/app1.conf
此时在server1主机产生公钥私钥,并将公钥私钥复制到远程机器中。这样主机之间可以实现免密登录。
###server1
cd
ssh-keygen
ssh-copy-id server1
ssh-copy-id server2
ssh-copy-id server3
ssh-copy-id server4
cd
scp -r .ssh/ server2:
scp -r .ssh/ server3:
scp -r .ssh/ server4:
在server4主机检测MHA部署及配置是否OK,借助于MHA自带的masterha_check_ssh
以及masterha_check_repl
脚本来检测。masterha_check_repl检测是保证MHA成功切换的重要一步。然后开始手动设定主库切换。
###server4
masterha_check_ssh --conf=/etc/masterha/app1.conf
masterha_check_repl --conf=/etc/masterha/app1.conf
masterha_master_switch --conf=/etc/masterha/app1.conf --master_state=alive --new_master_host=172.25.24.2 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000 ##开始在线主库切换操作,手动设定server2为master主机,yes,yes,yes
切换成功后,可以在server1
和server3
主机看到mysql当前状态为master
为server2
主机。在server2查看从库状态为空,即当前不是从库。
###server1 & server3
mysql -pwestos
> show slave status\G; ##可以看到状态,Master_Host: 172.25.24.2
###server2
mysql -pwestos
> show slave status\G; ##为空
实验完成后,重新将server1设置为master。
扩展:
masterha_check_repl检测步骤
a、读取配置文件
b、检测配置文件中列出的mysql服务器(识别主从)
c、检测从库配置信息
read_only参数
relay_log_purge参数
复制过滤规则
d、ssh等效性验证
e、检测主库保存binlog脚本(save_binary_logs) ,主要是用于在master死掉后从binlog读取日志
f、检测各从库能否apply差量binlog(apply_diff_relay_logs)
g、检测IP切换,如果有部署脚本
3、自动切换
检测配置,当前master为server1。
###server4
masterha_manager --conf=/etc/masterha/app1.conf &
cd /etc/masterha/
ls ##app1.master_status.health-->27160 0:PING_OK master:172.25.24.1
cat app1.master_status.health
在server1主机关闭mysql服务。
###server1
/etc/init.d/mysqld stop ##server1为master,所以需要关闭
此时server4主机显示master
主机done。
###server4
[1]+ Done
ls ##app1.failover.complete
在server2查看从库状态为空,即当前已成功切换成master。在server3查看,当前master为server2。
###server2
> show slave status\G; ##为空
###server3
> show slave status\G; ##可以看到状态,Master_Host: 172.25.24.2