ARM 架构上基于 ProxySQL 部署 PolarDB-X 高可用集群实战指南
环境准备与依赖项
操作系统要求 ARM 64
三台机器:192.168.106.136-138
资源准备:
1、proxysql-2.4.8-1-centos7.aarch64.rpm ->下载地址:link
2、t-polardbx-engine-8.4.19-20250825_17558853.el7.aarch64.rpm ->载地址:link
那么我们现在开启部署PolarDB-X之旅吧
1、将下载的RPM包分别上传到三台服务器上如下:
[root@k8s-master PolarDB-X]# ll t-polardbx-engine-8.4.19-20250825_17558853.el7.aarch64.rpm
-rw-r--r-- 1 root root 631160040 11月 2 15:40 t-polardbx-engine-8.4.19-20250825_17558853.el7.aarch64.rpm
2、使用rpm 命令进行安装:
rpm -ivh t-polardbx-engine-8.4.19-20250825_17558853.el7.aarch64.rpm
[root@k8s-master PolarDB-X]# rpm -ivh t-polardbx-engine-8.4.19-20250825_17558853.el7.aarch64.rpm
准备中... ################################# [100%]
正在升级/安装...
1:t-polardbx-engine-8.4.19-20250825################################# [100%]
Copying /u01/xcluster80_20250825_current to /u01/xcluster80
Copying /u01/xcluster80_20250825_current to /u01/xcluster80_20250825
出现上述为安装完成
验证是否完成安装执行:
[root@k8s-master opt]# ll polardbx_engine
lrwxrwxrwx 1 root root 24 11月 2 18:15 polardbx_engine -> /u01/xcluster80_20250825
[root@k8s-master opt]# cd polardbx_engine/
[root@k8s-master polardbx_engine]# ll
总用量 704
drwxr-xr-x 2 root root 4096 11月 2 18:14 bin
drwxr-xr-x 2 root root 87 11月 2 18:14 docs
drwxr-xr-x 3 root root 282 11月 2 18:14 include
drwxr-xr-x 6 root root 207 11月 2 18:15 lib
-rwxr-xr-x 1 root root 283374 11月 2 18:10 LICENSE
-rwxr-xr-x 1 root root 121462 11月 2 18:10 LICENSE.router
-rwxr-xr-x 1 root root 283374 11月 2 18:10 LICENSE-test
drwxr-xr-x 4 root root 30 11月 2 18:15 man
-rwxr-xr-x 1 root root 1622 11月 2 18:15 mysqlrouter-log-rotate
-rwxr-xr-x 1 root root 952 11月 2 18:10 README
-rwxr-xr-x 1 root root 679 11月 2 18:10 README.router
-rwxr-xr-x 1 root root 952 11月 2 18:10 README-test
drwxr-xr-x 2 root root 6 11月 2 18:15 run
drwxr-xr-x 28 root root 4096 11月 2 18:15 share
drwxr-xr-x 2 root root 77 11月 2 18:15 support-files
drwxr-xr-x 3 root root 17 11月 2 18:15 var
出现上述为安装完成
3、创建 polarx 用户
使用其他非 root 用户,准备一份 my.cnf(参考模板)和数据目录(如果改了 my.cnf,则下面的目录也要相应修改
创建并切换到 polarx 用户
useradd -ms /bin/bash polarx
echo "polarx:polarx" | chpasswd
echo "polarx ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
su - polarx
创建必要目录
cd /opt
mkdir polardbx-engine
cd polardbx-engine && mkdir log mysql run data tmp
准备一份 my.cnf 文件,放至polardbx-engine目录下
cd /opt/polardbx-engine
vi my.cnf
[mysqld]
basedir = /opt/polardbx_engine
log_error_verbosity = 2
gtid_mode = ON
enforce_gtid_consistency = ON
log_bin = mysql-binlog
binlog_format = row
binlog_row_image = FULL
master_info_repository = TABLE
relay_log_info_repository = TABLE
lower_case_table_names=1
-# change me if needed
datadir = /home/polarx/polardbx-engine/data
tmpdir = /home/polarx/polardbx-engine/tmp
socket = /home/polarx/polardbx-engine/tmp.mysql.sock
log_error = /home/polarx/polardbx-engine/log/alert.log
bind-address = 0.0.0.0
port = 4886
cluster_id = 1
server_id = 1
cluster_info = 192.168.106.136:14886@1,192.168.106.137:14886@2,192.168.106.138:14886@3
[mysqld_safe]
pid_file = /home/polarx/polardbx-engine/run/mysql.pid
注意:这里讲集群模式的my.cnf 配置注意事项,本案例是三个副本模式运行,配置文件my.cnf 中的参数注意如下三个重要参数:
cluster_id:整集群 相同,相当于“车队编号”。
cluster_info:整集群 相同,是“车队全部车辆列表”,逗号+@序号 必须写全。
server_id:每节点不同,相当于“自己在车队里的车牌号”。
三份配置文件里只有 server_id 不一样,其余完全保持一致,就是正确对应关系,更多副本是一个配置原理。
完成配置的目录结构如下:
[root@k8s-master polardbx-engine]# ll
总用量 4
drwxr-xr-x 2 root root 6 11月 2 18:31 data
drwxr-xr-x 2 root root 6 11月 2 18:31 log
-rw-r--r-- 1 root root 718 11月 2 19:09 my.cnf
drwxr-xr-x 2 root root 6 11月 2 18:31 mysql
drwxr-xr-x 2 root root 6 11月 2 18:31 run
drwxr-xr-x 2 root root 6 11月 2 18:31 tmp
注意一定要所有集群机器,准备好的的RPM包后,按上述步骤1-3执行安装步骤后;
注意:(如果有任何步骤失败,请完全清理 log mysql run data tmp 等目录,执行1-3安装步骤,重新创建),如果 my.cnf 不在当前目录,请将下述命令的 my.cnf 改成绝对路径。
然后在分别在所有集群机器上,分别在机器上执行如下命令进行初始化和启动操作:
#192.168.106.136上执行如下命令初始化:
/opt/polardbx_engine/bin/mysqld --defaults-file=my.cnf --cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886@1' --initialize-insecure
#192.168.106.136上执行如下命令启动:
/opt/polardbx_engine/bin/mysqld_safe --defaults-file=my.cnf --cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886@1' &
#192.168.106.137上执行如下命令初始化:
/opt/polardbx_engine/bin/mysqld --defaults-file=my.cnf --cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886@2' --initialize-insecure
#192.168.106.137上执行如下命令启动:
/opt/polardbx_engine/bin/mysqld_safe --defaults-file=my.cnf --cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886@2' &
#192.168.106.138上执行如下命令初始化:
/opt/polardbx_engine/bin/mysqld --defaults-file=my.cnf --cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886@3' --initialize-insecure
#192.168.106.138上执行如下命令启动:
/opt/polardbx_engine/bin/mysqld_safe --defaults-file=my.cnf --cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886@3' &
注意到,我们在启动时修改了 cluster-info 的配置项,其中的格式为 [host1]:[port1];[host2]:[port2];[host3]:[port3]@[idx] ,不同的机器,只有 [idx] 不同,[idx] 也反映了该机器是第几个 [host][port]。请根据实际机器的 ip 修改该配置项。
另外,如果要让 PolarDB-X 的副本启动为 Logger 模式(Logger 会占用更少的资源,推荐让其中一个副本配置为 Logger),需要设置cluster-log-type-node=ON。
# 比如我们把第四个主机,配置为logger模式
/opt/polardbx_engine/bin/mysqld_safe --defaults-file=my.cnf \
cluster-log-type-node=ON \
--cluster-info='192.168.106.136:14886;192.168.106.137:14886;192.168.106.138:14886;192.168.106.139:14886@4' \
&
数据库启动完成后,我们登录数据库,验证一下集群的状态。
# 分别登录每个数据库副本,执行下面的命令,可以看到每个副本的角色(Leader,Follower,Logger)。
MySQL [(none)]> SELECT * FROM INFORMATION_SCHEMA.ALISQL_CLUSTER_LOCAL \G
*************************** 1. row ***************************
SERVER_ID: 1
CURRENT_TERM: 6
CURRENT_LEADER: 192.168.106.136:14886
COMMIT_INDEX: 1
LAST_LOG_TERM: 6
LAST_LOG_INDEX: 1
ROLE: Leader
VOTED_FOR: 1
LAST_APPLY_INDEX: 0
SERVER_READY_FOR_RW: Yes
INSTANCE_TYPE: Normal
# 在 Leader 节点上执行下面的命令,可以看到整个集群的状态。
MySQL [(none)]> SELECT * FROM INFORMATION_SCHEMA.ALISQL_CLUSTER_GLOBAL;
+-----------+------------------+-------------+------------+----------+-----------+------------+-----------------+----------------+---------------+------------+--------------+
| SERVER_ID | IP_PORT | MATCH_INDEX | NEXT_INDEX | ROLE | HAS_VOTED | FORCE_SYNC | ELECTION_WEIGHT | LEARNER_SOURCE | APPLIED_INDEX | PIPELINING | SEND_APPLIED |
+-----------+------------------+-------------+------------+----------+-----------+------------+-----------------+----------------+---------------+------------+--------------+
| 1 | 192.168.106.136:14886 | 1 | 0 | Leader | Yes | No | 5 | 0 | 0 | No | No |
| 2 | 192.168.106.137:14886 | 1 | 2 | Follower | Yes | No | 5 | 0 | 1 | Yes | No |
| 3 | 192.168.106.138:14886 | 1 | 2 | Follower | No | No | 5 | 0 | 1 | Yes | No |
+-----------+------------------+-------------+------------+----------+-----------+------------+-----------------+----------------+---------------+------------+--------------+
3 rows in set (0.00 sec)
如果一切顺利,到这里,通过以上步骤,我们简单验证了基于Paxos三副本自动选主和切换的能力。
验证安装
登录所有机器。如果直接使用本文的 my.cnf 模板,可以用mysql -u root -h 127.0.0.1 -P 4886 登录数据库。(需要预先在机器上安装 mysql 客户端,centos 系统可以使用 yum install mysql 安装。)
$ mysql -u root -h 127.0.0.1 -P 4886
最后,官方不推荐使用RPM方式在生产上部署,生产推荐使用K8S方式部署。如果确实要用RPM方式在生产上部署,业务需要注意自行感知Leader的切换,以使用正确的连接串访问数据库,或者使用开源ProxySQL构建PolarDB-X标准版高可用路由服务。
┌----------------------┐
│ Application │
└----------┬-----------┘
│6033
┌----------▼-----------┐
│ ProxySQL 2.4.8 │◀- Keepalived(可选)
│ 192.168.106.36 │
└----┬--------┬--------┘
│4886 │4886
┌-------------------┼--------┼-------------------┐
▼ ▼ ▼ ▼
┌---------------┐ ┌---------------┐ ┌---------------┐ ┌---------------┐
│ PolarDB-X-1 │ │ PolarDB-X-2 │ │ PolarDB-X-3 │ │ Logger* │
│ Leader(10) │ │ Follower(20) │ │ Follower(20) │ │ (不参与路由)│
│192.168.106.36 │ │192.168.106.37 │ │192.168.106.38 │ │192.168.106.39 │
└---------------┘ └---------------┘ └---------------┘ └---------------┘
接下来我们一起通过使用开源ProxySQL构建PolarDB-X标准版高可用路由服务
口水话:
PolarDB-X 作为PolarDB分布式版,是阿里巴巴自主设计研发的高性能云原生分布式数据库产品,采用 Shared-nothing 与存储分离计算架构,支持集中式和分布式一体化形态,具备金融级数据高可用、分布式水平扩展、混合负载、低成本存储和极致弹性等能力,坚定以兼容MySQL开源生态构建分布式能力,为用户提供高吞吐、大存储、低延时、易扩展和超高可用的云时代数据库服务
前面已经将所需的 RPM 包准备好,下面开始正式实战
1、在指定机器安装ProxySQL服务
rpm -ivh proxysql-2.4.8-1-centos7.x86_64.rpm --nodeps
``
2、启动并查看运行状态
```bash
systemctl start proxysql
systemctl status proxysql
3、创建依赖视图,配置PolarDB-X集群,目的让ProxySQL识别PolarDB-X标准版的元数据(Leader、Follower)
CREATE VIEW sys.gr_member_routing_candidate_status AS
SELECT IF(ROLE='Leader' OR ROLE='Follower', 'YES', 'NO' ) as viable_candidate,
IF(ROLE <>'Leader', 'YES', 'NO' ) as read_only,
IF (ROLE = 'Leader', 0, LAST_LOG_INDEX - LAST_APPLY_INDEX) as transactions_behind,
0 as 'transactions_to_cert'
FROM information_schema.ALISQL_CLUSTER_LOCAL;
--注意如果有Logger节点服务,Logger节点不能提供数据服务,该地方只录入了Leader和Follower节点
创建ProxySql的监控账户,ProxySQL运行通用依赖
create user 'proxysql_monitor'@'%' identified with mysql_native_password by '123456';
GRANT SELECT on sys.* to 'proxysql_monitor'@'%';
创建测试账户,下面高可用测试依赖
create user 'admin'@'%' identified with mysql_native_password by '123456';
GRANT all privileges on *.* to 'admin'@'%';
检查配置是否生效
mysql> select @@port;
+--------+
| @@port |
+--------+
| 4886 |
+--------+
1 row in set (0.00 sec)
mysql> select * from information_schema.ALISQL_CLUSTER_GLOBAL;
mysql> select * from sys.gr_member_routing_candidate_status ;
mysql> select User,Host from mysql.user where User in ('admin2', 'proxysql_monitor');
4、配置
mysql -uadmin -padmin -h 127.0.0.1 -P 6032 -A
powershell
1
检查确保mysql_servers、mysql_group_replication_hostgroups、mysql_query_rules为空
#执行检查
mysql> select * from mysql_group_replication_hostgroups;
Empty set (0.00 sec)
mysql> select * from mysql_servers;
Empty set (0.00 sec)
mysql> select * from mysql_query_rules;
Empty set (0.00 sec)
mysql_servers作用
登记 所有后端 MySQL/PolarDB-X 实例 的地址、端口、所属 hostgroup、权重、最大连接数等。
ProxySQL 真正转发 SQL 时 只看 runtime_mysql_servers,而那张表的数据就是从这里 LOAD 过去的。
核心字段速记
hostgroup_id → 逻辑分组编号(10=写,20=读,可自定义)
hostname → IP 或域名
port → 实例端口(PolarDB-X 默认 4886)
weight → 负载均衡权重
max_connections / max_replication_lag → 保护阈值
status → ONLINE / OFFLINE_SOFT / OFFLINE_HARD / SHUNNED
mysql_group_replication_hostgroups作用
把 同一套 Paxos/MGR 集群 的多个 hostgroup 绑在一起,并告诉 ProxySQL:
“谁应该是写、谁应该是读,主挂了怎么切”。
只有 这一行配置 active=1,monitor 线程才会去扫 sys.gr_member_routing_candidate_status 视图,
然后 实时把节点挪到正确的 hostgroup,实现 自动故障转移 + 读写分离。
核心字段速记
writer_hostgroup → 写节点所在组(通常 10)
reader_hostgroup → 读节点所在组(通常 20)
backup_writer_hostgroup → 新主上任前的过渡组
offline_hostgroup → 故障/维护组
active → 1 才生效
max_writers → 同时允许几个写节点(PolarDB-X 单主填 1)
writer_is_also_reader → 主节点是否也参与读负载(1=是,0=纯写)
mysql_query_rules作用
SQL 级别的防火墙 + 路由表。
ProxySQL 收到每条语句后,按 rule_id 从小到大 逐条匹配;
一旦某条 match_pattern 命中且 apply=1,立即把该语句路由到 destination_hostgroup,
后续规则不再评估。
核心字段速记
rule_id → 全局自增,决定匹配顺序
active → 1 才生效
match_pattern → 正则或普通字符串(区分大小写)
destination_hostgroup → 目标 hostgroup
apply → 1=立即生效并跳出,0=继续往下匹配
cache_ttl → 查询缓存秒数(可选)
mirror_flag / mirror_hostgroup → 镜像流量(压测、审计)
更新监控账号
将我们在前面创建的监控账号更新到proxySQL中
UPDATE global_variables SET variable_value='proxysql_monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='123456' WHERE variable_name='mysql-monitor_password';
#检查:
mysql> select * from global_variables where variable_name in ('mysql-monitor_username', 'mysql-monitor_password');
+------------------------+------------------+
| variable_name | variable_value |
+------------------------+------------------+
| mysql-monitor_password | 123456 |
| mysql-monitor_username | proxysql_monitor |
+------------------------+------------------+
2 rows in set (0.00 sec)
添加测试账号
INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('admin2','123456',10);
#检查
mysql> select * from mysql_users;
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+------------+---------+
| username | password | active | use_ssl | default_hostgroup | default_schema | schema_locked | transaction_persistent | fast_forward | backend | frontend | max_connections | attributes | comment |
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+------------+---------+
| admin2 | 123456 | 1 | 0 | 10 | NULL | 0 | 1 | 0 | 1 | 1 | 10000 | | |
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+------------+---------+
1 row in set (0.00 sec)
设置读写组,写组10,备写组20,读组30,离线组40,主节点可作为读节点
INSERT INTO mysql_group_replication_hostgroups (writer_hostgroup,backup_writer_hostgroup,reader_hostgroup,offline_hostgroup,active,writer_is_also_reader) VALUES(10,20,30,40,1,1);
#检查
mysql> select * from mysql_group_replication_hostgroups;
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
| writer_hostgroup | backup_writer_hostgroup | reader_hostgroup | offline_hostgroup | active | max_writers | writer_is_also_reader | max_transactions_behind | comment |
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
| 10 | 20 | 30 | 40 | 1 | 1 | 1 | 0 | NULL |
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
1 row in set (0.00 sec)
添加后端mysql_servers,leader节点定义为写组10, follower节点定义为备写库20。 注意这里port为节点的PolarDB-X标准版的监听端口port。
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (10,'192.168.106.36',4886);
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (20,'192.168.106.37',4886);
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (20,'192.168.106.38',4886);
#检查
mysql> select * from mysql_servers;
配置读写分离规则。对于SELECT FOR UPDATE配置到写库,纯SELECT配置到读库。
INSERT INTO mysql_query_rules(active,match_pattern,destination_hostgroup,apply) VALUES(1,'^select.*for update$',10,1);
INSERT INTO mysql_query_rules(active,match_pattern,destination_hostgroup,apply) VALUES(1,'^select',30,1);
检查:
mysql> select * from mysql_query_rules;
+---------+--------+----------+------------+--------+-------------+------------+------------+--------+--------------+----------------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+-----------+--------+-------------+-----------+---------------------+-----+-------+------------+---------+
| rule_id | active | username | schemaname | flagIN | client_addr | proxy_addr | proxy_port | digest | match_digest | match_pattern | negate_match_pattern | re_modifiers | flagOUT | replace_pattern | destination_hostgroup | cache_ttl | cache_empty_result | cache_timeout | reconnect | timeout | retries | delay | next_query_flagIN | mirror_flagOUT | mirror_hostgroup | error_msg | OK_msg | sticky_conn | multiplex | gtid_from_hostgroup | log | apply | attributes | comment |
+---------+--------+----------+------------+--------+-------------+------------+------------+--------+--------------+----------------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+-----------+--------+-------------+-----------+---------------------+-----+-------+------------+---------+
| 9 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^select.*for update$ | 0 | CASELESS | NULL | NULL | 10 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 10 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^select | 0 | CASELESS | NULL | NULL | 30 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
+---------+--------+----------+------------+--------+-------------+------------+------------+--------+--------------+----------------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+-----------+--------+-------------+-----------+---------------------+-----+-------+------------+---------+
2 rows in set (0.00 sec)
保存配置并载入内存生效
save mysql users to disk;
save mysql servers to disk;
save mysql query rules to disk;
save mysql variables to disk;
save admin variables to disk;
load mysql users to runtime;
load mysql servers to runtime;
load mysql query rules to runtime;
load mysql variables to runtime;
load admin variables to runtime;
#检查:
mysql> select * from runtime_mysql_servers;
通过客户端连接工具连接验证:
连接方式应为是通过 ProxySQL实现路由的 所以通过6033端口,连接为: ip:prot 6033 admin2 123456
至此 ARM 架构上基于 ProxySQL 部署 PolarDB-X 集群实战全部完成 后续出一个PolarDB-PG