一、pxc简介
pxc是percona公司的percona xtraDB cluster.简称PXC。它是基于GaLera协议的高可用集群方案。可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据强一致性。pxc提供了MySQL高可用的一种实现方法,pxc集群是由节点组成的,推荐配置至少3个节点
-
优点总结
- 服务高可用
- 数据同步复制(并发复制),几乎无延迟
- 多个可同时读写节点,可实现写扩展
- 新节点可以自动部署,部署操作简单
- 数据严格一致性
- 完全兼容MySQL
-
缺点总结
- 只支持InnoDB引擎
- pxc集群一致性控制机制,是有可能被终止,原因如下:
集群允许在两个节点上同时执行操作同一行的两个事务,但是只有一个能执行成功,另一个会被终止,集群会给被终止的客户端返回死锁错误(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK))
- 所有表都要有主键
- 新加入的节点采用SST时代价高
二、原理描述
PXC是基于引擎层的同步复制,而不是异步复制,所以数据一致性更高。同时,基于引擎层,没有sql thread应用过程,所以没有延迟;PXC所有节点全都关掉后,不管怎么启动都有可能做SST的传输。原因是增量数据需要在内存里面记录,如果全部关闭,数据就是失效了,节点之间不知道同步到什么位置了
- pxc会使用四个端口号
- 3306:数据库对外服务端口号
- 4444:请求SST
- 4567:组成员之间进行沟通的一个端口号
- 4568:传输IST用的
- 名词说明
- WS:写数据集
- IST:增量同步
- SST:全量同步
三、pxc集群的启动和关闭
-
状态机变化阶段
- 1)OPEN:节点启动成功,尝试连接到集群,如果失败则根据配置退出或创建新的集群
- 2)PRIMARY:节点处于集群PC中,尝试从集群中选取donor进行数据同步
- 3)JOINER:节点处于等待接收/接收数据文件状态,数据传输完成后在本地加载数据
- 4)JOINED:节点完成数据同步工作,尝试保持和集群进度一致
- 5)SYNCED:节点正常提供服务:数据的读写,集群数据的同步,新加入节点的sst请求
- 6)DONOR(贡献数据者):节点处于为新节点准备或传输集群全量数据状态,对客户端不可用
-
状态机变化因素
- 新节点加入集群
- 节点故障恢复
- 节点同步失效
-
传输SST的几种方法
- mysqldump
- xtrbackup
- rsync
四、pxc节点挂掉处理方案
因为突然掉电,不确定哪个节点的数据是最新的,查看gvwstate.dat文件找出最新的seqno(cat /var/lib/mysql/gvwstate.dat )
- 当普通节点挂掉
- 重启该节点即可,重启后数据会同步到当前集群的最新数据
- 当根节点挂掉
- 删除这个节点,重新创建容器,以节点的方式挂载到这个节点之前的数据卷位置,看其他存活节点中/var/lib/mysql目录下gvwstate.dat 文件中的view_id对应的新的根节点,然后以这个新的根节点为CLUSTER_JOIN启动,之后数据将会全部进行同步
- 当所有节点都挂掉
- 如果pxc所有节点都挂掉时,建议删除所有节点以及挂载文件中的grastate.dat,然后以某个节点为根节点去启动集群(或者找到最后一个死亡的节点中的grastate.dat文件,修改文件中配置项safe_to_bootstrap为1,以该节点为master节点去启动集群)
五、grastate.dat文件内容详解
- seqno
- 当我们关闭一个节点时,其seqno会写入grastate.dat文件中,这时后续的seqno该节点将无法接收到
- 注意数据库开启状态或者异常关闭时seqno值为-1
- 当我们将所有节点关闭,准备重启时我们需要知道哪个节点是最后关闭的,并使用它来引导集群,这时查看seqno的值即可,最大的即可
- safe_to_bootstrap
- 安全引导即safe to bootstrap ,从3.19版本开始,Galera为防止在错误的节点上引导集群,引入了安全引导的保护
- 如果我们使用safe_to_bootstrao为0的节点来引导,数据库将无法启动
- 我们可以手动编辑该文件将值设置为1来引导,不过这样可能会造成数据丢失
- 如果所有节点同时异常宕机,这时所有节点的值都为0,需要选择一台手动编辑
六、docker搭建pxc-mysql集群
-
目录结构
./pxc ├── pxc-node1 │ ├── data │ └── docker-compose.yml ├── pxc-node2 │ ├── data │ └── docker-compose.yml └── pxc-node3 ├── data └── docker-compose.yml
- pxc-node1/docker-compose.yml
version: "3.5" services: pxc-node1: image: percona/percona-xtradb-cluster:5.7 container_name: pxc-node1 restart: always privileged: true ports: - "33061:3306" environment: - MYSQL_ROOT_PASSWORD=123456 - CLUSTER_NAME=pxc volumes: - $PWD/data:/var/lib/mysql networks: default: external: name: mysql_net
- pxc-node2/docker-compose.yml
version: "3.5" services: pxc-node2: image: percona/percona-xtradb-cluster:5.7 container_name: pxc-node2 restart: always privileged: true ports: - "33062:3306" environment: - MYSQL_ROOT_PASSWORD=oa3uTgs9K2soZljX - CLUSTER_NAME=pxc - CLUSTER_JOIN=pxc-node1 volumes: - $PWD/data:/var/lib/mysql networks: default: external: name: mysql_net
- pxc-node3/docker-compose.yml
version: "3.5" services: pxc-node3: image: percona/percona-xtradb-cluster:5.7 container_name: pxc-node3 restart: always privileged: true ports: - "33063:3306" environment: - MYSQL_ROOT_PASSWORD=oa3uTgs9K2soZljX - CLUSTER_NAME=pxc - CLUSTER_JOIN=pxc-node1 volumes: - $PWD/data:/var/lib/mysql networks: default: external: name: mysql_net
-
启动服务
- 以pxc-node1为根节点,先启动pxc-node1
cd ./pxc/pxc-node1 && docker-compose up
- 然后加入pxc-node2和pxc-node3普通节点
cd ./pxc/pxc-node2 && docker-compose up cd ./pxc/pxc-node3 && docker-compose up
- docker ps查看启动情况
- 以pxc-node1为根节点,先启动pxc-node1
错误解决
1、如果报错/entrypoint.sh: line 336: /var/lib/mysql//version_info: Permission denied,就修改一下data文件夹权限
2、如果第一个启动的是普通节点,或者根节点写了- CLUSTER_JOIN=xxx,会报错
[ERROR] WSREP: gcs/src/gcs.cpp:gcs_open():1527: Failed to open channel 'pxc' at 'gcomm://pxc-master': -131 (State not recoverable)