Percona XtraDB Cluster是一个针对MySQL的开源的高可用数据库集群解决方案。它确保高可用性,防止停机以及数据丢失,并为不断增长的环境提供线性可扩展性。集群包含多个节点,每个节点数据相同。
PXC是基于运行XtraDB存储引擎的Percona server,使用galera library。推荐的数据传输方式是Percona XtraBackup。
PXC集群推荐至少配置3个节点,避免创建具有两个或任意偶数个节点的集群。
可以将现有的MySQL服务器实例转换为PXC的节点。还可以将任何节点从集群中分离出来,并将其用作常规MySQL服务器实例。
PXC集群包含以下特点:
PXC最大的优势:强一致性、无同步延迟。
缺点:这不能用作有效的写扩展解决方案;写入效率取决于节点中最慢的一台
限制:
1、存储引擎:
基于PXC的复制仅适用于InnoDB存储引擎。
对其他存储引擎的表,包括mysql.*表之类的系统表,任何写入都不会被复制。
那创建用户那岂不是无法同步了?关于这个问题。对于基于DDL方式的语句还是被支持的。
DDL语句使用基于语句级别的方式来实现(即不使用row模式)。
对mysql.*表的所有已DDL方式的更改都将以语句级别式进行复制。
如:CREATE USER… DDL被复制(语句级)
INSERT INTO mysql.user… myisam存储引擎,不会被复制,因为非DDL语句
当然也可以配置wsrep_replicate_myisam参数实现(不建议使用)
2、不支持的查询:
LOCK TABLES在多主模式中不支持UNLOCK TABLES以及LOCK TABLES
锁定功能,如GET_LOCK(),RELEASE_LOCK()等也不被支持
3、查询日志不能定向到表:
如果启用查询日志记录,则必须将日志转发到文件
使用general_log和general_log_file选择查询日志记录和日志文件名称
log_output = file # Author : Leshami # Blog : https://blog.csdn.net/leshami
4、最大事务大小:
允许的最大事务大小由wsrep_max_ws_rows和wsrep_max_ws_size变量定义
LOAD DATA INFILE方式处理每10000行提交一次。对于大的事务将被分解众多小型事务
5、集群乐观并发控制:
PXC集群使用乐观并发控制,事务发出COMMIT可能仍会在该阶段中止
可以有两个事务写入相同的行并在单独的Percona XtraDB集群节点中提交,并且只有其中一个可以成功提交。
失败的将被中止。对于集群级中止,Percona XtraDB集群返回死锁错误代码:
(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).
6、不支持XA事务:
7、硬件配置短板限制:
整个群集的写吞吐量受最弱节点的限制。如果一个节点变慢,整个集群变慢。
如果您对稳定的高性能有要求,那么它应该由相应的硬件支持。
8、建议的最小群集大小是3个节点。第三个节点可以是仲裁者。
9、InnoDB虚假更改功能不受支持。
10、enforce_storage_engine=InnoDB与wsrep_replicate_myisam=OFF(默认)不兼容 。
11、所有表必须有主键,不支持不带主键条件的delete。
12、高负载时避免ALTER TABLE … IMPORT / EXPORT
在集群模式下运行Percona XtraDB集群时,请避免ALTER TABLE … IMPORT / EXPORT工作负载。
如果未在所有节点上同步执行,则可能导致节点不一致。
角色 |
主机名 |
IP |
操作系统 |
PXC版本 |
pxc1 |
pc1 |
192.168.1.202 |
CentOS 6 |
5.7.28 |
pxc2 |
pc2 |
192.168.1.203 |
||
pxc3,代理服务器 |
pc3 |
192.168.1.204 |
这里采用yum安装方式。
需要开放4个端口 3306,4444,4567,4568
3306-mysql实例端口
4567-pxc cluster相互通讯的端口
4444-用于SST传送的端口
4568-用于IST传送的端口
#开放这四个端口给192.168.1网段。
iptables --insert INPUT --protocol tcp --match tcp --dport 3306 --source 192.168.1.0/24 --jump ACCEPT
iptables --insert INPUT --protocol tcp --match tcp --dport 4567 --source 192.168.1.0/24 --jump ACCEPT
iptables --insert INPUT --protocol tcp --match tcp --dport 4568 --source 192.168.1.0/24 --jump ACCEPT
iptables --insert INPUT --protocol tcp --match tcp --dport 4444 --source 192.168.1.0/24 --jump ACCEPT
#将配置更新到配置文件
iptables-save > /etc/sysconfig/iptables
#查看SELINUX状态
getenforce
#修改selinux模式
临时修改:
setenforce 0 #设置SELinux 成为permissive模式,值为1表示enforcing模式。
永久修改:
vi /etc/sysconfig/selinux
将SELINUX=enforcing改为SELINUX=disabled
rpm -qa | grep -i mysql | xargs sudo rpm -e --nodeps
yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes socat nc -y
/*
假如安装socat报错:
Requires: socat
解决办法:
wget http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el6/en/x86_64/rpmforge/RPMS/socat-1.7.2.4-1.el6.rf.x86_64.rpm
rpm -ivh socat-1.7.2.4-1.el6.rf.x86_64.rpm
*/
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
若yum install安装报错:
Cannot open: https://repo.percona.com/yum/percona-release-latest.noarch.rpm. Skipping,则可以手动点击该页面进行下载,再上传到服务器上,执行下面命令进行下载:
rpm -ivh percona-release-latest.noarch.rpm
yum install Percona-XtraDB-Cluster-57 -y
/*
假如安装时报错:libev.so.4()(64bit) is needed。
解决办法:
wget ftp://rpmfind.net/linux/atrpms/el6-x86_64/atrpms/stable/libev-4.04-2.el6.x86_64.rpm
rpm -ivh libev-4.04-2.el6.x86_64.rpm
*/
service mysql start
数据库自动安装到了/var/lib/mysql下。
#查看并记录给临时生成的密码
grep 'temporary password' /var/log/mysqld.log
#修改root密码
mysqladmin -u root -p password #会提示让输入新密码
service mysql stop
vi /etc/my.cnf
添加:
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://192.168.1.202,192.168.1.203,192.168.1.204
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth= "sstuser:自定义一个密码"
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
wsrep_node_name=pxc1
wsrep_node_address=192.168.1.202
--注意:在节点2和节点3上需要相应地修改wsrep_node_name及wsrep_node_address的值。
--我原本是按官方文档里修改的/etc/percona-xtradb-cluster.conf.d/wsrep.cnf,但是发现不行,修改/etc/my.cnf可以。
2.2.9.1 引导第一个节点
/etc/init.d/mysql bootstrap-pxc
注意:在RHEL或CentOS 7上执行systemctl start [email protected]
使用上面的命令启动节点时,它将使用wsrep_cluster_address=gcomm://来进行引导。这告诉节点使用wsrep_cluster_conf_id设置为1。将其他节点添加到集群后,可以重新启动节点正常,将再次使用标准配置。
#创建SST专用用户(密码需要和2.2.8处wsrep_sst_auth里定义的密码一样)
CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 'passw0rd';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO
'sstuser'@'localhost';
#创建代理用户,供ProxySQL使用
CREATE USER 'proxysql_user'@'192.168.1.204' IDENTIFIED BY 'passw0rd';
GRANT insert,delete,update,select ON *.* TO 'proxysql_user '@'192.168.1.204';
#创建远程root用户
grant all privileges on *.* to 'root'@'%' identified by '密码';
#验证
如果wsep_cluster_status为Disconnected,wsrep_connected为OFF,则不正常,说明配置得有问题。
2.2.9.2 添加其他节点到集群
service mysql start
在第二个,第三个节点上可以看到之前在第一个节点上创建的sstuser用户也自动同步过来了:
mysql> select host,user from mysql.user;
+-----------+---------------+
| host | user |
+-----------+---------------+
| localhost | mysql.session |
| localhost | mysql.sys |
| localhost | root |
| localhost | sstuser |
+-----------+---------------+
4 rows in set (0.00 sec)
此时,在任意节点上查看集群状态,都能看到当前集群有三个节点,且都是primary:
在任意节点上创建一个库或一个表,都能自动同步到其他节点上:
mysql> create database baidd;
Query OK, 1 row affected (0.00 sec)
mysql> create table t1(id int primary key ,hostname varchar(30));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t1(id) values(1,’aa’);
Query OK, 1 row affected (0.00 sec)
ProxySQL是一个高性能的SQL代理。ProxySQL作为一个守护进程运行,被监控进程监视着,在崩溃时会被重新启动,以最小化停机时间。
它接受来自MySQL客户端的查询,并将其转发到后端MySQL服务器。
大多数配置可以在运行时完成,不需要重启。
#最好在额外一台机器上安装ProxySQL,这里资源有限,选择在node3上安装
yum install proxysql2 -y
datadir默认是/var/lib/proxysql。
也可以点击https://www.percona.com/downloads/proxysql2/下载安装包进行安装。
修改/etc/proxysql.cnf,改下admin_credentials值。
--默认值是admin:admin,表示用户和密码都是admin。
修改以下几行:
export PROXYSQL_PASSWORD='proxysql admin密码'
export CLUSTER_USERNAME='PXC集群的管理员账号'
export CLUSTER_PASSWORD='PXC集群的管理员密码'
export CLUSTER_HOSTNAME='192.168.1.202' #PXC集群中的其中一个节点
export MAX_CONNECTIONS="1000" #根据自己需要进行配置
export MODE="singlewrite" #这里配置成了单写模式
export CLUSTER_APP_USERNAME='proxysql_user'
export CLUSTER_APP_PASSWORD='passw0rd' # proxysql_user的密码
export MONITOR_PASSWORD='自定义一个monitor用户密码'
service proxysql start
6032是admin管理端口,用于查看和配置ProxySQL。
6033是接收sql语句的端口,类似于mysql的3306端口。
#开放这俩端口给192.168.1网段。
iptables --insert INPUT --protocol tcp --match tcp --dport 6032 --source 192.168.1.0/24 --jump ACCEPT
iptables --insert INPUT --protocol tcp --match tcp --dport 6033 --source 192.168.1.0/24 --jump ACCEPT
#将配置更新到配置文件
iptables-save > /etc/sysconfig/iptables
proxysql-admin --config-file=/etc/proxysql-admin.cnf --enable
输出信息如下:
This script will assist with configuring ProxySQL for use with
Percona XtraDB Cluster (currently only PXC in combination
with ProxySQL is supported)
ProxySQL read/write configuration mode is singlewrite
Configuring the ProxySQL monitoring user.
ProxySQL monitor user name as per command line/config-file is monitor
User 'monitor'@'192.%' has been added with USAGE privileges
Configuring the Percona XtraDB Cluster application user to connect through ProxySQL
Percona XtraDB Cluster application user name as per command line/config-file is sstuser
Percona XtraDB Cluster application user 'proxysql_user'@'192.%' has been added with ALL privileges, this user is created for testing purposes
Adding the Percona XtraDB Cluster server nodes to ProxySQL
Write node info
+---------------+--------------+------+--------+
| hostname | hostgroup_id | port | weight |
+---------------+--------------+------+--------+
| 192.168.1.204 | 10 | 3306 | 1000 |
+---------------+--------------+------+--------+
ProxySQL configuration completed!
ProxySQL has been successfully configured to use with Percona XtraDB Cluster
You can use the following login credentials to connect your application through ProxySQL
mysql --user=proxysql_user -p --host=localhost --port=6033 --protocol=tcp
--可以看到自动在PXC集群里创建一个monitor用户,选取了192.168.1.204作为了写节点。
#验证配置结果
mysql -u admin -p -P 6032 -h 127.0.0.1
--这些PXC节点都是自动配置上的,如果后续需要添加节点,可以再往该表手动插入数据。
#登录ProxySQL,新插入一条数据,验证下PXC集群是否能看到该记录
mysql --user=proxysql_user -ppassw0rd --host=192.168.1.204 --port=6033 --protocol=tcp -e "insert into baidd.t1(id,hostname) values(10,@@hostname);"
--注意:如果想从ProxySQL中移除PXC节点并停止监视进程,可以使用proxysql-admin --config-file=/etc/proxysql-admin.cnf --disable命令。
--官方文档上说--enable会自动配置scheduler,但我发现我这里scheduler表为空,所以这里手动插入下:
INSERT INTO scheduler (active,interval_ms,filename,arg1,comment)
VALUES (1,10000,'/usr/bin/proxysql_galera_checker','--config-file=/etc/proxysql-admin.cnf
--write-hg=10 --read-hg=11 --writer-count=1 --mode=singlewrite --priority=192.168.1.202:3306,192.168.1.203:3306,192.168.1.204:3306
--log=/var/lib/proxysql/cluster_one_proxysql_galera_check.log','cluster_one');
LOAD SCHEDULER TO RUNTIME;
mysql> select match_digest,destination_hostgroup,active,apply from mysql_query_rules;
+---------------------+-----------------------+--------+-------+
| match_digest | destination_hostgroup | active | apply |
+---------------------+-----------------------+--------+-------+
| ^SELECT.*FOR UPDATE | 10 | 1 | 1 |
| ^SELECT | 11 | 1 | 1 |
+---------------------+-----------------------+--------+-------+
[root@pc3 ~]# mysql --user=proxysql_user -ppassw0rd --host=localhost --port=6033 --protocol=tcp -e "insert into baidd.t1(id,hostname) values(12,@@hostname);"
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@pc3 ~]# mysql --user=proxysql_user -ppassw0rd --host=localhost --port=6033 --protocol=tcp -e "select * from baidd.t1 where id=12;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+----------+
| id | hostname |
+----+----------+
| 12 | pc3 |
[root@pc3 ~]# mysql --user=proxysql_user -ppassw0rd --host=localhost --port=6033 --protocol=tcp -e "select @@hostname for update"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| pc3 |
+------------+
[root@pc3 ~]# mysql --user=proxysql_user -ppassw0rd --host=localhost --port=6033 --protocol=tcp -e "select @@hostname"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| pc1 |
+------------+
写落到了pc3(pc3属于10写组)上,读落到了pc1上,说明实现了读写分离
[root@pc2 ~]#vi a.sh
for i in {1..200}
do
mysql --user=proxysql_user -ppassw0rd --host=192.168.1.204 --port=6033 --protocol=tcp -e "select @@hostname"
done
sh a.sh > a.log
[root@pc2 ~]# cat a.log | grep pc1 | wc -l
98
[root@pc2 ~]# cat a.log | grep pc2 | wc -l
102
--看来还挺均衡的。
如果没有负载均衡,查看下日志(/var/lib/proxysql/proxysql.log)看看是否有报错。
关掉主库pc3的mysql,远程连接proxysql插入一条带有主机名的数据
[root@pc2 ~]# mysql --user=proxysql_user -ppassw0rd --host=192.168.1.204 --port=6033 --protocol=tcp -e "insert into baidd.t1(id,hostname) values(17,@@hostname);"
[root@pc2 ~]# mysql --user=proxysql_user -ppassw0rd --host=192.168.1.204 --port=6033 --protocol=tcp -e "select *from baidd.t1 where id= 17;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+----------+
| id | hostname |
+----+----------+
| 17 | pc2 |
+----+----------+
可以看到pc3宕机后,仍然能正常插入,数据插入到了pc2上。
试验发现,当原主库启动后,仍然会往原主库上插入数据。
#关掉其中一个读节点,验证几百个select,看下是否都正常发送到了另一个读节点
--担心ProxySQL单点的话,可以在两台机器上装下ProxySQL,并通过Keepalive配置一个浮动ip。
--本篇文章主要参考自PXC官方手册