环境软件版本

此处我采用虚拟机安装了4台CentOS,版本是7.7。MySQL版本采用的是5.7.28。

架构

架构如图所示,4台机器的IP和角色如下图:


mysql怎么看是否集群_mysql


mysql怎么看是否集群_mysql_02



环境安装过程

1、MySQL安装

下载


wegt https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar


解压


tar xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
mysql-community-embedded-5.7.28-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
mysql-community-devel-5.7.28-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.28-1.el7.x86_64.rpm
mysql-community-libs-5.7.28-1.el7.x86_64.rpm
mysql-community-test-5.7.28-1.el7.x86_64.rpm
mysql-community-common-5.7.28-1.el7.x86_64.rpm
mysql-community-embedded-devel-5.7.28-1.el7.x86_64.rpm
mysql-community-client-5.7.28-1.el7.x86_64.rpm
mysql-community-server-5.7.28-1.el7.x86_64.rpm


安装

首先,要移除CentOS自带的mariadb-libs,不然会提示冲突,其次要安装net-tools工具(可采用rpm -qa|grep net-tools查看是否已安装)。


yum -y remove mariadb-libs
yum -y install net-tools


由于MySQL的server服务依赖了common、libs、client,所以需要按照以下顺序依次安装。

RPM是Red Hat公司随Redhat Linux推出的一个软件包管理器,通过它能够更加方便地实现软件的安装。rpm常用的命令有以下几个:


-i, --install 安装软件包
-v, --verbose 可视化,提供更多的详细信息的输出
-h, --hash 显示安装进度
-U, --upgrade=<packagefile>+ 升级软件包
-e, --erase=<package>+ 卸载软件包
--nodeps  不验证软件包的依赖


组合可得到几个常用命令:


安装软件:rpm -ivh rpm包名
升级软件:rpm -Uvh rpm包名
卸载软件:rpm -e rpm包名
查看某个包是否被安装 rpm -qa | grep 软件名称


下面就利用安装命令来安装MySQL:


rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-5.7.28-1.el7.x86_64.rpm


启动

Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器。

Systemd是一个系统管理守护进程、工具和库的集合,用于取代System V初始进程。Systemd的功能是用于集中管理和配置类UNIX系统。大部分的Linux发行版都使用了Systemd,CentOS 7开始也是,所以此处采用systemctl来对mysqld服务进行管理。

Systemd管理的服务被叫做unit,其命令格式如下:


systemctl [command] [unit]


常用命令如下:


启动服务:systemctl start xxx
关闭服务:systemctl stop xxx
杀掉服务:systemctl kill xxx(一般用于服务不能正常停止时)
查看服务运行状态:systemctl status xxx
重启服务:systemctl restart xxx
开机自动运行服务:systemctl enable xxx
检查某服务是否开机自启:systemctl is-enabled xxx
关闭开机自动运行:systemctl disable xxx
列出所有已安装的服务:systemctl list-unit-files


初始化用户


mysqld --initialize --user=mysql


查看初始密码


cat /var/log/mysqld.log | grep password


启动MySQL服务


systemctl start mysqld


配置为开机启动


systemctl enable mysqld


常用配置

使用初始密码登录MySQL


mysql -u root -p


接下来修改默认密码,但是MySQL默认的安全策略不允许使用简单字符,所以要修改MySQL的安全策略,建议仅在个人开发环境这么做,生产环境不要修改。

首先把密码验证策略等级降低,其次把密码长度校验改为6位,然后就可以把密码设置为简单字符。


mysql> set global validate_password_policy=LOW;
mysql> set global validate_password_length=6;
mysql> SHOW VARIABLES LIKE 'validate_password%';
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| validate_password_check_user_name    | OFF   |
| validate_password_dictionary_file    |       |
| validate_password_length             | 6     |
| validate_password_mixed_case_count   | 1     |
| validate_password_number_count       | 1     |
| validate_password_policy             | LOW   |
| validate_password_special_char_count | 1     |
+--------------------------------------+-------+

mysql> SET PASSWORD = PASSWORD('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)


最后一步,给root用户授权远程访问,同样是建议仅在个人开发环境设置。


mysql> use mysql;
mysql> GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;


解释一下GRANT命令:


GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
GRANT:授权
ALL PRIVILEGES:当前用户的所有权限
ON:在哪里
*.*:对所有数据库和所有表的相应操作权限
TO:给谁
‘root’@’%’:root用户的所有ip
IDENTIFIED BY ‘123456’:通过什么鉴定,此处为密码123456
WITH GRANT OPTION:允许级联授权
连起来就是授权root用户使用密码123456在任何地方操作任何库和表


此时可以看到,用户表里面已经多了一条记录。


mysql> select * from user G
*************************** 4. row ***************************
                  Host: %
                  User: root
           ...
                plugin: mysql_native_password
 authentication_string: *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
      password_expired: N
 password_last_changed: 2020-03-07 16:35:29
     password_lifetime: NULL
        account_locked: N


同样,采用往user表里面增加一条记录再加flush privileges; 的做法也可以实现让root用户远程登录,不过GRANT语句更方便。

2、关闭防火墙

不同的MySQL直接要互相访问,需要关闭Linux的防火墙,否则就要在配置/etc/sysconfig/iptables中增加规则。配置防火墙不是本次的重点,所以四台服务器均关闭防火墙。


systemctl stop firewalld


3、配置MySQL主从同步

Master节点

修改Master配置文件


[mysqld]
log_bin=mysql-bin
server-id=1
sync-binlog=1 # 每次写入都同步到binlog
binlog-ignore-db=performance_schema # 忽略不同步
binlog-ignore-db=information_schema
binlog-ignore-db=sys


重启服务


systemctl restart mysqld


主库给从库授权

在MySQL命令行执行如下命令:


grant replication slave on *.* to root@'%' identified by '123456';
grant all privileges on *.* to root@'%' identified by '123456';

flush privileges;
show master status;


Slave节点

修改Slave配置文件,两台Slave的server-id分别设置为2和3


[mysqld]
server-id=2
sync-binlog=1 # 每次写入都同步到binlog
binlog-ignore-db=performance_schema # 忽略不同步
binlog-ignore-db=information_schema
binlog-ignore-db=sys
relay_log=mysql-relay-bin  #中继日志名字
relay_log_purge=0
read_only=1


重启服务


systemctl restart mysqld


开启同步

在Slave节点的MySQL命令行执行如下命令:


change master to master_host='192.168.31.199',master_port=3306,master_user='root',master_password='123456',master_log_file='mysql-bin.000007',master_log_pos=154;

start slave; // 开启同步


4、配置半同步复制

Master节点

安装插件


install plugin rpl_semi_sync_master soname 'semisync_master.so';
show variables like '%semi%'


修改配置文件


# 自动开启半同步复制 
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_master_timeout=1000


重启服务


systemctl restart mysqld


Slave节点

两台Slave节点都执行以下步骤。

安装插件


install plugin rpl_semi_sync_slave soname 'semisync_slave.so';


修改配置文件


# 自动开启半同步复制 
rpl_semi_sync_slave_enabled=ON


重启服务


systemctl restart mysqld


检查半同步状态

首先通过MySQL命令行检查参数的方式,查看半同步是否开启。


show variables like '%semi%'


然后通过MySQL日志再次确认。


cat /var/log/mysqld.log


可以看到日志中已经启动半同步:


Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000005, 154)



配置MHA

1、四台机器ssh互通

第一台机器199先生成公钥和秘钥。


ssh-keygen -t rsa


第一台机器199把公钥写入到authorized_keys文件。


cat id_rsa.pub > authorized_keys


第二台机器165生成秘钥之后就把第一台199的authorized_keys拷贝过来,然后把自己的公钥追加进去。


scp 192.168.31.199:/root/.ssh/authorized_keys .
 cat id_rsa.pub >> authorized_keys


第三台再如法炮制,拷贝第二台的authorized_keys文件并写入自己的公钥,这样到第四台的时候,这个authorized_keys文件就写入了四台机器的公钥,再把这个authorized_keys文件倒序覆盖回前面三台机器,就实现了四台机器的ssh互通。

2、下载MHA安装包

MySQL5.7对应的MHA版本是0.5.8,所以在GitHub上找到对应的rpm包进行下载,Manager和Node的安装包需要分别下载:

https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58

https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58

安装MHA

首先将Manager和Node的安装包分别上传到对应的服务器。

Node节点

Node节点只需要安装mha4mysql-node。

MHA的Node依赖于perl-DBD-MySQL,所以要先安装perl-DBD-MySQL。


yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm


Manager节点

软件安装

Manager节点需要安装mha4mysql-node和mha4mysql-manager。

MHA的Manager又依赖了perl-Config-Tiny、perl-Log-Dispatch、perl-Parallel-ForkManager,也分别进行安装。


yum install perl-DBD-MySQL -y
 rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
 yum install perl-Config-Tiny -y


最终在成功下载(http://rpm.pbone.net/)了这些包并依次安装之后,perl-Log-Dispatch安装上了。

然而,perl-Log-Dispatch和perl-Parallel-ForkManager这两个被依赖包在yum仓库找不到,于是开始了一个漫长的rpm安装perl-Log-Dispatch的过程。


perl-Email-Date-Format-1.002-17cnt7.noarch.rpm
perl-IO-Socket-SSL-1.982-1.2.noarch.rpm
perl-Log-Dispatch-2.41-2.2.noarch.rpm
perl-Mail-Sender-0.8.23-1.el7.noarch.rpm
perl-Mail-Sendmail-0.79_16-5.1.noarch.rpm
perl-MailTools-2.12-2.el7.noarch.rpm
perl-MIME-Lite-3.030-1.el7.noarch.rpm
perl-MIME-Types-2.04-1cnt7.noarch.rpm
perl-Net-SMTP-SSL-1.01-13.el7.noarch.rpm
perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
perl-Params-Validate-0.91-2.2.x86_64.rpm
perl-Params-Validate-1.08-4.el7.src.rpm // 这个版本高了
perl-Sys-Syslog-0.33-3.el7.x86_64.rpm


接着perl-Parallel-ForkManager也安装上了。

最终,mha4mysql-manager终于安装好了。


rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm


PS:如果能连上有安装源的yum仓库,不用这么麻烦,直接yum install即可。

配置文件

Manager 节点需要为每个监控的 Master/Slave 集群提供一个专用的配置文件,而所有的 Master/Slave 集群也可共享全局配置

本次只监控一组,Master/Slave集群,就只采用一套配置文件。

创建目录 /usr/local/masterha/app1 和 /var/log/masterha/app1


mkdir -p /usr/local/masterha/app1
mkdir -p /var/log/masterha/app1


在199、165、142三台机器上也分别创建/usr/local/masterha/app1目录。

在Manager节点上添加App1的配置文件:/etc/app1.cnf,实际配置的时候要去掉注释。


[server default]
user=root  # mysql用戶名
password=123456 # mysql密码
ssh_user=root  # ssh免密钥登录的帐号名
repl_user=root  # mysql复制帐号,主从配置里配的
repl_password=123456  # mysql复制账号密码
ping_interval=1   # ping间隔,用来检测master是否正常,默认是3秒,尝试三次没有回应的时候自动进行failover

manager_workdir=/usr/local/masterha/app1
manager_log=/var/log/masterha/app1/app1.log
remote_workdir=/usr/local/masterha/app1
master_binlog_dir=/var/lib/mysql

[server1]
hostname=192.168.31.199
candidate_master=1

[server2]
hostname=192.168.31.165
candidate_master=1

[server3]
hostname=192.168.31.142
no_master=1


配置检测

执行ssh通信检测

在Manager节点上执行:


masterha_check_ssh -conf=/etc/app1.cnf


有问题解决问题,直到出现“All SSH connection tests passed successfully.”证明ssh通信没有问题。

检查MySQL复制集群的连接配置

在Manager节点上执行:


masterha_check_repl -conf=/etc/app1.cnf


有问题解决问题,直到出现“MySQL Replication Health is OK.”证明MySQL复制集群的连接配置没有问题。

启动MHA

在 Manager 节点上执行以下命令来启动 MHA:


nohup masterha_manager -conf=/etc/app1.cnf &> /var/log/masterha/manager.log &


启动成功以后,检查Master 节点的状态:


masterha_check_status -conf=/etc/app1.cnf



测试MHA故障转移

模拟主节点崩溃

在MHA的Manager节点124上面打开日志:


tail -200f /var/log/masterha/app1/app1.log


在Master节点199上关闭MySQL服务,模拟主节点崩溃


systemctl stop mysqld


到165机器上查看,变成主节点了


show master status;


执行主从切换

等199主机启动后,先作为165的从节点完成数据同步之后,可以再次切换回原来的199主机。记得不仅仅要切换MHA,也要切换MySQL节点的主从状态。


masterha_master_switch --conf=/etc/app1.cnf --master_state=alive --new_master_host=192.168.31.199 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000



遇到的问题

主从节点配置

配置主从后,检查从节点状态,发现报错:


Last_IO_Errno: 1593
 Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
 cat /var/lib/mysql/auto.cnf


然后去Mater和Slave节点检查UUIDs。


cat /var/lib/mysql/auto.cnf


发现从节点和主节点的UUIDs果然是一样的,此处是因为我偷了个懒,把199服务器装好之后直接复制虚拟机磁盘,导入Parallels生成了另外两台从节点。

解决办法如下:


systemctl stop mysqld.service
rm -rf /var/lib/mysql/auto.cnf
systemctl start mysqld.service


之后MySQL会重新生成Server UUIDs。

此时通过show slave status查看Slave状态,又报了另外一个错误:


Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'


这是因为一开始搭建主从同步之后并没有成功,我在Master执行了一些命令,没有同步到Slave,导致Slave的日志读取位置发生不一致。

此处有两种做法:第一种是从新去Master节点查看最新的pos,然后重新设置为最新pos,但是这种做法会丢失数据。第二种是正确的做法:


stop slave;
reset slave;
start slave;


先停止Slave,然后重置Slave,它的作用是“删除SLAVE数据库的relaylog日志文件,并重新启用新的relaylog文件”,然后再重启Slave。

我此处文件改动比较小,采用这种做法不会丢失数据,但是如果数据量比较大了,这种做法同步起来就会比较耗时了。

MHA安装

安装perl-DBD-MySQL的过程中遇到了一个报错,提示缺少libmysqlclient.so.18。


Error: Package: perl-DBD-MySQL-4.023-6.el7.x86_64 (base)
           Requires: libmysqlclient.so.18()(64bit)
Error: Package: perl-DBD-MySQL-4.023-6.el7.x86_64 (base)
           Requires: libmysqlclient.so.18(libmysqlclient_18)(64bit)


这是由于之前安装MySQL的时候没有把所有的包都安装,解决办法,重新安装libs-compat包。


rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm


MHA连接配置检测失败

执行命令masterha_check_repl -conf=/etc/app1.cnf后报错:


[error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln364] None of slaves can be master. Check failover configuration file or log-bin settings in my.cnf


发现是两个从节点没有配置log-bin日志,所以需要在从节点开启log-bin日志。在从节点的配置文件增加“log_bin=mysql-bin”;

之后执行又报了错误:


[error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln443] Binlog filtering check failed on 192.168.31.165(192.168.31.165:3306)! All log-bin enabled servers must have same binlog filtering rules (same binlog-do-db and binlog-ignore-db). Check SHOW MASTER STATUS output and set my.cnf correctly.


于是在各Slave节点增加以下配置:


sync-binlog=1 #每次写入都同步到binlog
binlog_format=ROW
binlog-ignore-db=performance_schema #忽略不同步
binlog-ignore-db=information_schema
binlog-ignore-db=sys


不小心在主库上启动了salve,在执行masterha_check_repl -conf=/etc/app1.cnf时就报错:


Fri May 29 00:29:14 2020 - [info] Slaves settings check done.
Fri May 29 00:29:14 2020 - [info] 
192.168.31.199(192.168.31.199:3306) (current master)
 +--192.168.31.199(192.168.31.199:3306)
 +--192.168.31.165(192.168.31.165:3306)
 +--192.168.31.142(192.168.31.142:3306)

Fri May 29 00:29:14 2020 - [info] Checking replication health on 192.168.31.199..
Fri May 29 00:29:14 2020 - [error][/usr/share/perl5/vendor_perl/MHA/Server.pm, ln490] Slave IO thread is not running on 192.168.31.199(192.168.31.199:3306)
Fri May 29 00:29:14 2020 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln1526]  failed!
Fri May 29 00:29:14 2020 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations.  at /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm line 420.


在主库上停止salve,然后执行reset slave all。