1、Percona XtraDB Cluster相关概念及原理:node
一、Percona XtraDB Cluster简介:mysql
Percona XtraDB Cluster是基于Galera协议的MySQL高可用集群架构。Galera是Codership提供的多主数据同步复制机制,具备高可用性,方便扩展,能够实现多个MySQL节点间的数据同步复制以及读写,而且可保障数据库的服务高可用及数据一致性。基于Galera的高可用方案主要有MariaDB Galera Cluster和Percona XtraDB Cluster(简称PXC)。PXC属于一套近乎完美的MySQL高可用集群解决方案,相比那些传统的基于主从复制模型的集群架构MHA和MM+Keepalived,Galera Cluster最突出的特色就是解决了诟病已久的数据复制延迟问题,基本上能够达到实时同步,并且节点与节点之间,它们相互的关系是对等的。自己Galera Cluster也是一种多主架构,以下图所示:sql
要搭建PXC架构至少须要3个MySQL实例来组成一个集群,3个实例之间不是主从模式,而是各自为主,因此三者是对等关系,不分从属,这就叫multi-master架构。客户端写入和读取数据时,链接哪一个实例都是同样的,读取到的数据也都是相同的,写入任意一个实例以后,集群自身会将新写入的数据同步到其它实例上,这种架构不共享任何数据,是一种高冗余架构。数据库
二、PXC原理:bootstrap
PXC最常使用以下4个端口号:vim
(1)3306:数据库对外服务的端口号缓存
(2)4444:请求SST的端口号安全
(3)4567:组成员之间进行沟通的端口号服务器
(4)4568:用于传输IST的端口号架构
备注:
Ø SST:State Snapshot Transfer,全量数据传输
Ø IST:Incremental State Transfer,增量数据传输
从上图中能够看出PXC的操做流程,首先客户端发起一个事务,该事务先在本地执行,执行完成后发起对事务的提交操做。在提交以前须要将产生的复制写集广播出去,而后获取到一个全局的事务ID号,一并传送到另外一节点上。经过验证合并数据以后,发现没有冲突数据,执行apply_cb和commit_cb操做,不然就须要取消(discard)这次事务的操做。而当前server节点经过验证以后,执行提交操做,并返回OK,若是验证没经过,则执行回滚。固然在生产中至少要有三个节点的集群环境,若是其中有一个节点没有验证经过,出现了数据冲突,那么此时采起的方式就是将出现不一致的节点踢出集群环境,并且它本身会执行shutdown命令,自动关机。
三、PXC架构的优缺点:
(1)优势:
a、实现MySQL集群架构的高可用性和数据强一致性
b、实现真正的多节点读写集群方案
c、改善了传统意义上的主从复制延迟问题,基本上达到了实时同步
d、新加入的节点能够自动部署,无需提供手动备份,维护方便
e、多节点写入,数据库故障切换容易
(2)缺点:
a、只支持InnoDB引擎,其它存储引擎的更改不复制,DDL语句在statement级别被复制,而且对mysql.*表的更改会基于此被复制,例如:CREATE USER...语句会被复制,但INSERT INTO mysql.user...语句则不会被复制,可经过wsrep_replicate_myisam参数开启MyISAM存储引擎的复制,但这只是一个实验性的参数
b、新加入节点采用SST时的代价高
c、存在写扩大问题
d、任何更新事务都须要全局验证经过,才会在每一个节点库上执行,集群性能/吞吐量受限于性能最差的节点,也就是常常说的短板效应
e、因为须要保证数据的一致性,因此在多节点并发写时,锁冲突及死锁问题比较严重
f、全部表必须含有主键
g、不支持LOCK TABLE等显式表级别的锁定操做
h、不支持XA
四、PXC中涉及到的重要概念和核心参数:
(1)集群中节点的数量:整个集群中节点数量应该控制在最少3个、最多8个的范围内。最少3个节点是为了防止出现脑裂现象,由于只有在2个节点下才会出现此现象。脑裂现象的标志就是输入任何命令,返回的结果都是unknown command。节点在集群中,会因新节点的加入或故障、同步失效等缘由发生状态的切换。
(2)节点状态的变化阶段:
a、open:节点启动成功,尝试链接到集群时的状态
b、primary:节点已处于集群中,在新节点加入并选取donor进行数据同步时的状态
c、joiner:节点处于等待接收同步文件时的状态
d、joined:节点完成数据同步工做,尝试保持和集群进度一致时的状态
e、synced:节点正常提供服务时的状态,表示已经同步完成并和集群进度保持一致
f、donor:节点处于为新加入的节点提供全量数据时的状态
备注:donor节点就是数据的贡献者,若是一个新节点加入集群,此时又须要大量数据的SST数据传输,就有可能所以而拖垮整个集群的性能,因此在生产环境中,若是数据量较小,还可使用SST全量数据传输,但若是数据量很大就不建议使用这种方式,能够考虑先创建主从关系,而后再加入集群。
(3)节点的数据传输方式:一种叫SST全量数据传输,另外一种叫IST增量数据传输。SST数据传输有xtrabackup、mysqldump和rsync三种方式,而增量数据传输就只有一种方式xtrabackup,但生产环境中通常数据量较小时,可使用SST全量数据传输,但也只使用xtrabackup方法。
(4)GCache模块:在PXC中一个特别重要的模块,它的核心功能就是为每一个节点缓存当前最新的写集。若是有新节点加入进来,就能够把新数据的增量传递给新节点,而不须要再使用SST传输方式,这样可让节点更快地加入集群中,涉及以下参数:
a、gcache.size:缓存写集增量信息的大小,它的默认大小是128MB,经过wsrep_provider_options参数设置,建议调整为2GB~4GB范围,足够的空间便于缓存更多的增量信息。
b、gcache.mem_size:GCache中内存缓存的大小,适度调大能够提升整个集群的性能
c、gcache.page_size:若是内存不够用(GCache不足),就直接将写集写入磁盘文件中
2、准备工做(如无特殊说明,3个节点都须要执行以下操做):
一、演示环境:
IP |
操做系统 |
主机名 |
角色 |
数据库版本 |
安装方式 |
192.168.1.143 |
CentOS 7.6 x86_64 |
node1 |
master1 |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
192.168.1.144 |
CentOS 7.6 x86_64 |
node2 |
master2 |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
192.168.1.145 |
CentOS 7.6 x86_64 |
node3 |
master3 |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
二、关闭SELinux和firewalld
三、配置epel源
四、配置服务器时间同步
五、配置主机名
六、配置/etc/hosts文件:
# vim /etc/hosts
192.168.1.143 node1
192.168.1.144 node2
192.168.1.145 node3
3、yum方式安装配置PXC(如无特殊说明,3个节点都须要执行以下操做):
一、安装percona yum源:# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
二、测试percona yum源:# yum list | grep -i percona
三、安装PXC:# yum -y install Percona-XtraDB-Cluster-57
备注:安装后生成的比较重要的配置文件
Ø /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
Ø /etc/percona-xtradb-cluster.conf.d/mysqld_safe.cnf
Ø /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
四、建立软连接:
# mv /etc/my.cnf /etc/my.cnf.bak
# update-alternatives --install /etc/my.cnf my.cnf "/etc/percona-xtradb-cluster.cnf" 200
五、master1节点修改mysqld.cnf配置文件:
# vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
[mysqld]
server-id=1
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
log_bin=mysql-bin
log_bin_index=mysql-bin.index
log_slave_updates
expire_logs_days=7
symbolic-links=0
port=3306
lower_case_table_names=1
character_set_server=utf8mb4
collation_server=utf8mb4_general_ci
innodb_file_per_table=1
skip_name_resolve=1
slow_query_log=1
slow_query_log_file=mysql-slow.log
备注:
Ø master2节点中的server-id=2,master3节点中的server-id=3
Ø 尽管Galera Cluster再也不须要经过binlog的形式进行同步,但仍是建议在配置文件中开启二进制日志功能,缘由是后期若是有新节点须要加入,老节点经过SST全量传输的方式向新节点传输数据,极可能会拖垮集群性能,因此让新节点先经过binlog方式完成同步后再加入集群会是一种更好的选择
六、master1节点修改wsrep.cnf配置文件:
# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_provider_options="gcache.size=2G"
wsrep_cluster_address="gcomm://192.168.1.143,192.168.1.144,192.168.1.145"
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads=8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=192.168.1.143
wsrep_cluster_name=pxc-cluster
wsrep_node_name=node1
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass"
经常使用配置参数说明:
(1)wsrep_provider:Galera库的路径和文件名
(2)wsrep_provider_options:Galera库的额外参数
(3)wsrep_cluster_address:集群中各节点IP
(4)binlog_format:二进制日志的记录格式
(5)default_storage_engine:默认使用的存储引擎
(6)wsrep_slave_threads:使用的从属线程个数
(7)wsrep_node_address:本节点IP
(8)wsrep_cluster_name:集群名称
(9)wsrep_node_name:本节点在集群中的名称
(10)wsrep_sst_method:SST传输数据的方式,有xtrabackup、mysqldump和rsync三种,前二者在传输时都须要对donor加全局只读锁(FLUSH TABLES WITH READ LOCK),而xtrabackup则不须要(它使用percona本身提供的backup lock),强烈推荐使用xtrabackup-v2方式
(11)wsrep_sst_auth:在SST传输时须要使用的认证凭据,格式为“用户:密码”
备注:
Ø master2节点中的wsrep_node_address=192.168.1.144,wsrep_node_name=node2
Ø master3节点中的wsrep_node_address=192.168.1.145,wsrep_node_name=node3
七、初始化MySQL数据:# mysqld --initialize --user=mysql
备注:确保初始化前/var/lib/mysql目录为空,初始化完成后会在此目录中生成各种文件
八、master1节点启动MySQL服务:
# systemctl start mysql@bootstrap.service
# ss -tunlp | grep mysqld
# systemctl enable mysql@bootstrap.service
# systemctl status mysql@bootstrap.service
# tail -100 /var/log/mysqld.log
九、master1节点配置MySQL安全向导:
# grep "password" /var/log/mysqld.log --> sIw4lWaqXy+X
# mysql_secure_installation
十、master1节点受权root用户远程登陆和建立PXC传输用户sstuser:
# mysql -uroot -p
mysql> create user 'root'@'192.168.1.%' identified by '123456';
mysql> grant all on *.* to 'root'@'192.168.1.%';
mysql> flush privileges;
mysql> create user 'sstuser'@'localhost' identified by 's3cretPass';
mysql> grant reload, lock tables, process, replication client on *.* to 'sstuser'@'localhost';
mysql> flush privileges;
备注:以后的MySQL版本将不支持grant受权的同时建立用户,而是须要先建立用户,再进行受权
十一、master2和master3节点分别启动MySQL服务:
# systemctl start mysql.service
# ss -tunlp | grep mysqld
# systemctl enable mysql.service
# systemctl status mysql.service
# tail -100 /var/log/mysqld.log
备注:master2和master3节点无需分别配置MySQL安全向导,也无需分别受权root用户远程登陆,已从master1节点处同步
十二、查看PXC集群状态:
mysql> show global status like 'wsrep%';
经常使用PXC集群状态监控指标说明:
(1)wsrep_local_state_uuid:与wsrep_cluster_state_uuid的值一致,且全部节点该值都相同
(2)wsrep_cluster_state_uuid:全部节点该值都相同,若是有不一样值的节点,说明该节点没有与集群创建链接
(3)wsrep_last_committed:集群已经提交事务的数量,是一个累计值,全部节点该值都相同,若是出现不一致,说明事务有延迟,能够用来计算延
(4)wsrep_replicated:从本节点复制出去的写集数量,wsrep_replicated_bytes为写集的总字节数,能够用于参考节点间的负载均衡是否平衡,该值较大的节点较为繁忙
(5)wsrep_received:与wsrep_replicated对应,本节点接收来自其它节点的写集数量
(6)wsrep_local_state:全部节点该值都应该为4,表示正常,节点状态有以下6个取值
a、取值1:节点启动并与集群创建链接
b、取值2:当节点成功执行状态传输请求时,该节点开始缓存写集
c、取值3:节点接收了SST全量数据传输,该节点如今拥有全部集群数据,并开始应用已缓存的写集
d、取值4:节点完成与集群数据的同步,它的从属队列如今是空的,并启用流控使其保持为空
e、取值5:节点接收了状态传输请求,该节点如今对donor不执行流控,该节点已缓存全部的写集但没法应用
f、取值6:节点完成对joiner节点的状态传输
(7)wsrep_incoming_addresses:集群中全部节点的IP,且每一个节点该值都相同
(8)wsrep_cluster_size:集群中的节点数量,全部节点该值都相同
(9)wsrep_cluster_conf_id:全部节点该值都相同,若是值不一样,说明该节点被临时“分区”了
(10)wsrep_cluster_status:集群组成的状态,全部节点该值都为“Primary”,若是该值不为“Primary”,说明该节点出现“分区”或“脑裂”现象
(11)wsrep_connected:全部节点该值都为“ON”,表示本节点已经与集群创建链接
(12)wsrep_ready:全部节点该值都为“ON”,表示本节点能够正常提供服务
4、测试PXC:
一、master1节点建立测试数据:
mysql> create database db;
mysql> use db;
mysql> create table tb(id int unsigned auto_increment primary key not null,name char(20) not null);
mysql> desc tb;
mysql> insert into tb(name) values('zhangsan'),('lisi');
mysql> select * from tb;
二、master2和master3节点分别查看测试数据:
mysql> show databases;
mysql> use db;
mysql> show tables;
mysql> desc tb;
mysql> select * from tb;
三、master2节点建立测试数据:
mysql> insert into tb(name) values('wangwu'),('zhaoliu');
mysql> select * from tb;
四、master1和master3节点分别查看测试数据:
mysql> select * from tb;
五、master3节点建立测试数据:
mysql> insert into tb(name) values('jack'),('tom');
mysql> select * from tb;
六、master1和master2节点分别查看测试数据:
mysql> select * from tb;
5、模拟新节点加入PXC:
将一个新节点加入PXC集群,须要SST全量数据传输,颇有可能拖垮集群总体性能,能够考虑让新节点先成为PXC集群中某个节点(此处以master2节点为例)的从节点,而后在线快速经过IST方式加入集群。
一、演示环境:
IP |
操做系统 |
主机名 |
角色 |
数据库版本 |
安装方式 |
192.168.1.143 |
CentOS 7.6 x86_64 |
node1 |
master1 |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
192.168.1.144 |
CentOS 7.6 x86_64 |
node2 |
master2 |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
192.168.1.145 |
CentOS 7.6 x86_64 |
node3 |
master3 |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
192.168.1.146 |
CentOS 7.6 x86_64 |
node4 |
slave |
5.7.25-28-57-log Percona XtraDB Cluster |
yum |
二、slave节点关闭SELinux和firewalld、配置epel源、配置服务器时间同步、配置主机名
三、四个节点配置/etc/hosts文件:
# vim /etc/hosts
192.168.1.143 node1
192.168.1.144 node2
192.168.1.145 node3
192.168.1.146 node4
四、slave节点安装percona yum源:# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
五、slave节点安装PXC:# yum -y install Percona-XtraDB-Cluster-57
六、slave节点建立软连接:
# mv /etc/my.cnf /etc/my.cnf.bak
# update-alternatives --install /etc/my.cnf my.cnf "/etc/percona-xtradb-cluster.cnf" 200
七、slave节点修改mysqld.cnf配置文件:
# vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
[mysqld]
server-id=4
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
log_bin=mysql-bin
log_bin_index=mysql-bin.index
log_slave_updates
expire_logs_days=7
symbolic-links=0
port=3306
lower_case_table_names=1
character_set_server=utf8mb4
collation_server=utf8mb4_general_ci
innodb_file_per_table=1
skip_name_resolve=1
slow_query_log=1
slow_query_log_file=mysql-slow.log
relay_log=relay-log
relay_log_index=relay-log.index
read_only=1
八、slave节点暂时不启用PXC的相关配置:# cd /etc/percona-xtradb-cluster.conf.d # mv wsrep.cnf wsrep.cnf.bak
九、slave节点初始化MySQL数据:# mysqld --initialize --user=mysql
十、slave节点启动MySQL服务:
# systemctl start mysql.service
# ss -tunlp | grep mysqld
# systemctl enable mysql.service
# systemctl status mysql.service
# tail -100 /var/log/mysqld.log
十一、slave节点配置MySQL安全向导:
# grep "password" /var/log/mysqld.log --> 7gk0ti?jf*(M
# mysql_secure_installation
十二、slave节点受权root用户远程登陆:
# mysql -uroot -p
mysql> create user 'root'@'192.168.1.%' identified by '123456';
mysql> grant all on *.* to 'root'@'192.168.1.%';
mysql> flush privileges;
1三、master2节点建立具备复制权限的用户repluser:
mysql> create user 'repluser'@'192.168.1.%' identified by '123456';
mysql> grant replication slave on *.* to 'repluser'@'192.168.1.%';
mysql> flush privileges;
1四、master2节点使用mysqldump对全部数据库进行全量热备,并将导出的sql文件复制至slave节点:
# mkdir -pv /backup
# mysqldump -E -F -R -q --single-transaction --master-data=2 -A -uroot -p > /backup/all_`date +%F`.sql
# less /backup/all_2019-06-06.sql,找到已被注释的CHANGE MASTER TO语句:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=154;
# scp -p /backup/all_2019-06-06.sql node4:/backup/
1五、slave节点还原数据:
mysql> show variables like 'sql_log_bin';
mysql> set sql_log_bin=0;
mysql> source /backup/all_2019-06-06.sql
mysql> set sql_log_bin=1;
1六、slave节点使用具备复制权限的用户链接至master2:
mysql> change master to master_host='192.168.1.144',master_user='repluser',master_password='123456',master_port=3306,master_log_file='mysql-bin.000002',master_log_pos=154;
mysql> start slave;
mysql> show slave status\G
1七、slave节点中止MySQL服务:
# systemctl stop mysql.service
# ss -tunlp | grep mysqld
# systemctl status mysql.service
# tail -100 /var/log/mysqld.log
1八、slave节点注释/etc/percona-xtradb-cluster.conf.d/mysqld.cnf的[mysqld]配置段中read_only=1选项
1九、slave节点启用PXC的相关配置:# cd /etc/percona-xtradb-cluster.conf.d # mv wsrep.cnf.bak wsrep.cnf
20、slave节点修改wsrep.cnf配置文件:
# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_provider_options="gcache.size=2G"
wsrep_cluster_address="gcomm://192.168.1.143,192.168.1.144,192.168.1.145,192.168.1.146"
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads=8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=192.168.1.146
wsrep_cluster_name=pxc-cluster
wsrep_node_name=node4
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass"
2一、master2节点确认PXC须要同步的位置:# mysqlbinlog /var/lib/mysql/mysql-bin.000001 | grep Xid
备注:master2节点在使用mysqldump对全部数据库进行全量热备时使用了“-F”选项,备份时会自动滚动二进制日志,因此此处命令中使用的二进制日志为mysql-bin.000001,Xid的值为最新的18
2二、master2节点查看grastate.dat文件的内容,并将grastate.dat文件复制至slave节点的对应目录下:
# cat /var/lib/mysql/grastate.dat
备注:
Ø uuid:集群中wsrep_cluster_state_uuid的值
Ø seqno:集群中swrep_last_committed的值,根据此值能够直接判断下次节点启动时作增量传输的位置,目前master2节点处于正常运行的状态,因此值为-1
# scp -p /var/lib/mysql/grastate.dat node4:/var/lib/mysql/
2三、slave节点修改grastate.dat文件的属主属组为mysql用户:# chown mysql.mysql /var/lib/mysql/grastate.dat
2四、slave节点设置同步开始位置:# vim /var/lib/mysql/grastate.dat
备注:修改seqno的值,将seqno: -1修改成刚才获取的position 1967对应Xid的值18,这就是PXC同步开始的位置
2五、slave节点启动MySQL服务:
# systemctl start mysql.service
# ss -tunlp | grep mysqld
# systemctl status mysql.service
# tail -100 /var/log/mysqld.log
2六、slave节点中止主从复制:
mysql> stop slave;
2七、查看PXC集群状态:
mysql> show global status like 'wsrep%';
(1)wsrep_local_state_uuid:与wsrep_cluster_state_uuid的值一致,且全部节点该值都相同
(2)wsrep_cluster_state_uuid:全部节点该值都相同
(3)wsrep_last_committed:全部节点该值都相同
(4)wsrep_local_state:全部节点该值都应该为4,表示正常
(5)wsrep_incoming_addresses:集群中全部节点的IP(192.168.1.143~146),且每一个节点该值都相同
(6)wsrep_cluster_size:集群中的节点数量,全部节点该值都相同
(7)wsrep_cluster_conf_id:全部节点该值都相同
(8)wsrep_cluster_status:集群组成的状态,全部节点该值都为“Primary”
(9)wsrep_connected:全部节点该值都为“ON”,表示本节点已经与集群创建链接
(10)wsrep_ready:全部节点该值都为“ON”,表示本节点能够正常提供服务
2八、新集群中不管哪一个节点写入数据,都会复制给其它三个节点
6、模拟PXC中某个节点故障并恢复:
一、master3节点中止MySQL服务:
# systemctl stop mysql.service
# ss -tunlp | grep mysqld
# systemctl status mysql.service
# tail -100 /var/log/mysqld.log
二、查看PXC集群状态:
mysql> show global status like 'wsrep%';
(1)wsrep_incoming_addresses:目前集群中全部节点的IP(143、144、146),且每一个节点该值都相同
(2)wsrep_cluster_size:集群中的节点数量(3),全部节点该值都相同
三、集群剩余节点中不管哪一个节点写入数据,都会复制给其它两个节点
四、master3节点修改wsrep.cnf配置文件:
# vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_cluster_address="gcomm://192.168.1.143,192.168.1.144,192.168.1.145,192.168.1.146"
五、master3节点启动MySQL服务:
# systemctl start mysql.service
# ss -tunlp | grep mysqld
# systemctl status mysql.service
# tail -100 /var/log/mysqld.log
六、查看PXC集群状态:
mysql> show global status like 'wsrep%';
备注:集群已恢复正常
七、宕机时在其它可用节点中写入的数据,已复制给master3节点