搭建PXC集群指引

背景

因为客户有一套PXC(Percona Xtradb Cluster)集群,有运维的需求,所以需要研究和测试PXC,现整理一套完整的搭建PXC标准文档,以供后面测试和学习用途。

mariadb的MGC(MariaDB Galera Cluster)集群仿造percona的PXC集群的,都是基于Totem协议的第三方插件Galera Cluster的数据同步技术的多主高可用解决方案,原理和搭建步骤都是一样的,所以本文也可以用于指导MGC集群的搭建。

架构图

PXC架构图

PXC的特点

优点

  • 多主架构
    • 真正的多点读写集群,在任何时候读写的数据都是最新的。
  • 同步复制
    • 集群不同节点之间的数据同步,没有延迟,在数据库挂掉之后,数据不会丢失
  • 并发复制
    • 从节点在APPLY数据时,支持并行执行,有更好的性能表现
  • 故障切换
    • 因为支持多点写入,所以在出现数据库故障时可以很容易地进行故障切换
  • 热插拔
    • 在服务期间,如果数据库挂了,只要监控程序发现得够快,不可服务时间就会非常少。在节点故障期间,节点本身对集群的影响非常小
  • 自动节点克隆
    • 在新增节点或停机维护时,增量数据或基础数据不需要人工手动备份提供,Galera Cluster会自动拉取在线节点数据,集群最终会变为一致。
  • 对应用透明
    集群的维护,对应用是透明的,几乎感觉不到。

缺点

  • 短板效应
    • 集群写入性能取决于性能最差那台机器,所以建议配置相同
  • 锁冲突严重
    • 建议单节点写+负载均衡
    • 或者写不同的库
  • 全量SST时,donor节点性能影响较为严重,receiver恢复较慢
    • 尽量避免SST
  • 维护成本高,限制和注意事项较多

搭建指引

机器准备

Node Host IP
Node 1 pxc1 192.168.1.101
Node 2 pxc2 192.168.1.102
Node 3 pxc3 192.168.1.103

避免创建具有两个或任意偶数节点的群集,因为这可能导致脑裂。

安装前准备

  • 三台服务器互相免密登录

SST全量同步是需要用到xtrabackup的远程流备份功能,这需要免密登录

  • 关闭iptables/firewall
  • 关闭SELinux
#建立免密
略

#关闭selinux
#selinux配置文件修改
vim /etc/selinux/config
SELINUX=disabled

#临时在线关闭selinux
setenforce 0

#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

为的是确保以下端口未被防火墙阻止或被其他软件使用。Percona XtraDB Cluster需要它们进行通信。
默认值如下:
3306 : 数据库对外服务的端口号
4444 : 请求SST SST: 指数据一个镜象传输 xtrabackup , rsync ,mysqldump
4567 : 组成员之间进行沟通的一个端口号
4568 : 传输IST用的。相对于SST来说的一个增量。

安装

本指引区别于官方文档的rpm部署方式,本文档采用是二进制的规范部署方式。

使用yum/rpm安装是最简单的,但其有如下缺点:

  1. 因为其自动解决了软件依赖问题,不方便新手学习和熟悉PXC架构的组件。
  2. 有些客户的内网环境yum源是内部的,不太方便采用yum安装
  3. yum安装后的文件目录放得太乱,不适合生产环境的规范部署。

安装依赖

yum install -y libaio

各节点PXC软件的下载和安装

e9dd70eed140479c0f30abfaf045e44.png

请记住,PXC软件包其实是带Galera组件的percona server集合,请勿再重复下载percona server,更不要下载其他mysql版本,因为只有percona server可以搭建PXC集群!

#下载ssl102还是ssl102,取决于你openssl的版本
[root@pxc1 /]# openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017

wget https://www.percona.com/downloads/Percona-XtraDB-Cluster-LATEST/Percona-XtraDB-Cluster-5.7.26-31.37/binary/tarball/Percona-XtraDB-Cluster-5.7.26-rel29-31.37.1.Linux.x86_64.ssl102.tar.gz

#解压安装
tar -zxvf Percona-XtraDB-Cluster-5.7.26-rel29-31.37.1.Linux.x86_64.ssl102.tar.gz -C /opt
ln -s /opt/Percona-XtraDB-Cluster-5.7.26-rel29-31.37.1.Linux.x86_64.ssl102/ /usr/local/mysql

#添加mysql组和mysql用户
groupadd mysql 
useradd -M -g mysql -s /sbin/nologin -d /usr/local/mysql mysql

#创建MySQL数据目录
mkdir -p /database/mysql/data/3306
chown mysql:mysql /database/mysql/data/3306 -R

#设置环境变量
echo  'export PATH=/usr/local/mysql/bin/:$PATH' >>/etc/profile

source /etc/profile

创建配置文件

vi /etc/my.cnf

要注意pxc的my.cnf有一些配置是必须的,三台server的my.cnf配置分别如下(只包含最小满足pxc需求的配置)

三台机器配置的内容分别如下:

###  pxc1 | 192.168.1.101
###  右边#号的是percona server默认值
[mysqld]

####: mysqld基本设置
user                                =mysql                          #   mysql
basedir                             =/usr/local/mysql/              #   /usr/local/mysql/
datadir                             =/database/mysql/data/3306      #   /usr/local/mysql/data
character_set_server                =utf8                           #   latin1
log_timestamps                      =system                         #   utc
skip_name_resolve                   =1                              #   0
lower_case_table_names              =1                              #   0

####: pxc必须满足的
server-id                           =101                            #   0    #注意三台服务器的设置不同
binlog_format                       =row                            #   row
default_storage_engine              =InnoDB                         #   InnoDB
innodb_autoinc_lock_mode            =2                              #   1

#### pxc配置
wsrep_node_name=pxc1  #注意三台服务器的设置不同。可以不配置,不配置时默认取hostname
wsrep_node_address=192.168.1.101:4567  #注意三台服务器的设置不同。可以不加端口,默认就是4567的pxc通讯端口,请注意不是mysql的3306监听端口!
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so  
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://192.168.1.101:4567,192.168.1.102:4567,192.168.1.103:4567
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
###  pxc2 | 192.168.1.102
###  右边#号的是percona server默认值
[mysqld]

####: mysqld基本设置
user                                =mysql                          #   mysql
basedir                             =/usr/local/mysql/              #   /usr/local/mysql/
datadir                             =/database/mysql/data/3306      #   /usr/local/mysql/data
character_set_server                =utf8                           #   latin1
log_timestamps                      =system                         #   utc
skip_name_resolve                   =1                              #   0
lower_case_table_names              =1                              #   0

####: pxc必须满足的
server-id                           =102                            #   0    #注意三台服务器的设置不同
binlog_format                       =row                            #   row
default_storage_engine              =InnoDB                         #   InnoDB
innodb_autoinc_lock_mode            =2                              #   1

#### pxc配置
wsrep_node_name=pxc2  #注意三台服务器的设置不同。可以不配置,不配置时默认取hostname
wsrep_node_address=192.168.1.102:4567  #注意三台服务器的设置不同。可以不加端口,默认就是4567的pxc通讯端口,请注意不是mysql的3306监听端口!
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so  
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://192.168.1.101:4567,192.168.1.102:4567,192.168.1.103:4567
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
###  pxc3 | 192.168.1.103
###  右边#号的是percona server默认值
[mysqld]

####: mysqld基本设置
user                                =mysql                          #   mysql
basedir                             =/usr/local/mysql/              #   /usr/local/mysql/
datadir                             =/database/mysql/data/3306      #   /usr/local/mysql/data
character_set_server                =utf8                           #   latin1
log_timestamps                      =system                         #   utc
skip_name_resolve                   =1                              #   0
lower_case_table_names              =1                              #   0

####: pxc必须满足的
server-id                           =103                            #   0    #注意三台服务器的设置不同
binlog_format                       =row                            #   row
default_storage_engine              =InnoDB                         #   InnoDB
innodb_autoinc_lock_mode            =2                              #   1

#### pxc配置
wsrep_node_name=pxc3  #注意三台服务器的设置不同。可以不配置,不配置时默认取hostname
wsrep_node_address=192.168.1.103:4567  #注意三台服务器的设置不同。可以不加端口,默认就是4567的pxc通讯端口,请注意不是mysql的3306监听端口!
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so  
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://192.168.1.101:4567,192.168.1.102:4567,192.168.1.103:4567
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING

安装xtrabackup

因为底层的底层全量补数据,依靠的是wsrep_sst_xtrabackup-v2脚本,调用的是xtrabackup那一套备份恢复工具,所以我们必须提前安装xtrabackup了。

# 请到percona官网下载对应操作系统版本的rpm包
# 我这里下载的是centos7版本
# wget https://www.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.14/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.14-1.el7.x86_64.rpm

# qpress需要百度第三方下载, centos6、centos7通用,直接拷贝可以用

# 实际上测试发现,解压直接拷贝以下五个文件也可以用,不需要rpm安装

cp xtrabackup xbstream qpress wsrep_sst_xtrabackup-v2 socat /usr/sbin
chmod +x /usr/sbin/xtrabackup
chmod +x /usr/sbin/xbstream
chmod +x /usr/sbin/qpress
chmod +x /usr/sbin/wsrep_sst_xtrabackup-v2
chmod +x /usr/sbin/socat

快捷通道: https://pan.baidu.com/s/179mV0QidiiMqdROGUFBZXQ 提取码: vcvg

各个节点无密码初始化

mysqld --defaults-file=/etc/my.cnf --initialize-insecure 

引导第一个节点

###  pxc1 | 192.168.1.101
#启动
mysqld_safe --defaults-file=/etc/my.cnf --wsrep-new-cluster  &

#改密码
mysql  #无密码登录

mysql> set password='fander';
Query OK, 0 rows affected (0.00 sec)

###创建SST用户  #SST是什么,文章最后会讲
#这个其实是使用xtrabackup的权限。
mysql> CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 'passw0rd';
mysql> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO
  'sstuser'@'localhost';
mysql> FLUSH PRIVILEGES;
# 账号、密码,要和配置文件的wsrep_sst_auth=sstuser:passw0rd 对应

引导第二、三个节点

#第二、三个节点以正常方式拉起就可以了。
mysqld_safe --defaults-file=/etc/my.cnf  &

检查测试

#主要看下面的参数
mysql> show status like 'wsrep%';
+----------------------------+--------------------------------------+
| Variable_name              | Value                                |
+----------------------------+--------------------------------------+
| wsrep_local_state_uuid     | c2883338-834d-11e2-0800-03c9c68e41ec |
| ...                        | ...                                  |
| wsrep_local_state          | 4                                    |
| wsrep_local_state_comment  | Synced                               |
| ...                        | ...                                  |
| wsrep_cluster_size         | 1                                    |
| wsrep_cluster_status       | Primary  #为Primary即正常拉起         |
| wsrep_connected            | ON                                   |
| ...                        | ...                                  |
| wsrep_ready                | ON                                   |
+----------------------------+--------------------------------------+
40 rows in set (0.01 sec)

# 如果三台机器以下两个状态值均如下,则集群正常
mysql> show status like 'wsrep_local_state_comment';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| wsrep_local_state_comment | Synced |
+---------------------------+--------+
1 row in set (0.00 sec)

mysql> show status like 'wsrep_cluster_status';
+----------------------+---------+
| Variable_name        | Value   |
+----------------------+---------+
| wsrep_cluster_status | Primary |
+----------------------+---------+
1 row in set (0.00 sec)

测试多点写入,是否能复制成功。

###  pxc1 | 192.168.1.101
mysql> create database fander1;
Query OK, 1 row affected (0.00 sec)
###  pxc2 | 192.168.1.102
mysql> create database fander2;
Query OK, 1 row affected (0.00 sec)
###  pxc3 | 192.168.1.103
mysql> create database fander3;
Query OK, 1 row affected (0.00 sec)

三台机器查看数据是否一致

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| fander1            |
| fander2            |
| fander3            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
7 rows in set (0.02 sec)

补充

PXC传输数据有两种方式

IST: Incremental State Transfer 增量同步
SST:State Snapshot Transfer 全量同步 

SST 全量同步底层用的同步方法取决于参数wsrep_sst_method的设置,xtrabackup-v2是最好的方法,其他可选值包括rsync、mysqldump等,rsync速度最快但会阻塞读写,mysqldump非常慢根本不建议用。 虽然xtrabackup很好,但数据量大的情况下,对donor的性能影响巨大,同步时间也不可接受,所以应该尽可能避免SST

什么情况下用SST?

答案是,优先使用IST,无法使用IST时,则SST。
IST 发生的条件:This is done using caching mechanism on nodes (即只发生在之前集群里的节点数据还有在缓存中)

所以

  1. 为了避免SST,建议一:
    调大数据缓存的空间,默认值是128M,建议按情况调大,个人建议可以调为2GB
vi /etc/my.cnf
wsrep_provider_options='gcache.size=2G'

down机时间过久,导致缓存没法缓存所有增量数据时,会走SST,有办法避免吗?

  1. 为了避免SST,建议二:
    我们可以让脱离集群的节点通过建立与主节点建立主从复制,等复制完成后关机,并伪造一个grastate.dat,来记录备份数据的seqno,这样当新节点启动时就会自动用IST的方法来进行,而不是SST(注意gcache.size应该有足够的容量来保证在备份及恢复这段时间内新产生的数据都被缓存到)

PXC使用的限制

  • 复制仅适用于InnoDB存储引擎。其他存储引擎的表的写入都不复制(包括mysql.表)。但是,DDL语句会在statement级别进行复制,对mysql.表的更改将以这种方式进行复制。因此您使用CREATE USER...命令,而不应该使用INSERT INTO mysql.user...
    当然您也可以使用wsrep_replicate_myisam变量启用实验性的MyISAM复制支持。

  • 不支持的查询:

    • 在多主设置中,不支持LOCK TABLESUNLOCK TABLES
    • 同样的,Lock functions如GET_LOCK(),RELEASE_LOCK()也不支持

general.log、slow.log不支持输出到TABLE,如果启用general.log、slow.log,则必须将日志输出到文件:

log_output  =  FILE

有坑,官档写着不支持,实际上可以设置输出到table,只是会有严重的锁冲突,导致性能问题,严重时导致mysqld崩溃。

  • 允许的最大事务大小由wsrep_max_ws_rows和wsrep_max_ws_size变量定义。LOAD DATA INFILE处理将(按参数设置)每10000行提交一次。因此大事务LOAD DATA时将被拆分为一系列小事务。

  • 由于集群级的乐观并发控制,事务在COMMIT阶段可能仍会中止。可以有两个事务写入相同的行并在单独的Percona XtraDB Cluster节点中提交,并且只有其中一个可以成功提交。失败的将被中止。对于集群级中止,Percona XtraDB Cluster提供了死锁错误代码:

(Error: 1213 SQLSTATE: 40001  (ER_LOCK_DEADLOCK)).
  • 由于可能在提交时回滚,因此不支持XA事务。

  • 整个集群的写吞吐量受最弱节点的限制。如果一个节点变慢,则整个群集速度变慢。如果您对稳定的高性能有要求,则应该由相应的硬件支持。

  • 群集的最小建议大小是3个节点。第三个节点会是仲裁者。

  • 不支持InnoDB虚假更改功能。

  • enforce_storage_engine=InnoDB与wsrep_replicate_myisam=OFF(默认)不兼容 。

  • 在群集模式下运行Percona XtraDB群集时,请避免ALTER TABLE ... IMPORT/EXPORT操作。如果未在所有节点上同步执行,则可能导致节点数据不一致。

  • 所有表必须具有主键。这可确保相同的行在不同节点上以相同的顺序出现。DELETE没有主键的表的语句不被支持。

posted on 2019-09-20 10:15  fanderchan  阅读(2333)  评论(0编辑  收藏  举报

导航