搭建mysql高可用集群之PXC

一、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传输。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容