1. PXC简介

Percona XtraDB Cluster(下文简称PXC)是一个开源的MySQL高可用的解决方案,它集成了Percona服务器和Percona XtraBackup和Galera库共同运用的同步多主复制,也就是说PXC是基于Galere协议的高可用方案,Galera是Codership提供的多主数据同步复制机制,可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据一致性。基于Galera的高可用方案主要有MariaDB Galera Cluster和Percona XtraDB Cluster,目前PXC用的会比较多一些,

  • PXC是由节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上;
  • 每个节点都是普通的MySQL/Percona服务器,可以将现有的数据库服务器组成集群,反之,也可以将集群拆分成单独的服务器;
  • 每个节点都包含完整的数据副本;
  • MariaDB的集群原理跟PXC一样,maridb-cluster其实就是PXC,两者原理是一样的。

2. PXC特性

  1. 同步复制,事务要么在节点中都提交要么不提交;
  2. 多主复制,可以在任意节点进行Write-Read操作;
  3. 在从服务器上并行应用事件,真正意义上的并行复制;
  4. 节点自动配置,数据一致性,不再是异步复制;
  5. PXC最大的优势:强一致性、无同步延迟

3. PXC优缺点

  • 优点:
    1. 服务高可用;
    2. 数据同步复制(并发复制),几乎无延迟;
    3. 多个节点支持同时读写,可实现写扩展,不过最好事先进行分库分表,让各个节点分别写不同的库或者表,避免让galera解决数据冲突;
    4. 新节点可以自动部署,部署操作简单;
    5. 数据严格一致性,尤其适合电商类应用(订单,金额等敏感数据);
    6. 完全兼容MySQL。
  • 缺点:
    1. 只支持InnoDB引擎;低版本(5.6.20)的复制只支持InnoDB引擎,其他存储引擎的更改不复制。然而,DDL(Data Definition Language) 语句在statement级别被复制,并且,对mysql.*表的更改会基于此被复制。例如CREATE USER…语句会被复制,但是 INSERT INTO mysql.user…语句则不会;
    2. PXC集群一致性控制机制,事有可能被终止,原因如下:集群允许在两个节点上同时执行操作同一行的两个事务,但是只有一个能执行成功,另一个会被终止,集群会给被终止的。客户端返回死锁错误(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK));
    3. 写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功;
    4. 所有表都需要有主键;
    5. 集群吞吐量/性能取决于短板;
    6. 新加入节点采用SST时代价高;
    7. 锁冲突、死锁问题相对更多。

4. PXC常识

  • 端口号

    3306:数据库对外服务的端口号;

    4444:请求SST SST: 指数据一个镜像传输 xtrabackup , rsync ,mysqldump;

    4567: 组成员之间进行沟通的一个端口号;

    4568: 传输IST用的。相对于SST来说的一个增量。

  • 名词介绍

    WS:write set 写数据集

    IST: Incremental State Transfer 增量同步

    SST:State Snapshot Transfer 全量同步

  • 状态机变化阶段

    OPEN: 节点启动成功,尝试连接到集群,如果失败则根据配置退出或创建新的集群;

    PRIMARY: 节点处于集群PC中,尝试从集群中选取donor进行数据同步;

    JOINER: 节点处于等待接收/接收数据文件状态,数据传输完成后在本地加载数据;

    JOINED: 节点完成数据同步工作,尝试保持和集群进度一致;

    SYNCED:节点正常提供服务:数据的读写,集群数据的同步,新加入节点的sst请求;

    DONOR(贡献数据者):节点处于为新节点准备或传输集群全量数据状态,对客户端不可用。

  • 状态机变化因素

    新节点加入集群;

    节点故障恢复;

    节点同步失败。

  • 传输SST的方法

    mysqldump、xtrabackup、rsync

  • 配置文件各项配置意义
    wsrep_provider:指定Galera库的路径

    wsrep_cluster_name:Galera集群的名称

    wsrep_cluster_address:Galera集群中各节点地址。地址使用组通信协议gcomm://(group communication)

    wsrep_node_name:本节点在Galera集群中的名称

    wsrep_node_address:本节点在Galera集群中的通信地址

    wsrep_sst_method:state_snapshot_transfer(SST)使用的传输方法,可用方法有mysqldump、rsync和xtrabackup,前两者在传输时都需要对Donor加全局只读锁(FLUSH TABLES WITH READ LOCK),xtrabackup则不需要(它使用percona自己提供的backup lock)。强烈建议采用xtrabackup

    wsrep_sst_auth:在SST传输时需要用到的认证凭据,格式为:”用户:密码”

    pxc_strict_mode:是否限制PXC启用正在试用阶段的功能,ENFORCING是默认值,表示不启用

    binlog_format:二进制日志的格式。Galera只支持row格式的二进制日志

    default_storage_engine:指定默认存储引擎。Galera的复制功能只支持InnoDB

    innodb_autoinc_lock_mode:只能设置为2,设置为0或1时会无法正确处理死锁问题

5. PXC集群搭建

5.1 环境描述

本文档所涉及IP均为虚假IP。

Name IP
master 192.168.5.139
test1 192.168.5.138
test2 192.168.5.137

三个节点上的iptables与firewalld需先关闭,否则应开放3306、4444、4567、4568端口的访问,同时应关闭selinux。

5.2 安装PXC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 三台主机都需执行,安装Persona仓库
$ yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
# 执行命令修改SELINUX项
$ vi /etc/selinux/config
SELINUX=disabled # 修改该项为disabled
# Seliux安全模块可能会对Percona XtraDB集群的数据进行限制访问,最好的方法是更改模式为许可
$ setenforce 0
# 安装PXC
$ yum -y --nogpgcheck install Percona-XtraDB-Cluster-57
# 开放相应端口(如无开启防火墙可忽略)
$ firewall-cmd --zone=public --add-port=3306/tcp --permanent
$ firewall-cmd --zone=public --add-port=4444/tcp --permanent
$ firewall-cmd --zone=public --add-port=4567/tcp --permanent
$ firewall-cmd --zone=public --add-port=4568/tcp --permanent
$ firewall-cmd --reload
# 开启PXC服务
$ systemctl start mysqld.service

5.3 接入MySQL

1
2
3
4
5
6
7
8
9
10
11
12
# 查询MySQL临时生成密码
$ cat /var/log/mysqld.log | grep password
2019-06-28T10:02:12.733076Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: rldW%6_5J3h<
# 进入MySQL登录
$ mysql -u root -p
# 使用上述的临时密码进行登录
Enter password: rldW%6_5J3h<
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.26-29-57-log Percona XtraDB Cluster (GPL), Release rel29, Revision 03540a3, WSREP version 31.37, wsrep_31.37
# 通过命令修改登录密码
mysql> alter user 'root'@'localhost' identified with mysql_native_password by '所要修改的密码需包含大小写字母、数字及特殊符号';

默认密码检查策略要求必须包含:大小写字母、数字和特殊符号,并且长度不能少于8位,否则会提示ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

5.4 远程访问授权

1
2
3
4
5
6
7
8
9
# 创建远程访问用户
mysql> create user 'root'@'%' identified with mysql_native_password by '远程访问密码';
Query OK, 0 rows affected (0.01 sec)
# 允许访问权限
mysql> grant all privileges on *.* to 'root'@'%' with grant option;
Query OK, 0 rows affected (0.01 sec)
# 刷新权限列表
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

5.5 PXC配置

下述配置根据节点不同进行配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 停止MySQL服务
$ systemctl stop mysqld
# 修改配置文件 配置节点
$ vi /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
# 集群中节点的IP地址(本机填最后)
wsrep_cluster_address=gcomm://ip地址,IP地址,本机IP地址(用,号隔开)
# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW
# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB
# Slave thread to use
wsrep_slave_threads= 8
wsrep_log_conflicts
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2
# Node IP address
# 当前节点IP
wsrep_node_address=IP地址
# Cluster name
# 集群名称
wsrep_cluster_name=pxc-cluster
#If wsrep_node_name is not specified, then system hostname will be used
# 当前节点名称
wsrep_node_name=pxc-cluster-node-1
#pxc_strict_mode allowed values: DISABLED,PERMISSIVE,ENFORCING,MASTER
# 不使用实验功能
pxc_strict_mode=ENFORCING
# SST method
#状态快照传输(sst)方法,官方建议
wsrep_sst_method=xtrabackup-v2
#Authentication for SST method
# 用户凭证——用于同步(mysql的用户名和密码)
wsrep_sst_auth="用户名:密码"

6. PXC初始化主节点

1
2
3
4
5
6
7
8
9
10
11
12
# 其中一个节点使用以下命令启动
$ systemctl start mysql@bootstrap.service
# 登入MySQL
$ mysql -u root -p
# 开启wsrep_causal_reads
mysql> set wsrep_causal_reads =1;
# 创建配置文件中对应的用户(此步骤所有节点的IP都需要创建)
mysql> create user '对应配置文件的用户名'@'%' identified with mysql_native_password by '对应配置文件的密码';
# 给予权限
mysql> grant all privileges on *.* to '用户名'@'%' with grant option;
# 刷新权限表
mysql> flush privileges;

7. 启动其他节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 其他节点采用以下命令进行启动
$ systemctl start mysqld
# 同时根据上述 6 步骤进行配置
# 开启wsrep_causal_reads
mysql> set wsrep_causal_reads =1;
# 创建配置文件中对应的用户(此步骤所有节点的IP都需要创建)
mysql> create user '对应配置文件的用户名'@'%' identified with mysql_native_password by '对应配置文件的密码';
# 给予权限
mysql> grant all privileges on *.* to '用户名'@'%' with grant option;
# 刷新权限表
mysql> flush privileges;
# 验证集群
mysql> show status like 'wsrep%';
+----------------------------------+---------------------------------------+
| Variable_name | Value |
+----------------------------------+---------------------------------------+
| wsrep_local_state_uuid | 8cae2eb0-9ccb-11e9-afcb-5ea6cd71dc63 |
| wsrep_protocol_version | 9 |
...
| wsrep_incoming_addresses | 192.168.5.137:3306,192.168.5.138,192.168.5.139:3306 |
| wsrep_cluster_weight | 3 |
| 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 | 380130ce-9ccd-11e9-9386-6a21f3d1896f |
| wsrep_cluster_conf_id | 6 |
| wsrep_cluster_size | 3 |
| wsrep_cluster_state_uuid | 8cae2eb0-9ccb-11e9-afcb-5ea6cd71dc63 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| wsrep_local_bf_aborts | 0 |
...
| wsrep_ready | ON |
+----------------------------------+---------------------------------------+
71 rows in set (0.05 sec)

至此PXC集群搭建完成,可通过建库验证节点是否同步。


服务的启动和停止要对应

1
$ systemctl stop mysqld   ------>  启动时用systemctl start mysqld

或者

1
$ systemctl stop mysql@bootstrap.service   ----->  启用是用 systemctl start mysql@bootstrap.service

如果忘记root密码,则按以下操作恢复:

在[mysqld]的段中加上一句:skip-grant-tables 保存并且退出vi。

1
2
3
$ mysql  -u root 
$ update mysql.user set authentication_string=password('123qwe') where user='root' and Host = 'localhost';
$ flush privileges