PXC简介:
Percona XtraDB Cluster是MySQL的完全开源高可用性解决方案。它将Percona Server和Percona XtraBackup与Galera库集成在一起,以实现同步多主复制。
PXC属于一套近乎完美的mysql高可用集群解决方案,相比那些比较传统的基于主从复制模式的集群架构MHA和MM+keepalived,galera cluster最突出特点就是解决了诟病已久的数据复制延迟问题,基本上可以达到实时同步。而且节点与节点之间,他们相互的关系是对等的。本身galera cluster也是一种多主架构。galera cluster最关注的是数据的一致性,对待事物的行为时,要么在所有节点上执行,要么都不执行,它的实现机制决定了它对待一致性的行为非常严格,这也能非常完美的保证MySQL集群的数据一致性;
对galera cluster的封装有两个,虽然名称不同,但实质都是一样的,使用的都是galera cluster。一个MySQL的创始人在自己全新的MariaDB上实现的MAriaDB cluster;一个是著名的MySQL服务和工具提供商percona实现的percona xtradb cluster,简称PXC
要搭建PXC架构至少需要3个mysql实例来组成一个集群,三个实例之间不是主从模式,而是各自为主,所以三者是对等关系,不分从属,这就叫multi-master架构。客户端写入和读取数据时,连接哪个实例都是一样的。读取到的数据时相同的,写入任意一个实例之后,集群自己会将新写入的数据同步到其他实例上,这种架构不共享任何数据,是一种高冗余架构。
pxc特性:
PXC的优点:
1、实现mysql数据库集群架构的高可用性和数据的 强一致性。
2、完成了真正的多节点读写的集群方案。
3、改善了传统意义上的主从复制延迟问题,基本上达到了实时同步。
4、新加入的节点可以自动部署,无须提供手动备份,维护起来很方便。
5、由于是多节点写入,所以数据库故障切换很容易。
PXC的缺点:
1、只支持InnoDB引擎;当前版本(5.6.20)的复制只支持InnoDB引擎,其他存储引擎的更改不复制。然而,DDL(Data Definition Language) 语句在statement级别被复制,并且,对mysql.*表的更改会基于此被复制。例如CREATE USER...语句会被复制,但是 INSERT INTO mysql.user...语句则不会,(也可以通过wsrep_replicate_myisam参数开启myisam引擎的复制,但这是一个实验性的参数)。
2、由于群集级别的乐观并发控制,COMMIT在该阶段可能仍中止事务发布。可以有两个事务写入同一行并在不同的Percona XtraDB Cluster节点中提交,而其中只有一个可以成功提交。失败的将被中止。对于集群级中止,Percona XtraDB集群返回死锁错误代码:
(错误: 1213 SQLSTATE : 40001 (ER_LOCK_DEADLOCK ))。
3、写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功;
4、所有表都要有主键;
5、不支持LOCK TABLE等显式锁操作;
6、锁冲突、死锁问题相对更多;
7、不支持XA事务,因为可能会在提交时回滚;
8、集群吞吐量/性能取决于短板;
9、新加入节点采用SST时代价高;
10、存在写扩大问题;
11、如果并发事务量很大的话,建议采用InfiniBand网络,降低网络延迟;
PXC端口号:
3306-数据库对外服务的端口号。
4444-请求SST的端口(SST是指数据库一个备份全量文件的传输。)
4567-组成员之间进行沟通的一个端口号
4568-用于传输IST(相对于SST来说的一个增量)
准备三台虚拟机:
192.168.0.232 mysql-pxc001
192.168.0.233 mysql-pxc002
192.168.0.234 mysql-pxc003
软件安装:
1、先清理原环境:
yum remove percona*
2、检查端口是否占用:
3306 4444 4567 4568
netstat -lntup
3、禁用selinux:
#临时关闭
setenforce 0
#永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
#查询
getenforce
4、配置percona的yum源:
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
5、下载pxc软件程序:
yum install Percona-XtraDB-Cluster-57 -y
6、启动Percona XtraDB Cluster server
systemctl start mysql
7、获取临时生成的超级用户帐密信息
grep 'temporary password' /var/log/mysqld.log
8、登录数据库
mysql -u root -p
9、更改root用户密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
10、停止mysql服务
systemctl stop mysql
(以上步骤在三个节点都要执行、软件yum安装很慢,可配置清华源,待验证;)
集群配置
1、编辑/etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql.log
log-bin=/var/lib/mysqlbin
binlog_format=row
secure-file-priv=/tmp
server-id=51
log-slave-updates=1
relay_log_purge = 0
skip-name-resolve
expire_logs_days=30
pid-file=/var/run/mysqld/mysqld.pid
# 集群名称
wsrep_cluster_name=pxc-cluster
# 集群中节点的ip
wsrep_cluster_address=gcomm://192.168.0.232,192.168.0.233,192.168.0.234
# 当前节点信息
wsrep_node_name=mysql-pxc001
wsrep_node_address=192.168.0.232
# --------------------以下信息不用修改----------------------
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
[mysql]
socket=/var/lib/mysql/mysql.sock
在第二个、第三个节点上重复同样的配置,但需要修改以下两个配置项:
第二个节点:
wsrep_node_name=mysql-pxc002
wsrep_node_address=192.168.0.233
第三个节点:
wsrep_node_name=mysql-pxc003
wsrep_node_address=192.168.0.234
2.启动第一个节点:
systemctl start mysql@bootstrap.service
采用bootstrap启动,其实是告诉数据库,这是第一个节点,不用从其他节点做数据同步。利用这种方式启动,相当于wsrep_cluster_address方式设置为gcomm://
查看服务状态:
systemctl status mysql@bootstrap
进入数据库查看状态:
mysql -uroot -p
show status like '%wsrep%';
wsrep_cluster_size 当前集群大小
wsrep_local_state_comment 数据同步状态 Synced表示处于ready状态
状态机变化阶段(wsrep_local_state_comment):
1)OPEN: 节点启动成功,尝试连接到集群,如果失败则根据配置退出或创建新的集群
2)PRIMARY: 节点处于集群PC(primary component)中,尝试从集群中选取donor进行数据同步
3)JOINER: 节点处于等待接收/接收数据文件状态,数据传输完成后在本地加载数据
4)JOINED: 节点完成数据同步工作,尝试保持和集群进度一致
5)SYNCED:节点正常提供服务:数据的读写,集群数据的同步,新加入节点的sst请求
6)DONOR(贡献数据者):节点处于为新节点准备或传输集群全量数据状态,对客户端不可用
3.配置XtraBackup鉴权信息
在上面的配置文件中,有个wsrep_sst_auth参数。该参数是用于其它节点加入到该集群中,利用XtraBackup执行State Snapshot Transfer(类似于全量同步)的。
需要登录数据库做如下配置:
CREATE USER 'sstuser' IDENTIFIED BY 'passw0rd';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sstuser';
FLUSH PRIVILEGES;
4.新增节点到集群
如果第1步中,我们已经配置好了/etc/my.cnf,那可以直接启动mysql服务:
登录第二个节点,执行:
systemctl start mysql
查看服务状态:
systemctl status mysql
进入mysql查看状态:
show status like 'wsrep%';
此时可以看到wsrep_cluster_size已经变为2。
同理,在第三个节点上执行同样的操作,wsrep_cluster_size最终应该为3.
至此,集群配置结束。
集群验证
为了验证集群的同步复制是否生效,我们采用以下思路来做验证:
- 在node2上创建percona数据库
- 在node3上为percona数据库创建表
- 在node1上添加一些记录到表中
- 查看各个node上的数据是否一致
1.在mysql-pxc001上创建percona数据库
CREATE DATABASE percona;
2.在mysql-pxc002上查看数据库
3.再mysql-pxc003上创建表
create table student (id int primary key,name varchar(30));
4.在mysql-pxc002上插入一条数据
insert into percona.student values (1,'xiaoming');
5.各节点访问,验证数据一致性
启动关闭:
当galera cluster集群单个节点或所有节点停机情况分析
单个节点停机
节点停机重启,重新加入集群,通过IST增量同步数据,来保持集群数据的一致性。IST的实现由wsrep_provider_options="gcache.size=1G"参数决定,一般设置为1G。参数大小由什么决定,根据停机时间,若停机一小时,需要确认一小时产生多大的binlog来算出参数大小。如果停机时间过长,部分数据gcache没有,此时该节点SST全量同步数据。
- 所有节点关闭,应采用轮巡滚动关闭的方式:a节点关闭修复,加回集群;b节点关闭修复,加回集群...原则就是保持cluster中最少一个成员存活,进行滚动重启。
3,集群所有节点都关闭了,没有存活的节点的情况:每个节点数据库关闭后,都会保存最后一个GTID,启动集群时要先启动最后一个关闭的节点,启动顺序和关闭顺序相反。 - 避免关闭和启动节点时数据丢失
3.1 原则保持cluster集群中最少有一个成员存货,然后进行滚动重启
3.2 利用主从的概念,把一个从节点转化为PXC/Galera集群中的节点
增加或者删除节点:
增加节点:
1,如果是之前旧节点恢复了只需要启动就可以了,会自动加入集群。
2,如果是新搭建的机器,还是按照之前安装集群的方法装好这台机器,然后修改其他节点的/etc/my.cnf中的wsrep_cluster_address=gcomm://,修改其他节点的my.cnf文件后不需要重启。
删除节点:
直接停掉该节点的mysql,修改my.cnf中wsrep_cluster_address=gcomm://,然后修改其他节点/etc/my.cnf把停掉的节点ip在wsrep_cluster_address=gcomm://中删除掉,修改完my.cnf后不需要重启。
PXC集群恢复排错:
gvwstate.dat : ThisfileisusedforPrimaryComponentrecoveryfeaturegrastate.dat:ThisfilecontainstheGalerastateinformation.
情景1:三个节点挂了2个(正常关闭):
node1,node2挂了,node3存活
在node1,node2上执行:
#service mysql start --wsrep_sst_donor=node3
注意:当某个node被宣威donor时,使用rsync或者dump时,该节点无法提供服务。即使使用xtrabackup这个节点性能也会收到影响,建议手动选择donar,避免高负载的机器被用来做donar,不指定则随机选择。
情景2:三个节点全部挂了(正常关闭):
在node1上执行:
#systemctl start mysql@bootstrap.service
在node2,node3上执行:
#systemctl start mysql
情景3:node1,node2不见了(非正常关闭),node3无法单独形成仲裁,同时它会变成non-primary状态并且不会处理任何请求。
在node3上执行命令:
mysql> select * fromtest.t1;
ERROR 1047 (08S01): Unknowncommand
查看节点日志:
140814 0:42:13[Note]WSREP: commitfailedforreason: 3
140814 0:42:13[Note]WSREP: conflictstate: 0
140814 0:42:13[Note]WSREP: clusterconflictduetocertificationfailureforthreads:
140814 0:42:13[Note]WSREP: Victimthread:
THD: 7, mode: local, state: executing, conflict: certfailure, seqno: -1SQL: insertintotvalues (1)
解决办法:
在node3上执行(告诉node3你可以自己组成一个新集群):
SETGLOBAL wsrep_provider_options='pc.bootstrap=true';
注意:在执行命令之前一定要确认node1,node2确实挂了,否则会造成数据不一致。
情景4,所有节点突然掉电
#cat /var/lib/mysql/grastate.dat# GALERA saved state
version: 2.1
uuid: 220dcdcb-1629-11e4-add3-aec059ad3734
seqno: -1
cert_index:
因为突然掉电,不确定哪个节点的数据是最新的,查看gvwstate.dat文件找出最新的seqno
#cat /var/lib/mysql/gvwstate.dat
my_uuid: 76de8ad9-2aac-11e4-8089-d27fd06893b9
#vwbeg
view_id: 3 6c821ecc-2aac-11e4-85a5-56fe513c651f 3
bootstrap: 0
member: 6c821ecc-2aac-11e4-85a5-56fe513c651f 0
member: 6d80ec1b-2aac-11e4-8d1e-b2b2f6caf018 0
member: 76de8ad9-2aac-11e4-8089-d27fd06893b9 0
#vwend
实际上在 PXC5.6.19以后的系统会根据这个文件自动找到seqno最大的节点,从而自动启动数据恢复过程,不需要人工干预。如果实在不行就在该文件中找到最新的节点,手动在该节点上执行SET GLOBAL wsrep_provider_options='pc.bootstrap=true'(同情景2处理方法一样);
两节点集群排错:
解决方法:
在其中一个节点上初始化所有集群,并且将该节点设为新的Primary Component
mysql> SET GLOBAL wsrep_provider_options='pc.bootstrap=YES';
如果你想该节点可以同时处理请求,执行如下命令:
mysql> SET GLOBAL wsrep_provider_options='pc.ignore_sb=TRUE';
注意:在多主节点中执行这个很危险,会有脑裂的风险。所以该命令尽量只在主从环境中执行。
perconaXtraDB cluster中有两种参数可用于在通信断开时防止节点降级为non-primary状态。分别为pc.ignore_quorum和pc.ignore_sb。
pc.ignore_quorum参数设置为true的时候,节点忽略quorum算法,节点正常运行。
pc.ignore_sb是当节点通讯关闭,发生脑裂时,忽略为防止脑裂时数据不一致而无法执行语句的机制,可以在各个节点正常运行命令。
例1:
在各节点my.cnf中加入wsrep_provider_options = "pc.ignore_quorum =true" 参数,断开节点间网络。
可以看到两个节点都没有降级到non-primary状态,不会降级并且可以各自处理请求。但是当网络恢复之后,点不会自动恢复到同步状态,不会发生数据同步,双节点各自形成一个cluter。
如果要恢复集群模式,只能通过SST方式将数据同步,但是会造成一个节点的数据丢失!
例2:
在各节点my.cnf中加入wsrep_provider_options = "pc.ignore_sb = true" 参数,断开节点间网络。
可以看到两个节点都没有降级到non-primary状态,向两个节点插入不同的数据后恢复网络,集群不会恢复到原来的状态,
重启备节点,由于备节点多插入了数据,seqno比主节点的高,所以重启失败。节点间无法构成集群,只能删除数据重新进行SST。
HAproxy负载均衡pxc集群
1.安装HAproxy
yum install haproxy -y
2.编辑配置文件
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen admin_stats
bind 0.0.0.0:8888
balance roundrobin
mode http
stats uri /dbs
stats realm Global\statistics
stats auth admin:admin
listen proxy
bind 0.0.0.0:3307
balance roundrobin
mode tcp
option tcplog
option mysql-check user haproxy
server mysql_1 192.168.0.232:3306 check weight 1 maxconn 2000
server mysql_2 192.168.0.233:3306 check weight 1 maxconn 2000
server mysql_1 192.168.0.234:3306 check weight 1 maxconn 2000
option tcpka
3.在mysql数据库创建用于haproxy心跳检测的用户haproxy(只有登陆权限,权限最小化)
create user 'haproxy'@'%';
#这个%可以具体到只有haproxy可以进行连接
4.访问haproxy的页面进行检测mysql的节点状态
在此可以down掉一个mysql节点做检测,绿色会变红,此处不做截图
5.通过负载均衡端口进行登陆测试
至此测试完成;关于haproxy的单点问题我们可以基于keepalived做高可用!
参考文档
https://www.atatech.org/articles/134058?spm=ata.13269325.0.0.4eeb49fa1Ms26m#13
https://www.percona.com/doc/percona-xtradb-cluster/5.7/howtos/virt_sandbox.html