一、PXC 介紹
1.1 PXC 簡(jiǎn)介
PXC 是一套 MySQL 高可用集群解決方案,與傳統(tǒng)的基于主從復(fù)制模式的集群架構(gòu)相比 PXC 最突出特點(diǎn)就是解決了詬病已久的數(shù)據(jù)復(fù)制延遲問(wèn)題,基本上可以達(dá)到實(shí)時(shí)同步。而且節(jié)點(diǎn)與節(jié)點(diǎn)之間,他們相互的關(guān)系是對(duì)等的。PXC 最關(guān)注的是數(shù)據(jù)的一致性,對(duì)待事物的行為時(shí),要么在所有節(jié)點(diǎn)上執(zhí)行,要么都不執(zhí)行,它的實(shí)現(xiàn)機(jī)制決定了它對(duì)待一致性的行為非常嚴(yán)格,這也能非常完美的保證 MySQL 集群的數(shù)據(jù)一致性;
1.2 PXC特性和優(yōu)點(diǎn)
- 完全兼容 MySQL。
- 同步復(fù)制,事務(wù)要么在所有節(jié)點(diǎn)提交或不提交。
- 多主復(fù)制,可以在任意節(jié)點(diǎn)進(jìn)行寫(xiě)操作。
- 在從服務(wù)器上并行應(yīng)用事件,真正意義上的并行復(fù)制。
- 節(jié)點(diǎn)自動(dòng)配置,數(shù)據(jù)一致性,不再是異步復(fù)制。
- 故障切換:因?yàn)橹С侄帱c(diǎn)寫(xiě)入,所以在出現(xiàn)數(shù)據(jù)庫(kù)故障時(shí)可以很容易的進(jìn)行故障切換。
- 自動(dòng)節(jié)點(diǎn)克?。涸谛略龉?jié)點(diǎn)或停機(jī)維護(hù)時(shí),增量數(shù)據(jù)或基礎(chǔ)數(shù)據(jù)不需要人工手動(dòng)備份提供,galera cluster會(huì)自動(dòng)拉取在線(xiàn)節(jié)點(diǎn)數(shù)據(jù),集群最終會(huì)變?yōu)橐恢拢?/li>
PXC最大的優(yōu)勢(shì):強(qiáng)一致性、無(wú)同步延遲
1.3 PXC的局限和劣勢(shì)
- 復(fù)制只支持InnoDB 引擎,其他存儲(chǔ)引擎的更改不復(fù)制
- 寫(xiě)入效率取決于節(jié)點(diǎn)中最慢的一臺(tái)
1.4 PXC 常用端口
- 3306:數(shù)據(jù)庫(kù)對(duì)外服務(wù)的端口號(hào)。
- 4444:請(qǐng)求SST的端口。
- 4567:組成員之間進(jìn)行溝通的一個(gè)端口號(hào)
- 4568:用于傳輸IST。
二、搭建 PXC 集群
環(huán)境
centos7 4臺(tái)
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
準(zhǔn)備環(huán)境
四臺(tái)主機(jī)分別都做解析 /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
關(guān)閉防火墻和selinux
下載pxc相關(guān)的包
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存儲(chǔ)庫(kù)
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
percona-release enable-only tools release
安裝
yum -y localinstall *.rpm
如果出現(xiàn)下面的報(bào)錯(cuò)
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
啟動(dòng)mysqld修改密碼(每個(gè)節(jié)點(diǎn)的密碼必須保持一致)
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配置文件中添加(根據(jù)不同節(jié)點(diǎn)做少量的修改)
[mysqld]
datadir=/var/lib/mysql
user=mysql
wsrep_provider=/usr/lib64/libgalera_smm.so #指定Galera庫(kù)的路徑
wsrep_cluster_name=pxc #Galera集群的名稱(chēng)
wsrep_cluster_address=gcomm://192.168.0.4,192.168.0.5,192.168.0.6,192.168.0.7 #Galera集群中各節(jié)點(diǎn)地址。
binlog_format=ROW #二進(jìn)制日志的格式。#Galera只支持row格式的二進(jìn)制日志
default_storage_engine=InnoDB #指定默認(rèn)存儲(chǔ)引擎。Galera的復(fù)制功能只支持InnoDB
innodb_autoinc_lock_mode=2 #只能設(shè)置為2,設(shè)置為0或1時(shí)會(huì)無(wú)法正確處理死鎖問(wèn)題
wsrep_node_name=node1 #本節(jié)點(diǎn)在Galera集群中的名稱(chēng)
wsrep_node_address=192.168.0.4 #本節(jié)點(diǎn)在Galera集群中的通信地址
wsrep_sst_method=xtrabackup-v2 #state_snapshot_transfer(SST)使用的傳輸方法,可用方法有mysqldump、rsync和xtrabackup,前兩者在傳輸時(shí)都需要對(duì)Donor加全局只讀鎖(FLUSH TABLES WITH READ LOCK),xtrabackup則不需要(它使用percona自己提供的backup lock)。強(qiáng)烈建議采用xtrabackup
wsrep_sst_auth="sstuser:s3cret" #在SST傳輸時(shí)需要用到的認(rèn)證憑據(jù),格式為:"用戶(hù):密碼"
節(jié)點(diǎn)的數(shù)據(jù)庫(kù)的登陸和master節(jié)點(diǎn)的用戶(hù)名密碼一致,自動(dòng)同步。所以其它的節(jié)點(diǎn)數(shù)據(jù)庫(kù)用戶(hù)名密碼無(wú)須重新設(shè)置。
也就是說(shuō),如上設(shè)置,只需要在名義上的master節(jié)點(diǎn)(如上的node1)上設(shè)置權(quán)限,其它的節(jié)點(diǎn)配置好/etc/my.cnf后,只需要啟動(dòng)mysql就行,權(quán)限會(huì)自動(dòng)同步過(guò)來(lái)。
開(kāi)啟第一個(gè)節(jié)點(diǎn)
臨時(shí)的master節(jié)點(diǎn),當(dāng)?shù)诙€(gè)節(jié)點(diǎn)連接進(jìn)來(lái)后,就沒(méi)有主從之分了
systemctl start mysql@bootstrap.service
開(kāi)啟其他節(jié)點(diǎn)
systemctl start mysql
如果是其他節(jié)點(diǎn)啟動(dòng)不了
查看/var/lib/mysql下的err日志報(bào)錯(cuò)如下
[ERROR]WSREP: gcs/src/gcs_group.cpp:long int gcs_group_handle_join_msg(gcs_
- 查看節(jié)點(diǎn)上的iptables防火墻是否關(guān)閉;檢查到名義上的master節(jié)點(diǎn)上的4567端口是否連通(telnet)
- selinux是否關(guān)閉
- 刪除名義上的master節(jié)點(diǎn)上的grastate.dat后,重啟名義上的master節(jié)點(diǎn)的數(shù)據(jù)庫(kù);當(dāng)然當(dāng)前節(jié)點(diǎn)上的grastate.dat也刪除并重啟數(shù)據(jù)庫(kù)
如果是node1啟動(dòng)不了
查看/var/lib/mysql下的err日志報(bào)錯(cuò)如下
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
啟動(dòng)成功后,進(jìn)入數(shù)據(jù)庫(kù)中,查看集群的狀態(tài)
查看集群是否啟動(dòng)
mysql> show status like 'wsrep_ready';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_ready | ON |
+---------------+-------+
1 row in set (0.00 sec)
查看集群的成員數(shù)
mysql> show status like 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.00 sec)
查看wsrep的相關(guān)參數(shù)
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集群已經(jīng)搭建成功。測(cè)試環(huán)節(jié)就不測(cè)試了,無(wú)非就是創(chuàng)庫(kù)創(chuàng)表導(dǎo)入數(shù)據(jù)。
新增節(jié)點(diǎn)加入Galera集群
1.新節(jié)點(diǎn)加入Galera集群
新節(jié)點(diǎn)加入集群時(shí),需要從當(dāng)前集群中選擇一個(gè)Donor節(jié)點(diǎn)來(lái)同步數(shù)據(jù),也就是所謂的state_snapshot_tranfer(SST)過(guò)程。SST同步數(shù)據(jù)的方式由選項(xiàng)wsrep_sst_method決定,一般選擇的是xtrabackup。
必須注意,新節(jié)點(diǎn)加入Galera時(shí),會(huì)刪除新節(jié)點(diǎn)上所有已有數(shù)據(jù),再通過(guò)xtrabackup(假設(shè)使用的是該方式)從Donor處完整備份所有數(shù)據(jù)進(jìn)行恢復(fù)。所以,如果數(shù)據(jù)量很大,新節(jié)點(diǎn)加入過(guò)程會(huì)很慢。而且,在一個(gè)新節(jié)點(diǎn)成為Synced狀態(tài)之前,不要同時(shí)加入其它新節(jié)點(diǎn),否則很容易將集群壓垮。
如果是這種情況,可以考慮使用wsrep_sst_method=rsync來(lái)做增量同步,既然是增量同步,最好保證新節(jié)點(diǎn)上已經(jīng)有一部分?jǐn)?shù)據(jù)基礎(chǔ),否則和全量同步?jīng)]什么區(qū)別,且這樣會(huì)對(duì)Donor節(jié)點(diǎn)加上全局read only鎖。
2.舊節(jié)點(diǎn)加入Galera集群
如果舊節(jié)點(diǎn)加入Galera集群,說(shuō)明這個(gè)節(jié)點(diǎn)在之前已經(jīng)在Galera集群中呆過(guò),有一部分?jǐn)?shù)據(jù)基礎(chǔ),缺少的只是它離開(kāi)集群時(shí)的數(shù)據(jù)。這時(shí)加入集群時(shí),會(huì)采用IST(incremental snapshot transfer)傳輸機(jī)制,即使用增量傳輸。
但注意,這部分增量傳輸?shù)臄?shù)據(jù)源是Donor上緩存在GCache文件中的,這個(gè)文件有大小限制,如果缺失的數(shù)據(jù)范圍超過(guò)已緩存的內(nèi)容,則自動(dòng)轉(zhuǎn)為SST傳輸。如果舊節(jié)點(diǎn)上的數(shù)據(jù)和Donor上的數(shù)據(jù)不匹配(例如這個(gè)節(jié)點(diǎn)離組后人為修改了一點(diǎn)數(shù)據(jù)),則自動(dòng)轉(zhuǎn)為SST傳輸。