PXC(Percona XtraDB Cluster)是什么?

PXC(Percona XtraDB Cluster)是一个开源的MySQL高可用解决方案。他将Percona Server和XtraBackup与Galera库集成,以实现同步多主复制。基于Galera的高可用方案主要有MariaDB Galera Cluster和Percona XtraDB Cluster,目前PXC架构在生产线上用的更多而且更成熟一些。PXC相比那些传统的基于主从模式的集群架构MHA和双主,Galera Cluster 最突出的特点就是解决了诟病已久的复制延迟问题,基本上可以达到实时同步。而且节点与节点之间,它们互相的关系是对等的。本身Galera Cluster也是一种多主架构。PXC是在存储引擎层实现的同步复制,而非异步复制,所以其数据的一致性是相当高的。


集群IP示例

master

192.168.1.1

slave

192.168.1.2

arbiter

192.168.1.3


PXC优缺点

  • 优点:

    • 实现了MySQL集群的高可用性和数据的强一致性;

    • 完成了真正的多节点读写的集群方案;

    • 改善了主从复制延迟问题,基本上达到了实时同步;

    • 新加入的节点可以自动部署,无需提交手动备份,维护方便;

    • 由于是多节点写入,所以DB故障切换很容易。

  • 缺点:

    • 加入新节点时开销大。添加新节点时,必须从现有节点之一复制完整数据集。如果是100GB,则复制100GB。

    • 任何更新的事务都需要全局验证通过,才会在其他节点上执行,集群性能受限于性能最差的节点,也就说常说的木桶定律。

    • 因为需要保证数据的一致性,PXC采用的实时基于存储引擎层来实现同步复制,所以在多节点并发写入时,锁冲突问题比较严重。

    • 存在写扩大的问题。所以节点上都会发生写操作,对于写负载过大的场景,不推荐使用PXC。

    • 只支持InnoDB存储引擎。


部署前置服务*Docker


创建Mysql-Pxc数据盘

  • 部署所在服务器:master slave arbiter

docker volume create mysql-data 
docker volume create mysql-conf 
docker volume create mysql-back 

导入镜像

  • 部署所在服务器:master slave arbiter

docker  load < pxc.tar

启动初始化主服务等待加入集群

  • 部署所在服务器:master

docker run -itd --privileged=true --restart=always --name mysql-pxc -v mysql-data:/var/lib/mysql -v mysql-conf:/etc/mysql -v mysql-back:/data -e MYSQL_ROOT_PASSWORD=mysqlpassword -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=mysqlpassword --net=host pxc:latest

启动从节点

  • 部署所在服务器:slave

# 获取主机名
hostname=$(cat /etc/hostname)

# 写入配置文件
cat << EOF > /var/lib/docker/volumes/mysql-conf/_data/node.cnf
[mysqld]
pxc_strict_mode=PERMISSIVE
ignore-db-dir=lost+found
datadir=/var/lib/mysql
socket=/tmp/mysql.sock
skip-host-cache

group_concat_max_len = 10240000
max_connections=65535
max_allowed_packet=500M
wait_timeout=2880000
interactive_timeout=2880000
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
thread_cache_size=64


#coredumper
#server_id=0
binlog_format=ROW
default_storage_engine=InnoDB

innodb_flush_log_at_trx_commit  = 0
innodb_flush_method             = O_DIRECT
innodb_file_per_table           = 1
innodb_autoinc_lock_mode=2

bind_address = 0.0.0.0

wsrep_slave_threads=2
wsrep_cluster_address=gcomm://192.168.1.1,192.168.1.2,192.168.1.3   #修改集群IP地址
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so

wsrep_cluster_name=PXC
wsrep_node_address=192.168.1.2   #加入集群的IP地址
wsrep_node_incoming_address=$hostname:3306 

wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth='xtrabackup:mysqlpassword'

[client]
socket=/tmp/mysql.sock

[sst]
progress=/var/lib/mysql/sst_in_progress

EOF

# 赋权
mkdir -p /var/lib/docker/volumes/mysql-conf/_data/conf.d
chown 1001:docker /var/lib/docker/volumes/mysql-conf/_data/conf.d
chown 1001:docker /var/lib/docker/volumes/mysql-conf/_data/node.cnf
chmod 644 /var/lib/docker/volumes/mysql-conf/_data/node.cnf

# 启动容器
docker run -itd --privileged=true --restart=always --name mysql-pxc \
    -v mysql-data:/var/lib/mysql \
    -v mysql-conf:/etc/mysql \
    -v mysql-back:/data \
    -e MYSQL_ROOT_PASSWORD=mysqlpassword \
    -e CLUSTER_NAME=PXC \
    -e CLUSTER_JOIN=192.168.1.1,192.168.1.2,192.168.1.3 \
    -e XTRABACKUP_PASSWORD=mysqlpassword \
    --net=host \
    pxc:latest

启动仲裁节点

  • 部署所在服务器:arbiter

#!/bin/bash

# 获取主机名
hostname=$(cat /etc/hostname)

# 写入配置文件
cat << EOF > /var/lib/docker/volumes/mysql-conf/_data/node.cnf
[mysqld]
pxc_strict_mode=PERMISSIVE
ignore-db-dir=lost+found
datadir=/var/lib/mysql
socket=/tmp/mysql.sock
skip-host-cache

group_concat_max_len = 10240000
max_connections=65535
max_allowed_packet=500M
wait_timeout=2880000
interactive_timeout=2880000
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
thread_cache_size=64

#coredumper
#server_id=0
binlog_format=ROW
default_storage_engine=InnoDB

innodb_flush_log_at_trx_commit  = 0
innodb_flush_method             = O_DIRECT
innodb_file_per_table           = 1
innodb_autoinc_lock_mode=2

bind_address = 0.0.0.0

wsrep_slave_threads=2
wsrep_cluster_address=gcomm://192.168.1.1,192.168.1.2,192.168.1.3   #修改集群IP地址
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so

wsrep_cluster_name=PXC
wsrep_node_address=192.168.1.3   #加入集群的IP地址
wsrep_node_incoming_address=$hostname:3306

wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth='xtrabackup:mysqlpassword'

[client]
socket=/tmp/mysql.sock

[sst]
progress=/var/lib/mysql/sst_in_progress

EOF

# 赋权
mkdir -p /var/lib/docker/volumes/mysql-conf/_data/conf.d
chown 1001:docker /var/lib/docker/volumes/mysql-conf/_data/conf.d
chown 1001:docker /var/lib/docker/volumes/mysql-conf/_data/node.cnf
chmod 644 /var/lib/docker/volumes/mysql-conf/_data/node.cnf

# 启动容器
docker run -itd --privileged=true --restart=always --name mysql-pxc \
    -v /etc/hosts:/etc/hosts \
    -v mysql-data:/var/lib/mysql \
    -v mysql-conf:/etc/mysql \
    -v mysql-back:/data \
    -e MYSQL_ROOT_PASSWORD=mysqlpassword \
    -e CLUSTER_NAME=PXC \
    -e CLUSTER_JOIN=192.168.1.1,192.168.1.2,192.168.1.3 \
    -e XTRABACKUP_PASSWORD=mysqlpassword \
    --net=host \
    pxc:latest

主节点重新加入集群

  • 部署所在服务器:master

#!/bin/bash

# 停止初始的容器
docker rm -f mysql-pxc

# 获取主机名
hostname=$(cat /etc/hostname)

# 写入配置文件
cat << EOF > /var/lib/docker/volumes/mysql-conf/_data/node.cnf
[mysqld]
pxc_strict_mode=PERMISSIVE
ignore-db-dir=lost+found
datadir=/var/lib/mysql
socket=/tmp/mysql.sock
skip-host-cache

group_concat_max_len = 10240000
max_connections=65535
max_allowed_packet=500M
wait_timeout=2880000
interactive_timeout=2880000
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
thread_cache_size=64


#coredumper
#server_id=0
binlog_format=ROW
default_storage_engine=InnoDB

innodb_flush_log_at_trx_commit  = 0
innodb_flush_method             = O_DIRECT
innodb_file_per_table           = 1
innodb_autoinc_lock_mode=2

bind_address = 0.0.0.0

wsrep_slave_threads=2
wsrep_cluster_address=gcomm://192.168.1.1,192.168.1.2,192.168.1.3  #修改集群IP地址
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so

wsrep_cluster_name=PXC 
wsrep_node_address=192.168.1.1     #加入集群的IP地址
wsrep_node_incoming_address=$hostname:3306

wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth='xtrabackup:mysqlpassword'

[client]
socket=/tmp/mysql.sock

[sst]
progress=/var/lib/mysql/sst_in_progress

EOF

# 赋权
mkdir -p /var/lib/docker/volumes/mysql-conf/_data/conf.d
chown 1001:docker /var/lib/docker/volumes/mysql-conf/_data/conf.d
chown 1001:docker /var/lib/docker/volumes/mysql-conf/_data/node.cnf
chmod 644 /var/lib/docker/volumes/mysql-conf/_data/node.cnf

# 启动容器
docker run -itd --privileged=true --restart=always --name mysql-pxc \
    -v mysql-data:/var/lib/mysql \
    -v mysql-conf:/etc/mysql \
    -v mysql-back:/data \
    -e MYSQL_ROOT_PASSWORD=mysqlpassword \
    -e CLUSTER_NAME=PXC \
    -e CLUSTER_JOIN=192.168.1.1,192.168.1.2,192.168.1.3 \
    -e XTRABACKUP_PASSWORD=mysqlpassword \
    --net=host \
    pxc:latest

查看进群数量

docker exec -it mysql-pxc mysql -u root -p'mysqlpassword' -e "SHOW VARIABLES LIKE 'wsrep_cluster_size';"