一、系统环境与软件版本
系统&软件 | 版本 |
---|---|
VMware Workstation | 15 Pro |
CentOS | 7.6.1810 |
MySQL | 5.7.32 |
Xshell | 7 |
Xftp | 7 |
Tips: 查看 CentOS
版本
cat /etc/redhat-release
二、环境架构介绍
机器名称 | IP | 角色 | 权限 |
---|---|---|---|
MySQL_Master | 192.168.32.102 | 数据库Master | 可读写,主库 |
MySQL_Slave1 | 192.168.32.103 | 数据库Slave | 只读,从库 |
MySQL_Slave2 | 192.168.32.104 | 数据库Slave | 只读,从库 |
MySQL_MHA | 192.168.32.105 | MHA Manager | 高可用监控 |
架构图
三、MySQL 安装
可能用到的 Linux 命令:
# 查看防火墙状态:
systemctl status firewalld.service
# 启动防火墙:
systemctl start firewalld.service
# 关闭防火墙:
systemctl stop firewalld.service
# 重启防火墙:
systemctl restart firewalld.service
# 开机自启防火墙:
systemctl enable firewalld.service
# 禁止自启防火墙:
systemctl disable firewalld.service
# 修改本机ip
vim /etc/sysconfig/network-scripts/ifcfg-ens33
# 重启网络服务
service network restart
可能会遇到的坑
如果你 MySQL
只安装了一台服务器,而其他两台都是靠虚拟机克隆得到的,那么你一定要注意:
-
my.cnf
文件中的server-id
属性的值一定要再三确认,不可重复。 -
如果你通过
show slave status \G;
命令查看从库属性时,发现Slave_IO_Running
这个属性的值一直为No
,而且无论怎么重启MySQL
都不管用的时候,那么你需要确认如下四件事:- 主从库之间的计算机网络是否通畅。
- 主库是否已经完成了对从库的授权
- 从库中
Master_Log_File
和Read_Master_Log_Pos
的值是否与主库的信息一致。 - 最后一条也是找遍全网都不一定找的到的一条就是:检查从库的
MySQL server-uuid
是否与主库的重复了。该信息保存在数据库配置文件my.cnf
中的datadir
属性所对应的目录下的auto.cnf
文件中。随便修改一下server-uuid
的值让每台机器的值保持不同后重启MySQL
服务即可。
-
主从复制都配置都没事,但是为啥需要同步的
Database
主库有,从库里没有呢?这是因为MySQL
集群不会帮你创建数据库它只维护库里的内容,所以数据库的创建还是需要你自己完成的。 -
MHA
masterha_check_repl --conf=/etc/mha/app1.cnf
命令报如下错误:报错内容:
Slave IO thread is not running on 192.168.32.102(192.168.32.102:3306)
报错原因:
102
服务器作为MySQL Master
不小心执行了start slave
,所以检查会报错处理方式:在
MySQL Master
服务器上的MySQL
内执行如下命令:stop slave; reset slave all;
-
MHA Manager
服务器成功测试过一次主从切换后再次演示不可用了报错原因:
mha
服务将MHA Manager
服务器上的/etc/mha/app1.cnf
文件修改了,MySQL
主从授权也发生了变化处理方式:
# 启动 MySQL Master 节点数据库(102 服务器) service mysql start # 进入 MySQL 查询 Master 状态 mysql> show master status; # 进入另一台 MySQL Slave 节点(104 服务器) mysql> stop slave; mysql> change master to master_host='192.168.32.102', master_user='root',master_password='root',master_port=3306, master_log_file='mysql-bin.000009',master_log_pos=154; mysql> start slvae; # 进入当前 MySQL Master 服务器(103 服务器) mysql> change master to master_host='192.168.32.102', master_user='root',master_password='root',master_port=3306, master_log_file='mysql-bin.000009',master_log_pos=154; mysql> start slvae; # 修改 HMA Manager 配置文件 vim /etc/mha/app1.cnf # 主从复制功能检测 masterha_check_repl --conf=/etc/mha/app1.cnf
1、卸载以前的 MySQL 和 mariadb-libs
rpm -qa|grep -i mysql
rpm -e 包名 --nodeps
rpm -qa|grep mariadb
rpm -e 包名 --nodeps
2、安装 MySQL
安装文件:mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz
# 解压安装文件
tar -zxvf mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz
# 重命名文件夹
mv mysql-5.7.32-linux-glibc2.12-x86_64 mysql-5.7.32
# 创建 MySQL 安装目录
mkdir /usr/local/mysql
# 将解压出的安装文件移动到 MySQL 安装目录
mv mysql-5.7.32 /usr/local/mysql/
# 添加 mysql 用户组
groupadd mysql
# 创建用户 mysql 到用户组 mysql(使用-r参数表示mysql用户是一个系统用户,不能登录)
useradd -r -g mysql mysql
# 查看 mysql 用户的信息
id mysql
# 手动创建 MySQL 数据存放目录
mkdir /usr/local/mysql/datafile
# 修改 MySQL 文件所属用户和组
chown -R mysql:mysql /usr/local/mysql/
# 删除老旧的 MySQL 配置文件
rm -rf my.cnf
# 创建 MySQL 配置文件
touch /etc/my.cnf
# 编辑 MySQL 配置文件
vim my.cnf
以下为 my.cnf 文件内容
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld]
init-connect='SET NAMES utf8'
# 根据自己的安装目录填写
basedir=/usr/local/mysql/mysql-5.7.32
# 根据自己的 MySQL 数据目录填写
datadir=/usr/local/mysql/datafile
socket=/tmp/mysql.sock
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
3、运行 MySQL
# 初始化 MySQL (注意:mysqld --initialize-insecure初始化后的mysql是没有密码的)
/usr/local/mysql/mysql-5.7.32/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql/mysql-5.7.32/bin --datadir=/usr/local/mysql/datafile
# 收回 MySQL 安装目录权限
chown -R root:root /usr/local/mysql/mysql-5.7.32
# 启动 MySQL (看到启动信息后敲一下 Enter)
/usr/local/mysql/mysql-5.7.32/bin/mysqld_safe --user=mysql &
# 登录 MySQL (注意:由于没有密码,所以 Enter password: 时直接回车即可)
/usr/local/mysql/mysql-5.7.32/bin/mysql -u root -p
# 修改 MySQL root 用户密码
use mysql
update user set authentication_string=password('这里填你设置的密码') where user='root';
flush privileges;
exit;
# 重新登录 (注意:此次登录就需要输入密码了)
/usr/local/mysql/mysql-5.7.32/bin/mysql -u root -p
# 设置外网访问权限
use mysql
update user set host='%' where user ='root';
flush privileges;
# 没问题,退出
exit;
4、将 MySQL 设置为开机启动
# 复制 MySQL 启动脚本
cp /usr/local/mysql/mysql-5.7.32/support-files/mysql.server /etc/init.d/mysql
# 添加服务
chkconfig --add mysql
# 显示服务列表
chkconfig --list
# 设置开机自启
chkconfig --level 345 mysql on
# 测试 MySQL 服务是否可用
service mysql status
service mysql stop
service mysql start
四、MySQL MHA配置
1、配置 MySQL_Master 节点
安装主库的半同步复制插件
# 登录MySQL,在MySQL命令行执行如下命令
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
创建 binlog 日志文件存放路径
# 递归创建日志目录
mkdir -p /var/mysql/log
# 修改日志目录所有者
chown -R mysql:mysql /var/mysql/log
修改 my.cnf 配置
# 指定一个server的id,随便起只要不重复即可
server-id=1
# 开启binlog日志并且指定日志的位置,从服务器就是根据这个日志做数据同步的
log_bin=/var/mysql/log/mysql-bin
# sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。sync_binlog=n,表示当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。
sync-binlog=1
# 日志的缓存时间,设置5天
expire_logs_days=5
#日志的最大大小,设置5G
max_binlog_size=5G
#同步的数据库名称
binlog_do_db=SupremeSir
#开启主库半同步复制
rpl_semi_sync_master_enabled=ON
#设置超时时间,一旦有一次超时自动降级为异步
rpl_semi_sync_master_timeout=1000
# relay log 配置
relay_log=/var/mysql/log/mysql-relay-bin
log_slave_updates=1
relay_log_purge=0
重启 MySQL 服务
service mysql restart
主库给从库授权
登录MySQL,在MySQL命令行执行如下命令
# 赋予从库赋值的权限
mysql> grant replication slave on *.* to root@'%' identified by 'root';
# 数据库授权,`*.*代表所有数据库中的所有表,'root'@'%'代表所有主机可使用root账号录,identified后面是密码
mysql> grant all privileges on *.* to root@'%' identified by 'root';
# 刷新权限
mysql> flush privileges;
# 查看主库状态信息
mysql> show master status;
# 确认是否开启半同步
mysql> show variables like '%semi%';
2、配置 MySQL_Slave 节点
安装主库的半同步复制插件
# 登录MySQL,在MySQL命令行执行如下命令
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
创建 binlog 日志文件存放路径
# 递归创建日志目录
mkdir -p /var/mysql/log
# 修改日志目录所有者
chown -R mysql:mysql /var/mysql/log
修改 my.cnf 配置
# 指定一个server的id,不允许与其它服务器重复
server-id=2
#下面之所以要开启 binlog和log_slave_updates是因为5.7版本开启 slave_preserve_commit_order必须要先开启两个参数
# 开启binlog日志并且指定日志的位置
log_bin=/var/mysql/log/mysql-bin
# sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。sync_binlog=n,表示当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。
sync-binlog=1
# 日志的缓存时间,设置5天
expire_logs_days=5
#日志的最大大小,设置5G
max_binlog_size=5G
#同步的数据库名称
binlog_do_db=SupremeSir
#如果不手动设置,那么bin-log只会记录直接在该库上执行的SQL语句,由replication机制的SQL线程读取relay-log而执行的SQL语句并不会记录到bin-log
log_slave_updates=1
# 开启从库半同步复制
rpl_semi_sync_slave_enabled=ON
#配置成只读
read_only=1
# relay log 配置
relay_log=/var/mysql/log/mysql-relay-bin
log_slave_updates=1
relay_log_purge=0
# 开启并行复制
slave_parallel_type='logical_clock'
slave_parallel_workers=4
slave_preserve_commit_order=1
重启 MySQL 服务
service mysql restart
开启同步
登录MySQL,在Slave节点的MySQL命令行执行同步操作
#选择要同步的主库
mysql> change master to master_host='192.168.32.102', master_user='root',master_password='root',master_port=3306, master_log_file='mysql-bin.000003',master_log_pos=154;
# 开启同步
mysql> start slave;
# 检查同步状态
mysql> show slave status;
# 确认是否开启半同步
mysql> show variables like '%semi%';
3、配置 MHA Manager
四台机器互通 SSH
# 在四台机器上分别执行如下命令(一路回车即可)
ssh-keygen -t rsa
# 将三台 MySQL 主机的 SSH 秘钥发送至 MHA Manager主机(期间需输入 yes 和用户密码)
ssh-copy-id 192.168.32.105
# 以在 MHA Manager服务器上检查下,看看 .ssh/authorized_keys 文件是否包含3个公钥
cat /root/.ssh/authorized_keys
# 将 MHA Manager的公钥添加到 authorized_keys 文件中(此时应该包含4个公钥)
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
# 从MHA Manager服务器执行下面命令,向其他三台MySQL服务器分发公钥信息。(期间需输入 yes 和用户密码)
scp /root/.ssh/authorized_keys [email protected]:/root/.ssh/authorized_keys
scp /root/.ssh/authorized_keys [email protected]:/root/.ssh/authorized_keys
scp /root/.ssh/authorized_keys [email protected]:/root/.ssh/authorized_keys
# 检测下 MHA Manager 与三台 MySQL 主机是否实现 ssh 互通
ssh 192.168.32.102
exit
ssh 192.168.32.103
exit
ssh 192.168.32.104
exit
MHA下载安装
MySQL5.7
对应的 MHA
版本是 0.5.8
,所以在 GitHub
上找到对应的 rpm
包进行下载,MHA manager
和 node
的安装包需要分别下载:
https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58
下载后,将 Manager
和 Node
的安装包分别上传到对应的服务器。
-
三台
MySQL
服务器需要安装node
-
MHA Manager
服务器需要安装manager
和node
MHA node安装
首先在三台 MySQL
服务器上安装 mha4mysql-node
。由于 MHA
的 Node
依赖于 perl-DBD-MySQL
,所以要先安装 perl-DBD-MySQL
。
# 安装依赖环境
yum install perl-DBD-MySQL -y
# 下载 mha4mysql-node 如果已经有离线安装包可跳过本步
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
# 安装 mha4mysql-node
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
# 创建 mysqlbinlog 命令软连接
ln -s /usr/local/mysql/mysql-5.7.32/bin/mysqlbinlog /usr/local/bin/mysqlbinlog
# 创建 mysql 命令软连接
ln -s /usr/local/mysql/mysql-5.7.32/bin/mysql /usr/local/bin/mysql
MHA manager安装
在 MHA Manager
服务器安装 mha4mysql-node
和 mha4mysql-manager
。
MHA
的 manager
又依赖了 perl-Config-Tiny
、perl-Log-Dispatch
、perl-Parallel-ForkManager
,也分别进行安装。
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager -y
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
Tips:由于perl-Log-Dispatch和perl-Parallel-ForkManager这两个被依赖包在yum仓库找不到,因此安装epel-release-latest-7.noarch.rpm。在使用时,可能会出现下面异常:Cannot retrieve metalink for repository: epel/x86_64。可以尝试使用/etc/yum.repos.d/epel.repo,然后注释掉metalink,取消注释baseurl。
MHA 配置文件
MHA Manager服务器需要为每个监控的 Master/Slave 集群提供一个专用的配置文件,而所有的Master/Slave 集群也可共享全局配置。
# 初始化配置目录
mkdir -p /var/log/mha/app1
touch /var/log/mha/app1/manager.log
目录说明:
- /var/log (CentOS目录)
- /mha (MHA监控根目录)
- /app1 (MHA监控实例根目录)
- /manager.log (MHA监控实例日志文件)
配置监控配置文件
MySQL 主库创建 mha 用户
# 在master mysql的主库执行下列命令建一个新用户
create user 'mha'@'%' identified by '123123';
grant all privileges on *.* to mha@'%' identified by '123123';
flush privileges;
创建监控实例配置文件
# 创建目录
mkdir -p /etc/mha
# 编辑文件
vim /etc/mha/app1.cnf
app1.cnf 文件内容
[server default]
user=mha
password=123123
port=3306
#ssh登录账号
ssh_user=root
##从库复制账号和密码
repl_user=root
repl_password=root
port=3306
##ping次数
ping_interval=1
#MHA监控实例根目录
manager_workdir=/var/log/mha/app1
#MHA监控实例日志文件
manager_log=/var/log/mha/app1/manager.log
#ping次数
ping_interval=1
#二次检查的主机
secondary_check_script=masterha_secondary_check -s 192.168.32.102 -s 192.168.32.103 -s 192.168.32.104
[server1]
hostname=192.168.32.102
candidate_master=1
master_binlog_dir=/var/mysql/log
[server2]
hostname=192.168.32.103
candidate_master=1
master_binlog_dir=/var/mysql/log
[server3]
hostname=192.168.32.104
candidate_master=1
master_binlog_dir=/var/mysql/log
MHA 配置检测
在 MHA Manager
服务器上执行命令进行 ssh
通信检测:
masterha_check_ssh --conf=/etc/mha/app1.cnf
在 MHA Manager
服务器上执行命令进行 MySQL
主从复制功能检测:
masterha_check_repl --conf=/etc/mha/app1.cnf
MHA Manager启动
在MHA Manager服务器上执行:
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
查看监控状态命令如下:
masterha_check_status --conf=/etc/mha/app1.cnf
查看监控日志命令如下:
tail -f /var/log/mha/app1/manager.log
五、测试MHA故障转移
1、模拟主节点崩溃
在MHA Manager服务器执行打开日志命令:
tail -200f /var/log/mha/app1/manager.log
关闭Master MySQL服务器服务,模拟主节点崩溃
service mysql stop
2、测试SQL脚本
create TABLE position (
id int(20),
name varchar(50),
salary varchar(20),
city varchar(50)
) ENGINE=innodb charset=utf8;
insert into position values(1, 'Java', 13000, 'shanghai');
insert into position values(2, 'DBA', 20000, 'beijing');
create TABLE position_detail (
id int(20),
pid int(20),
description text
) ENGINE=innodb charset=utf8;
insert into position_detail values(1, 1, 'Java Developer');
insert into position_detail values(2, 2, 'Database Administrator');
--------------------------------------- 法乎其上,得乎其中,法乎其中,仅得其下。---------------------------------------