一、PXC 介绍
1.1 PXC 简介
PXC 是一套 MySQL 高可用集群解决方案,与传统的基于主从复制模式的集群架构相比 PXC 最突出特点就是解决了诟病已久的数据复制延迟问题,基本上可以达到实时同步。而且节点与节点之间,他们相互的关系是对等的。PXC 最关注的是数据的一致性,对待事物的行为时,要么在所有节点上执行,要么都不执行,它的实现机制决定了它对待一致性的行为非常严格,这也能非常完美的保证 MySQL 集群的数据一致性;
1.2 PXC特性和优点
- 完全兼容 MySQL。
- 同步复制,事务要么在所有节点提交或不提交。
- 多主复制,可以在任意节点进行写操作。
- 在从服务器上并行应用事件,真正意义上的并行复制。
- 节点自动配置,数据一致性,不再是异步复制。
- 故障切换:因为支持多点写入,所以在出现数据库故障时可以很容易的进行故障切换。
- 自动节点克隆:在新增节点或停机维护时,增量数据或基础数据不需要人工手动备份提供,galera cluster会自动拉取在线节点数据,集群最终会变为一致;
PXC最大的优势:强一致性、无同步延迟
1.3 PXC的局限和劣势
- 复制只支持InnoDB 引擎,其他存储引擎的更改不复制
- 写入效率取决于节点中最慢的一台
1.4 PXC 常用端口
- 3306:数据库对外服务的端口号。
- 4444:请求SST的端口。
- 4567:组成员之间进行沟通的一个端口号
- 4568:用于传输IST。
二、搭建 PXC 集群
环境
centos7 4台
192.168.0.4 node1 pxc5.7.28
192.168.0.5 node2 pxc5.7.28
192.168.0.6 node3 pxc5.7.28
192.168.0.7 node4 pxc5.7.28
准备环境
四台主机分别都做解析 /etc/hosts
[root@admin ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.4 node1
192.168.0.5 node2
192.168.0.6 node3
192.168.0.7 node4
关闭防火墙和selinux
下载pxc相关的包
wget https://www.percona.com/downloads/Percona-XtraDB-Cluster-LATEST/Percona-XtraDB-Cluster-5.7.28-31.41-2/binary/redhat/7/x86_64/Percona-XtraDB-Cluster-5.7.28-31.41-r536-el7-x86_64-bundle.tar
tar -xf Percona-XtraDB-Cluster-5.7.28-31.41-r514-el7-x86_64-bundle.tar
root@node3 ~]# ls
Percona-XtraDB-Cluster-5.7.28-31.41-r514-el7-x86_64-bundle.tar
Percona-XtraDB-Cluster-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-57-debuginfo-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-client-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-devel-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-full-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-garbd-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-server-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-shared-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-shared-compat-57-5.7.28-31.41.1.el7.x86_64.rpm
Percona-XtraDB-Cluster-test-57-5.7.28-31.41.1.el7.x86_64.rpm
下载percona-release配置Percona存储库
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
percona-release enable-only tools release
安装
yum -y localinstall *.rpm
如果出现下面的报错
Failing package is: percona-xtrabackup-24-2.4.20-1.el7.x86_64
GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Percona
则要将percona-release更新
percona-release enable original
yum update percona-release
yum -y localinstall *.rpm
启动mysqld修改密码(每个节点的密码必须保持一致)
systemctl restart mysql
mysql_pass=`grep 'password is generated' /var/log/mysqld.log |awk '{print $NF}' |awk 'END{print}'` && echo $mysql_pass
mysql -u root -p${mysql_pass}
ALTER USER 'root'@'localhost' IDENTIFIED BY 'rootPass';
grant all on *.* to 'sstuser'@'%' identified by 's3cret';
flush privileges;
exit
systemctl stop mysql
再在/etc/my.cnf配置文件中添加(根据不同节点做少量的修改)
[mysqld]
datadir=/var/lib/mysql
user=mysql
wsrep_provider=/usr/lib64/libgalera_smm.so #指定Galera库的路径
wsrep_cluster_name=pxc #Galera集群的名称
wsrep_cluster_address=gcomm://192.168.0.4,192.168.0.5,192.168.0.6,192.168.0.7 #Galera集群中各节点地址。
binlog_format=ROW #二进制日志的格式。#Galera只支持row格式的二进制日志
default_storage_engine=InnoDB #指定默认存储引擎。Galera的复制功能只支持InnoDB
innodb_autoinc_lock_mode=2 #只能设置为2,设置为0或1时会无法正确处理死锁问题
wsrep_node_name=node1 #本节点在Galera集群中的名称
wsrep_node_address=192.168.0.4 #本节点在Galera集群中的通信地址
wsrep_sst_method=xtrabackup-v2 #state_snapshot_transfer(SST)使用的传输方法,可用方法有mysqldump、rsync和xtrabackup,前两者在传输时都需要对Donor加全局只读锁(FLUSH TABLES WITH READ LOCK),xtrabackup则不需要(它使用percona自己提供的backup lock)。强烈建议采用xtrabackup
wsrep_sst_auth="sstuser:s3cret" #在SST传输时需要用到的认证凭据,格式为:"用户:密码"
节点的数据库的登陆和master节点的用户名密码一致,自动同步。所以其它的节点数据库用户名密码无须重新设置。
也就是说,如上设置,只需要在名义上的master节点(如上的node1)上设置权限,其它的节点配置好/etc/my.cnf后,只需要启动mysql就行,权限会自动同步过来。
开启第一个节点
临时的master节点,当第二个节点连接进来后,就没有主从之分了
systemctl start mysql@bootstrap.service
开启其他节点
systemctl start mysql
如果是其他节点启动不了
查看/var/lib/mysql下的err日志报错如下
[ERROR]WSREP: gcs/src/gcs_group.cpp:long int gcs_group_handle_join_msg(gcs_
- 查看节点上的iptables防火墙是否关闭;检查到名义上的master节点上的4567端口是否连通(telnet)
- selinux是否关闭
- 删除名义上的master节点上的grastate.dat后,重启名义上的master节点的数据库;当然当前节点上的grastate.dat也删除并重启数据库
如果是node1启动不了
查看/var/lib/mysql下的err日志报错如下
2020-04-19T16:43:29.302640Z 0 [ERROR] WSREP: It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .
2020-04-19T16:43:29.302642Z 0 [ERROR] WSREP: Provider/Node (gcomm://192.168.0.4,192.168.0.5,192.168.0.7) failed to establish connection with cluster (reason: 7)
2020-04-19T16:43:29.302644Z 0 [ERROR] Aborting
解决办法:
将grastate.dat中的0改为1
vim /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: 755c0452-8259-11ea-bd41-6a788f6d7d46
seqno: -1
safe_to_bootstrap: 1
启动成功后,进入数据库中,查看集群的状态
查看集群是否启动
mysql> show status like 'wsrep_ready';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_ready | ON |
+---------------+-------+
1 row in set (0.00 sec)
查看集群的成员数
mysql> show status like 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.00 sec)
查看wsrep的相关参数
mysql> show status like 'wsrep%';
+----------------------------------+----------------------------------------------------+
| Variable_name | Value |
+----------------------------------+----------------------------------------------------+
| wsrep_local_state_uuid | 755c0452-8259-11ea-bd41-6a788f6d7d46 |
| wsrep_protocol_version | 9 |
| wsrep_last_applied | 9 |
| wsrep_last_committed | 9 |
| wsrep_replicated | 1 |
| wsrep_replicated_bytes | 200 |
| wsrep_repl_keys | 1 |
| wsrep_repl_keys_bytes | 32 |
| wsrep_repl_data_bytes | 102 |
| wsrep_repl_other_bytes | 0 |
| wsrep_received | 4 |
| wsrep_received_bytes | 608 |
| wsrep_local_commits | 0 |
| wsrep_local_cert_failures | 0 |
| wsrep_local_replays | 0 |
| wsrep_local_send_queue | 0 |
| wsrep_local_send_queue_max | 1 |
| wsrep_local_send_queue_min | 0 |
| wsrep_local_send_queue_avg | 0.000000 |
| wsrep_local_recv_queue | 0 |
| wsrep_local_recv_queue_max | 1 |
| wsrep_local_recv_queue_min | 0 |
| wsrep_local_recv_queue_avg | 0.000000 |
| wsrep_local_cached_downto | 9 |
| wsrep_flow_control_paused_ns | 0 |
| wsrep_flow_control_paused | 0.000000 |
| wsrep_flow_control_sent | 0 |
| wsrep_flow_control_recv | 0 |
| wsrep_flow_control_interval | [ 173, 173 ] |
| wsrep_flow_control_interval_low | 173 |
| wsrep_flow_control_interval_high | 173 |
| wsrep_flow_control_status | OFF |
| wsrep_cert_deps_distance | 1.000000 |
| wsrep_apply_oooe | 0.000000 |
| wsrep_apply_oool | 0.000000 |
| wsrep_apply_window | 1.000000 |
| wsrep_commit_oooe | 0.000000 |
| wsrep_commit_oool | 0.000000 |
| wsrep_commit_window | 1.000000 |
| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |
| wsrep_cert_index_size | 1 |
| wsrep_cert_bucket_count | 22 |
| wsrep_gcache_pool_size | 1560 |
| wsrep_causal_reads | 0 |
| wsrep_cert_interval | 0.000000 |
| wsrep_open_transactions | 0 |
| wsrep_open_connections | 0 |
| wsrep_ist_receive_status | |
| wsrep_ist_receive_seqno_start | 0 |
| wsrep_ist_receive_seqno_current | 0 |
| wsrep_ist_receive_seqno_end | 0 |
| wsrep_incoming_addresses | 192.168.0.4:3306,192.168.0.5:3306,192.168.0.6:3306,192.168.0.7:3306 |
| wsrep_cluster_weight | 4 |
| wsrep_desync_count | 0 |
| wsrep_evs_delayed | |
| wsrep_evs_evict_list | |
| wsrep_evs_repl_latency | 0/0/0/0/0 |
| wsrep_evs_state | OPERATIONAL |
| wsrep_gcomm_uuid | ba642bd4-825d-11ea-9e1d-1ea0bdb4eb27 |
| wsrep_cluster_conf_id | 3 |
| wsrep_cluster_size | 3 |
| wsrep_cluster_state_uuid | 755c0452-8259-11ea-bd41-6a788f6d7d46 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| wsrep_local_bf_aborts | 0 |
| wsrep_local_index | 0 |
| wsrep_provider_name | Galera |
| wsrep_provider_vendor | Codership Oy <info@codership.com> |
| wsrep_provider_version | 3.41(rb3295e6) |
| wsrep_ready | ON |
+----------------------------------+----------------------------------------------------+
71 rows in set (0.00 sec)
从怎么的查看,可以看出pxc集群已经搭建成功。测试环节就不测试了,无非就是创库创表导入数据。
新增节点加入Galera集群
1.新节点加入Galera集群
新节点加入集群时,需要从当前集群中选择一个Donor节点来同步数据,也就是所谓的state_snapshot_tranfer(SST)过程。SST同步数据的方式由选项wsrep_sst_method决定,一般选择的是xtrabackup。
必须注意,新节点加入Galera时,会删除新节点上所有已有数据,再通过xtrabackup(假设使用的是该方式)从Donor处完整备份所有数据进行恢复。所以,如果数据量很大,新节点加入过程会很慢。而且,在一个新节点成为Synced状态之前,不要同时加入其它新节点,否则很容易将集群压垮。
如果是这种情况,可以考虑使用wsrep_sst_method=rsync来做增量同步,既然是增量同步,最好保证新节点上已经有一部分数据基础,否则和全量同步没什么区别,且这样会对Donor节点加上全局read only锁。
2.旧节点加入Galera集群
如果旧节点加入Galera集群,说明这个节点在之前已经在Galera集群中呆过,有一部分数据基础,缺少的只是它离开集群时的数据。这时加入集群时,会采用IST(incremental snapshot transfer)传输机制,即使用增量传输。
但注意,这部分增量传输的数据源是Donor上缓存在GCache文件中的,这个文件有大小限制,如果缺失的数据范围超过已缓存的内容,则自动转为SST传输。如果旧节点上的数据和Donor上的数据不匹配(例如这个节点离组后人为修改了一点数据),则自动转为SST传输。