实验环境模拟:
- 一台进行源码编译过mysql.5.7.31的主机lnmp,编译目录在 /usr/local/lnmp/mysql ,主机IP为172.25.3.199/24。
- 一台IP为172.25.3.1/24 的server1主机,两台主机都做好了解析。
mysql 的主从复制
基于二进制文件的主从复制
步骤:
- 通过rsync命令将lnmp主机上的nginx 源码编译后的目录发送到server1主机上,并添加mysql用户. 将mysql目录下的bin 目录写在
$PATH
中,用mysqld --initialize --user=mysql
生成一个临时密码,修改/etc/my.cnf
文件。
lnmp主机/etc/my.cnf
文件
[mysqld]
datadir=/usr/local/lnmp/mysql/data
socket=/usr/local/lnmp/mysql/data/mysql.sock
server-id=1
log-bin=mysql-bin ## 启用二进制日志记录
server1主机/etc/my.cnf
文件 (可以不启用二进制日志文件记录 )
[mysqld]
datadir=/usr/local/lnmp/mysql/data
socket=/usr/local/lnmp/mysql/data/mysql.sock
server-id=2
cp support-files/mysql.server /etc/init.d/mysqld
用二进制脚本文件来控制mysql服务,
/etc/init.d/mysqld start
启动服务,mysql_secure_installation
进行安全初始化。
- 将lnmp主机作为master主机, 在lnmp 主机上:
mysql -p
输入密码进入mysql数据库
执行下面的SQL语句
CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; ##创建用户
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; ##给用户授权
show master status;
查看master 主机的状态信息
- server1 作为slave主机,
mysql -p
输入密码,在server1主机上执行
CHANGE MASTER TO
-> MASTER_HOST='172.25.3.199',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='westos',
-> MASTER_LOG_FILE='mysql-bin.000002',
-> MASTER_LOG_POS=154;
start slave;
启动复制线程;通过show slave status\G
查看slave 主机状态
测试:
当在master 主机上建立一个rhel数据库时,slave 主机会自动回放主机上执行的sql语句,生成一个rhel数据库。
slave 主机上会自动生成数据库rhel
基于gtid 的方式实现主从复制
作用:通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
实现步骤:
- 给master和slave主机的
/etc/my.cnf
中加入两个参数
gtid_mode=ON ## 表示打开gitd 模块
enforce-gtid-consistency=ON ##
- 重启服务 ,进入mysql数据库,在slave 主机上执行
change master to master_host='172.25.3.199', master_user='repl', master_password='westos', master_auto_position=1;
,成功之后start slave;
开启备份。通过show slave status\G;
查看备份状态。
测试:
在master 主机上建立一个表,查看slave 主机上会不会自动备份
半同步复制
5.7版本之前的after_commit半同步模式
after_sync半同步模式
区别: after_commit 半同步模式在主机事务提交后将日志传送到从机,其在主从切换过程中存在幻读问题(非数据库理论的幻读)。即切换过后,之前用户“看到”的数据可能不存在了。所以说after_commit 不是无损复制,after_sync半同步模式在收到从机的ack返回之后,事物才进行提交。在mysql5.7版本之后,半同步复制默认采用的时after_sysnc模式
半同步模式实现步骤
修改master 端和slave端的配置文件
lnmp主机
重启mysql服务并进入mysql数据库,执行以下sql语句
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; ## 加载插件
SET GLOBAL rpl_semi_sync_master_enabled = 1 ## 开启半同步服务
server1 主机
变量 | 作用 |
---|---|
slave_parallel_workers | 用于并行执行复制事务的应用程序线程数 |
slave_parallel_type | 用来决定如何使用多线程复制,默认是datebase,每个线程只能处理一个数据库,配置成基于逻辑时钟的方式 |
master_info_repository | 此变量的设置确定副本是否将有关源的元数据(包括状态和连接信息)记录到系统数据库中的InnoDB 表中mysql,还是记录为数据目录中的文件。 |
relay_log_info_repository | 确定副本服务器是将其适当的元数据存储库存储为系统数据库中的 InnoDB表 mysql还是数据目录中的文件。 |
relay_log_recovery | 设置为 relay_log_recovery = ON 自动处理已从中继日志执行的事务序列中的任何不一致和空白。 |
重启mysql服务并进入mysql数据库,执行以下sql语句
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; ## 安装模块
SET GLOBAL rpl_semi_sync_slave_enabled = 1; ## 开启服务
stop slave io_thread;
start slave io_thread; ## 重启slave 端上的IO线程
测试:
通过关闭从库的IO线程,来达到主库不能采用半同步复制的方式进行同步
stop slave IO_thread
延迟复制
从源接收到的事件N要比在源上执行的事件至少晚几秒钟后才执行
作用:
-
防止用户在源上犯错误。DBA可以将延迟的副本回滚到灾难发生之前的时间。
-
测试存在滞后时系统的行为。例如,在应用程序中,延迟可能是由于副本上的繁重负载引起的。但是,可能很难生成此负载级别。延迟复制可以模拟延迟,而不必模拟负载。它还可以用于调试与滞后副本有关的条件。
-
无需重新加载备份即可检查数据库的外观。例如,如果延迟是一周,并且DBA需要在开发最后几天之前查看数据库的外观,则可以检查延迟的副本。
方法:
只用在slave端修改一个选项。
change master to master_delay=N
N是秒数。
测试:
组复制协议(全同步)
组复制相对于其他两种复制的优点,可以使每一台数据库互备,都具有读写的功能,对于主从复制而言,只有主机可写,其他从机只读的特性。在组复制中,每一个节点都可以实现读写功能。
组复制的要求:
- InnoDB存储引擎。
- 主键: 该组要复制的每个表都必须具有定义的主键,或等效的主键,其中等效项是非null的唯一键。此类键是作为表中每一行的唯一标识符所必需的,从而使系统能够通过准确标识每个事务已修改的行来确定哪些事务发生冲突。
- IPv4网络。 MySQL组复制使用的组通信引擎仅支持IPv4。因此,组复制需要IPv4网络基础结构。
- 网络性能。
组复制的限制: MySQL服务器的最大数量为9
多主模式下的组复制实现步骤:
- 实验环境搭建,搭建三台未做初始化处理的mysql数据库,主机名分别为lnmp , server1 , server2。可以通过删除mysql数据库的data数据目录。使恢复最初状态
修改三台主机的mysql的配置文件:
[mysqld]
datadir=/usr/local/lnmp/mysql/data
socket=/usr/local/lnmp/mysql/data/mysql.sock
server_id=2
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.3.1:33061"
group_replication_group_seeds= "172.25.3.199:33061,172.25.3.1:33061,172.25.3.2:33061"
group_replication_bootstrap_group= off
group_replication_ip_whitelist="172.25.3.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
其他两台主机的配置文件除了server_id
和 group_replication_local_address
不同其他都是一样的,server_id只要三台主机不同就行,group_replication_local_address 写的是本机的地址。
- 在三台主机上做好这三台主机的解析
在lnmp主机上mysqld --initialize --user=mysql
初始化数据库, 并生成数据库的临时密码。
/etc/init.d/mysqld start
启动数据库
mysql -p
用临时密码进入数据库,执行以下的sql语句
alter user root@localhost identified by 'westos';
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY 'westos';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery';
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
SELECT * FROM performance_schema.replication_group_members;
查看组成员
其他两台主机上除了不执行SET GLOBAL group_replication_bootstrap_group=ON;
和 SET GLOBAL group_replication_bootstrap_group=OFF;
两个sql语句,其他的步骤都要执行。
最后查看组成员:
建立一个数据库用来测试:
在任何一个主机上建立数据,都会在其他主机上自动回放在该主机上执行的sql语句
在lnmp 上建立test数据库,并建立带有主键的表t1;
在其他主机上查看:
组复制相较与主从复制而言,实现了在每台组成员上都可以实现读写的功能,对于主从复制中,只有主机可以写,其他从机只能读,不能写。
测试:
在server1 上写入数据
在lnmp主机上可以查看到数据
mysql-router 实现对组内成员的负载均衡和高可用
安装包:链接: mysql-router提取码: 8425
实现步骤:
- 开启第四台虚拟机,作为mysql路由管理器,
安装rpm包, 编辑配置文件,将以下内容加到/etc/mysqlrouter/mysqlrouter.conf
后
[routing:ro]
bind_address = 0.0.0.0
bind_port = 7001
destinations = 172.25.3.199:3306,172.25.3.1:3306,172.25.3.2:3306
routing_strategy = round-robin
[routing:rw]
bind_address = 0.0.0.0
bind_port = 7002
destinations = 172.25.3.199:3306,172.25.3.1:3306,172.25.3.2:3306
routing_strategy = first-available
- 重启服务
systemctl start mysqlrouter.service
, 并在任何一个后端数据库建立普通用户, 使他对test数据库有访问的权力
grant all on test.* to 'snji'@'%' identified by 'westos'
测试:
- 负载均衡
在宿主机上远程登陆mysql路由器的7001端口
由于mysql路由器的7001端口采用的使轮询的调度算法,所以每次连接到的后端真实的数据库都是一次变化的,第一次连接的是lnmp主机
第二次连接,是在server1主机上 ,实现了对后端服务器的负载均衡
- 高可用。
此时连接的是server1主机,当server1主机被down掉之后,并不影响客户端对数据库的访问
此时mysql路由器,就会自动的连接到了server2主机上
MHA 高可用
实验环境搭建:
一共四台虚拟机,三台做mysql的一主两从复制, 一台做管理端(server3)
配置文件:
[mysqld]
datadir=/usr/local/lnmp/mysql/data
socket=/usr/local/lnmp/mysql/data/mysql.sock
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
实现步骤:
需要的数据包: 链接: MH7提取码: 27fn
- server3管理端,在MH7目录下安装
yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm mha4mysql-node-0.58-0.el7.centos.noarch.rpm perl-*
将MH7目录下的mha4mysql-node-0.58-0.el7.centos.noarch.rpm
分别发送给后端mysql服务器,并安装。
- 在server3端,解压源码
tar zxf mha4mysql-manager-0.58.tar.gz
,将源码包目录下的samples/conf/
中的两个配置文件放到/etc/masterha
目录下,该目录需要自己建立。修改masterha_default.cnf配置文件,该masterha_default.cnf文件要放到 /etc 下 , 做repl 检测的时候,默认检测的是/etc/masterha_default.cnf
/etc/masterha_default.cnf 文件内容:
[server default]
user=westos ## 登陆mysql数据库的用户
password=westos ## 登陆mysql数据库的用户密码
ssh_user=root ## 连接后端搭载mysql数据库的主机的用户
master_binlog_dir= /usr/local/lnmp/mysql/data ## 后端mysql数据库的bin-log 目录
remote_workdir=/tmp ## 远端mysql在发生切换时binlog的保存位置
secondary_check_script= masterha_secondary_check -s server1 -s server2
ping_interval=3 ## 发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
repl_user=repl ## 后端服务器做主从复制的用户和密码
repl_password=westos
# 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
/etc/masterha/app1.cnf文件内容:
[server default]
manager_workdir=/usr/local/masterha/app1 ##管理端的工作路径
manager_log=/usr/local/masterha/app1/manager.log ## 管理端的日志存放路径
[server1]
hostname=172.25.3.199
#candidate_master=1
[server2]
hostname=172.25.3.1
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.3.2
no_master=1 ## 表示该主机始终是slave,不会成为master
- 在后端mysql服务器上建立一个mysql用户westos, 和配置文件中的user对应,并且使4台主机的root用户能够互相免密连接。
masterha_check_ssh --conf=/etc/masterha/app1.cnf
做ssh是否成功
masterha_check_repl --conf=/etc/masterha/app1.cnf
检查主从复制是否正常
自动切换
masterha_manager --conf=/etc/masterha/app1.cnf &
进行一次监控
测试:
此时的master 在server1上,当关闭server1时,
注: 如果切换不了可以删除/usr/local/masterha/app1
下的complete文件,这是系统为了防止多次连续的切换生成的文件。
对于该集群而言,不会自动启动被down掉的master端,需要手工引导
手动切换
当master 的状态是alive 状态
此时的master 端是172.25.3.199
手工切换master 端:
masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.cnf --new_master_host=172.25.3.1 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
切换后的结果:
当master 的状态是dead 状态
手工切换:
masterha_master_switch --master_state=dead --conf=/etc/masterha/app.cnf --dead_master_host=172.25.3.1 --dead_master_port=3306 --new_master_host=172.25.3.199 --new_master_port=3306 --ignore_last_failover
测试:
添加虚拟ip的高可用
步骤:
- 在管理端server3, 将MHA-7 目录下的两个脚本文件
master_ip_failover
,master_ip_online_change
移动到/etc/masterha
目录下,修改/etc/masterha_default.cnf
文件
- 修改两个脚本,并且给这两个脚本执行权限
给master端加上虚拟IPip addr add 172.25.3.100/24 dev eth0
访问测试
测试:
在管理端开启监控: masterha_manager --conf=/etc/masterha/app1.cnf
此时的master端在lnmp主机,虚拟ip也在lnmp主机,当手动关闭mysql服务时,虚拟ip 会自动漂移到新的master上去,并不会影响客户端的正常访问