软件 | 版本 |
---|---|
centos | 8 |
mysql | 5.7.32 |
mha | 0.58 |
架构介绍:MHA由两部分组成MHA Manager(管理节点)和MHA Node(数据节点),MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master
MHA的隐患:在MHA自动故障切换的过程中,MHA试图从宕掉的主服务器上保存二进制日志,最大程度保证数据的不丢失,存在的问题是,如果主服务器硬件故障宕机或无法通过SSH访问,MHA没有办法保存二进制日志,只能进行故障转移而可能丢失最新数据
工作原理总结为以下几条:
1.从宕机崩溃的master保存二进制日志事件(binlog events);
2.识别含有最新更新的slave;
3.应用差异的中继日志(relay log) 到其他slave;
4.应用从master保存的二进制日志事件(binlog events);
5.提升一个slave为新master;
6.使用其他的slave连接新的master进行复制。
rpm -qa|grep -i mysql
rpm -e 包名 --nodeps
rpm -qa|grep mariadb
rpm -e 包名 --nodeps
# 解压安装文件
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
缺少依赖的包,安装命令
yum install libncurses*
安装主库的半同步复制插件
登录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%';
安装主库的半同步复制插件
登录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%';
四台机器互通 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 的安装包需要分别下载:
三台 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
MHA 配置文件
MHA Manager服务器需要为每个监控的 Master/Slave 集群提供一个专用的配置文件,而所有的Master/Slave 集群也可共享全局配置。
# 初始化配置目录
mkdir -p /var/log/mha/app1
touch /var/log/mha/app1/manager.log
目录说明:
配置监控配置文件
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服务器上执行:
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
sudo gedit /usr/local/share/perl/5.22.1/MHA/NodeUtil.pm
sub parse_mysql_major_version($) {
my $str = shift ;
my $result = sprintf ( '%03d%03d' , $str =~ m/(\d+)/g );
return $result ;
}
#改成下面这样
sub parse_mysql_major_version($) {
my $str = shift ;
$str =~ /(\d+)\.(\d+)/;
my $strmajor = "$1.$2" ;
my $result = sprintf ( '%03d%03d' , $strmajor =~ m/(\d+)/g );
return $result ;
}
在MHA Manager服务器执行打开日志命令:
tail -200f /var/log/mha/app1/manager.log
关闭Master MySQL服务器服务,模拟主节点崩溃
service mysql stop
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');