目录
[一、设置 ProxySQL 分片](#一、设置 ProxySQL 分片)
[1. 基于用户的分片](#1. 基于用户的分片)
[2. 基于库的分片](#2. 基于库的分片)
[3. 基于数据的分片](#3. 基于数据的分片)
[(2)INSERT 规则](#(2)INSERT 规则)
[(3)UPDATE / DELETE / SELECT 规则](#(3)UPDATE / DELETE / SELECT 规则)
[4. 注意事项](#4. 注意事项)
[1. mysql_aws_aurora_hostgroups](#1. mysql_aws_aurora_hostgroups)
[2. mysql_collations](#2. mysql_collations)
[3. mysql_firewall_whitelist_rules](#3. mysql_firewall_whitelist_rules)
[4. mysql_firewall_whitelist_sqli_fingerprints](#4. mysql_firewall_whitelist_sqli_fingerprints)
[5. mysql_firewall_whitelist_users](#5. mysql_firewall_whitelist_users)
[6. mysql_galera_hostgroups](#6. mysql_galera_hostgroups)
[7. mysql_group_replication_hostgroups](#7. mysql_group_replication_hostgroups)
[8. mysql_hostgroup_attributes](#8. mysql_hostgroup_attributes)
[9. mysql_query_rules](#9. mysql_query_rules)
[10. mysql_query_rules_fast_routing](#10. mysql_query_rules_fast_routing)
[11. mysql_replication_hostgroups](#11. mysql_replication_hostgroups)
[12. mysql_servers](#12. mysql_servers)
[13. mysql_servers_ssl_params](#13. mysql_servers_ssl_params)
[14. mysql_users](#14. mysql_users)
一、设置 ProxySQL 分片
ProxySQL 支持三种主要的分片方式:基于用户、基于库和基于数据。用户可以选择最适合自己应用架构的方式。
1. 基于用户的分片
最简单的方式,是根据连接的用户来路由查询。这种方式无需配置查询规则,只要绑定用户即可。例如:
sql
-- 实例1 → hostgroup 0
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (0, '192.168.1.10', 3306, 1000);
-- 实例2 → hostgroup 1
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (1, '192.168.1.11', 3306, 1000);
-- 实例3 → hostgroup 2
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (2, '192.168.1.12', 3306, 1000);
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
INSERT INTO mysql_users (username, password, active, default_hostgroup, comment) VALUES
('accounts', 'shard0_pass', 1, 0, '路由到accounts分片'),
('transactions', 'shard1_pass', 1, 1, '路由到transactions分片'),
('logging', 'shard2_pass', 1, 2, '路由到logging分片');
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
实例1 中有个用户叫 accounts, 实例2 中有个用户叫 transactions,实例3 中有个用户叫 logging。这样就完成绑定了:
- 用户 accounts → default_hostgroup=0 → 走实例 1
- 用户 transactions → default_hostgroup=1 → 走实例 2
- 用户 logging → default_hostgroup=2 → 走实例 3
完全不需要写任何查询规则,自动路由。accounts、transactions、logging 既是应用连 ProxySQL 的账号,也是 ProxySQL 去连真实 MySQL 的账号。ProxySQL 只是"透明转发",账号密码不换,只做路由。
2. 基于库的分片
通过查询规则将库名映射到目标主机组。要求库名遵循约定格式,例如 shard_0、shard_1 等。例如:
sql
-- 实例1 → hostgroup 0
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (0, '192.168.1.10', 3306, 1000);
-- 实例2 → hostgroup 1
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (1, '192.168.1.11', 3306, 1000);
-- 实例3 → hostgroup 2
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (2, '192.168.1.12', 3306, 1000);
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
INSERT INTO mysql_query_rules (rule_id, active, schemaname, destination_hostgroup, apply) VALUES
(1, 1, 'shard_0', 0, 1),
(2, 1, 'shard_1', 1, 1),
(3, 1, 'shard_2', 2, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
实例1 中有个库叫 shard_0, 实例2 中有个库叫 shard_1,实例3 中有个库叫 shard_2。最终绑定关系:
- shard_0 → hostgroup 0 → 实例1 (192.168.1.10)
- shard_1 → hostgroup 1 → 实例2 (192.168.1.11)
- shard_2 → hostgroup 2 → 实例3 (192.168.1.12)
客户端一执行:
sql
USE shard_0;
ProxySQL:shard_0 → 0组 → 实例1
实例上有什么库名,就把那个库名绑定到这个实例的编号上。这就是最标准、最简单的库级分片(分库)。
3. 基于数据的分片
最灵活的方式,是根据分片键标识的特定行,将请求路由到不同主机组。需要精心设计规则,但支持表级或行级分片。
(1)示例表结构
bash
loc_account_data 表:
+----------------------------------------+---------+---------+
| loc_id | user | acc_id |
+----------------------------------------+---------+---------+
| 20086020554955909836090724037181646035 | joe32 | 1 |
| 21503957780049285539986052866765125704 | sam57 | 2 |
| 75863560943999160082133817802533222835 | pam18 | 3 |
+----------------------------------------+---------+---------+
loc_mapping 表:
+----------------------------------------+---------+
| loc_id | region |
+----------------------------------------+---------+
| 20086020554955909836090724037181646035 | AMERICA |
| 21503957780049285539986052866765125704 | EMEA |
| 75863560943999160082133817802533222835 | OCEANIA |
+----------------------------------------+---------+
MySQL 实例还是这三个:
sql
-- 实例1 → hostgroup 0
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (0, '192.168.1.10', 3306, 1000);
-- 实例2 → hostgroup 1
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (1, '192.168.1.11', 3306, 1000);
-- 实例3 → hostgroup 2
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (2, '192.168.1.12', 3306, 1000);
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
(2)INSERT 规则
sql
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
(1, 1, 'loc_account_data.*20086020554955909836090724037181646035', 0, 1),
(2, 1, 'loc_account_data.*21503957780049285539986052866765125704', 1, 1),
(3, 1, 'loc_account_data.*75863560943999160082133817802533222835', 2, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
match_pattern 正则表达式的意思是:只要 SQL 语句里出现 "loc_account_data" 这个表,后面跟着这个 loc_id,就匹配 INSERT(因为 INSERT 一定会写表名)。
- loc_account_data 里带 20086... → 发 hostgroup 0(实例1)
- loc_account_data 里带 21503... → 发 hostgroup 1(实例2)
- loc_account_data 里带 75863... → 发 hostgroup 2(实例3)
(3)UPDATE / DELETE / SELECT 规则
直接匹配分片键,适用于所有其他语句类型:
sql
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply) VALUES
(4, 1, 'loc_id = 20086020554955909836090724037181646035', 0, 1),
(5, 1, 'loc_id = 21503957780049285539986052866765125704', 1, 1),
(6, 1, 'loc_id = 75863560943999160082133817802533222835', 2, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
- loc_id = 20086... → 发 0
- loc_id = 21503... → 发 1
- loc_id = 75863... → 发 2
只有 SQL 完全一模一样才会匹配,只要 SQL 变成下面任意一种,直接不匹配:
sql
WHERE loc_id='20086...' -- 加了引号
WHERE loc_id = 20086... -- 多空格
WHERE abc=1 AND loc_id=20086... -- 前面多条件
所以这个示例只是演示思路,真实生产不能这么写。ProxySQL 用的是正则表达式,灵活、通用要写模糊匹配可以是这样:
bash
'loc_id\s*=\s*[\'"]?200860205549559090724037181646035[\'"]?'
基于数据的分片就是按数据里的某个字段(loc_id)的值,决定这条 SQL 发给哪台 MySQL,loc_id 就是分片键。
- 场景 1:插入 joe32 的数据
sql
INSERT INTO loc_account_data (loc_id, user, acc_id)
VALUES ('20086020554955909836090724037181646035', 'joe32', 1);
ProxySQL 动作:看到 loc_id = 20086...→ 发给 hostgroup 0(192.168.1.10)→ 只有这台机器存了 joe32。
- 场景 2:查询 sam57
sql
SELECT * FROM loc_account_data
WHERE loc_id = '21503957780049285539986052866765125704';
ProxySQL 动作:匹配到 loc_id = 21503...→ 发给 hostgroup 1(192.168.1.11)→ 只有这台机器有 sam57 的数据。
- 场景 3:更新 pam18
sql
UPDATE loc_account_data
SET user='pam_new'
WHERE loc_id = '75863560943999160082133817802533222835';
ProxySQL 动作:匹配到 loc_id = 75863...→ 发给 hostgroup 2(192.168.1.12)
4. 注意事项
- 基于用户和基于库的分片更易实现与维护,应优先使用这两种方式。
- 基于数据的分片需要为每个分片键值和每种语句类型(INSERT、UPDATE、DELETE、SELECT)分别配置规则。
- 跨分片 JOIN 必须在应用层处理,ProxySQL 单次查询仅路由到一个主机组。
- 基于数据的分片可结合读写分离,只需为每个分片添加额外规则。
- 分片不限于这三种方式,它们是最常用的模式。
二、查询规则参考
ProxySQL 管理端将配置存储在表中。连接到管理端可以看到配置表和运行时表列表,具体的表列表会因使用的版本以及 ProxySQL 某些模块是否运行而有所不同。下面是 2.7.3 版本的输出:
sql
ProxySQL Admin> SHOW TABLES FROM main;
+----------------------------------------------------+
| tables |
+----------------------------------------------------+
| coredump_filters |
| global_variables |
| mysql_aws_aurora_hostgroups |
| mysql_collations |
| mysql_firewall_whitelist_rules |
| mysql_firewall_whitelist_sqli_fingerprints |
| mysql_firewall_whitelist_users |
| mysql_galera_hostgroups |
| mysql_group_replication_hostgroups |
| mysql_hostgroup_attributes |
| mysql_query_rules |
| mysql_query_rules_fast_routing |
| mysql_replication_hostgroups |
| mysql_servers |
| mysql_servers_ssl_params |
| mysql_users |
| proxysql_servers |
| restapi_routes |
| runtime_checksums_values |
| runtime_coredump_filters |
| runtime_global_variables |
| runtime_mysql_aws_aurora_hostgroups |
| runtime_mysql_firewall_whitelist_rules |
| runtime_mysql_firewall_whitelist_sqli_fingerprints |
| runtime_mysql_firewall_whitelist_users |
| runtime_mysql_galera_hostgroups |
| runtime_mysql_group_replication_hostgroups |
| runtime_mysql_hostgroup_attributes |
| runtime_mysql_query_rules |
| runtime_mysql_query_rules_fast_routing |
| runtime_mysql_replication_hostgroups |
| runtime_mysql_servers |
| runtime_mysql_servers_ssl_params |
| runtime_mysql_users |
| runtime_proxysql_servers |
| runtime_restapi_routes |
| runtime_scheduler |
| scheduler |
+----------------------------------------------------+
38 rows in set (0.00 sec)
关键配置表:
|--------------------------------------------|----------------------------------|
| 表名 | 配置内容 |
| mysql_aws_aurora_hostgroups | 支持原生发现的 Amazon Aurora MySQL 集群 |
| mysql_collations | 已知的 MySQL 字符集和排序规则 |
| mysql_firewall_whitelist_rules | 按用户和库的查询防火墙白名单规则 |
| mysql_firewall_whitelist_sqli_fingerprints | 用于注入检测和拦截的 SQL 注入指纹 |
| mysql_firewall_whitelist_users | 用户及其分配的防火墙强制执行模式 |
| mysql_galera_hostgroups | 使用 Galera 复制的 MySQL 集群 |
| mysql_group_replication_hostgroups | 使用组复制的 MySQL 集群 |
| mysql_hostgroup_attributes | 覆盖全局配置的主机组专属属性 |
| mysql_query_rules | MySQL 流量查询规则 |
| mysql_query_rules_fast_routing | 专门用于路由的 MySQL 流量查询规则 |
| mysql_replication_hostgroups | 服务器处于读写(RW)或只读(RO)模式的 MySQL 复制集群 |
| mysql_servers | 后端 MySQL 服务器 |
| mysql_servers_ssl_params | 后端 MySQL 服务器专属 SSL 参数 |
| mysql_users | 前端和后端 MySQL 用户 |
1. mysql_aws_aurora_hostgroups
用于定义 Amazon Aurora 集群对应的主机组。ProxySQL 利用 Aurora 发现机制自动检测集群拓扑变更,包括写入节点和读取节点端点分配。
sql
CREATE TABLE mysql_aws_aurora_hostgroups (
writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>0),
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
aurora_port INT NOT NULL DEFAULT 3306,
domain_name VARCHAR NOT NULL DEFAULT '',
max_lag_ms INT CHECK (max_lag_ms>=0) NOT NULL DEFAULT 600000,
check_interval_ms INT CHECK (check_interval_ms>=0) NOT NULL DEFAULT 1000,
check_timeout_ms INT CHECK (check_timeout_ms>=0) NOT NULL DEFAULT 800,
writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0,
new_reader_weight INT CHECK (new_reader_weight >= 0 AND new_reader_weight <=10000000) NOT NULL DEFAULT 1,
add_lag_ms INT NOT NULL DEFAULT 30,
min_lag_ms INT NOT NULL DEFAULT 30,
lag_num_checks INT NOT NULL DEFAULT 1,
comment VARCHAR,
UNIQUE (reader_hostgroup)
)
各字段含义:
- writer_hostgroup:Aurora 写入节点所在的主机组,ProxySQL 会将写入流量路由到该主机组。
- reader_hostgroup:Aurora 读取节点所在的主机组,读取流量需通过查询规则或只读用户路由至此。
- active:设为 1 时,ProxySQL 主动监控 Aurora 集群并根据拓扑发现调整主机组成员;设为 0 则禁用该集群的 Aurora 监控。
- aurora_port:连接 Aurora 实例使用的 TCP 端口,默认 3306。
- domain_name:拓扑发现时解析实例主机名所用的 Aurora 集群 DNS 域名后缀。
- max_lag_ms:读取节点保留在 reader_hostgroup 中可接受的最大复制延迟(毫秒),超出阈值会被临时屏蔽。
- check_interval_ms:ProxySQL 轮询 Aurora 拓扑端点发现集群变更的频率(毫秒)。
- check_timeout_ms:ProxySQL 等待拓扑检查响应的最大时长(毫秒),超时则视为失败。
- writer_is_also_reader:设为 1 时,当前写入节点也会加入 reader_hostgroup,可承接读取流量。
- new_reader_weight:ProxySQL 自动将新发现的读取节点加入 reader_hostgroup 时分配的权重。
- add_lag_ms:评估 max_lag_ms 阈值时,在测量延迟基础上增加的缓冲值。
- min_lag_ms:视为有效的最小延迟值,低于该值的测量结果按 0 处理。
- lag_num_checks:读取节点连续超出 max_lag_ms 阈值的检查次数,达标后被屏蔽。
- comment:自定义备注字段。
2. mysql_collations
存储 ProxySQL 支持的所有可用字符集/排序规则组合。
sql
CREATE TABLE mysql_collations (
Id INTEGER NOT NULL PRIMARY KEY,
Collation VARCHAR NOT NULL,
Charset VARCHAR NOT NULL,
`Default` VARCHAR NOT NULL
)
3. mysql_firewall_whitelist_rules
为 ProxySQL 防火墙模块定义按用户、按库的查询白名单。当对应用户开启防火墙强制执行时,仅摘要匹配活跃白名单规则的查询允许执行。
sql
CREATE TABLE mysql_firewall_whitelist_rules (
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
username VARCHAR NOT NULL,
client_addr VARCHAR NOT NULL,
schemaname VARCHAR NOT NULL,
flagIN INT NOT NULL DEFAULT 0,
digest VARCHAR NOT NULL,
match_digest VARCHAR NOT NULL DEFAULT '',
error_msg VARCHAR NOT NULL DEFAULT '',
comment VARCHAR NOT NULL DEFAULT '',
PRIMARY KEY (username, client_addr, schemaname, flagIN, digest)
)
各字段含义:
- active:仅 active=1 的规则会加载到运行时防火墙并对传入的查询生效。
- username:规则适用的 MySQL 用户名,仅连接用户匹配时才校验该规则。
- client_addr:规则适用的客户端 IP 地址,空字符串表示匹配该用户的所有客户端地址。
- schemaname:规则校验时使用的默认库,空字符串表示匹配任意库。
- flagIN:与 mysql_query_rules 的 flagIN/flagOUT 链式机制关联,让防火墙可集成多阶段规则校验。
- digest:白名单的精确查询摘要,与 stats_mysql_query_digest 记录的值一致,为核心匹配条件。
- match_digest:对查询摘要的可选正则表达式二次过滤,空则仅依赖 digest 列。
- error_msg:查询被防火墙拦截时返回给客户端的信息,覆盖默认错误响应。
- comment:自定义备注字段。
4. mysql_firewall_whitelist_sqli_fingerprints
存储 ProxySQL 防火墙用于检测并拦截 SQL 注入攻击的注入指纹。当查询指纹匹配本表条目且对应用户处于 DETECTING 或 PROTECTING 模式时,ProxySQL 会记录或拦截该查询。
sql
CREATE TABLE mysql_firewall_whitelist_sqli_fingerprints (
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
fingerprint VARCHAR NOT NULL,
comment VARCHAR NOT NULL DEFAULT '',
PRIMARY KEY (fingerprint)
)
各字段含义:
- active:仅 active=1 的指纹会加载到运行时防火墙并用于 SQL 注入检测。
- fingerprint:代表已知 SQL 注入模式的标准化查询指纹,ProxySQL 防火墙校验时会将传入的查询指纹与此表对比。
- comment:自定义备注字段,可记录指纹关联的 CVE 编号或攻击模式名称。
5. mysql_firewall_whitelist_users
控制哪些用户受防火墙强制执行及执行模式。查询到达时优先查询此表:未在此表列出的连接用户不受防火墙管控。
sql
CREATE TABLE mysql_firewall_whitelist_users (
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
username VARCHAR NOT NULL,
client_addr VARCHAR NOT NULL,
mode VARCHAR CHECK (UPPER(mode) IN ('OFF','DETECTING','PROTECTING')) NOT NULL DEFAULT 'OFF',
comment VARCHAR NOT NULL DEFAULT '',
PRIMARY KEY (username, client_addr)
)
各字段含义:
- active:仅 active=1 的条目会加载到运行时防火墙。
- username:适用该防火墙模式的 MySQL 用户名。
- client_addr:适用该条目的客户端 IP 地址,空字符串表示匹配该用户的所有客户端地址。
- mode:该用户的防火墙强制执行模式:
- OFF:对该用户禁用防火墙,所有查询无过滤放行。
- DETECTING:防火墙按白名单和 SQL 注入指纹校验查询并记录违规,但不拦截流量。
- PROTECTING:防火墙校验查询,主动拦截未匹配活跃白名单规则或命中已知 SQL 注入指纹的查询。
- comment:自定义备注字段。
6. mysql_galera_hostgroups
用于定义 Galera 集群 / Percona XtraDB 集群对应的主机组,表中每一行代表一个集群及其所属主机组。
sql
CREATE TABLE mysql_galera_hostgroups (
writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL,
reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0),
offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0),
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1,
writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0,
max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0,
comment VARCHAR,
UNIQUE (reader_hostgroup),
UNIQUE (offline_hostgroup),
UNIQUE (backup_writer_hostgroup)
)
各字段含义:
- writer_hostgroup:默认接收所有流量的主机组,MySQL 中 read_only=0 的健康节点会分配至此。
- backup_writer_hostgroup:集群中 read_only=0 的节点数超过 max_writers 时,多余节点放入该主机组。
- reader_hostgroup:MySQL 中 read_only=1 的健康节点会分配至此。
- offline_hostgroup:不健康节点会移入该主机组,直至恢复健康。
- active:启用时 ProxySQL 监控主机组并在合适主机组间迁移服务器;禁用时则停止该集群的 Galera 监控,不做配置调整(即便主机组和服务器已在 mysql_servers 中配置)。
- max_writers:writer_hostgroup 允许的最大节点数,超出部分移入 backup_writer_hostgroup。
- writer_is_also_reader:控制节点是否同时加入 reader_hostgroup 和 writer_hostgroup。
- max_transactions_behind:节点落后集群的最大写入集数,超出则被屏蔽以避免脏读。
- comment:自定义备注字段。
有关如何配置 Galera 集群 / Percona XtraDB 集群的更多信息,请参阅 Galera 配置文档。
7. mysql_group_replication_hostgroups
用于定义 MySQL 组复制/InnoDB 集群对应的主机组。
sql
CREATE TABLE mysql_group_replication_hostgroups (
writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL,
reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0),
offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0),
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1,
writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0,
max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0,
comment VARCHAR,
UNIQUE (reader_hostgroup),
UNIQUE (offline_hostgroup),
UNIQUE (backup_writer_hostgroup)
)
各字段含义:
- writer_hostgroup:默认接收所有流量的主机组,MySQL 中 read_only=0 的节点会分配至此。
- backup_writer_hostgroup:集群中 read_only=0 的节点数超过 max_writers 时,多余节点放入该主机组。
- reader_hostgroup:读取流量应路由至此的主机组,需配置查询规则或只读用户;MySQL 中 read_only=1 的节点会分配至此。
- offline_hostgroup:ProxySQL 监控判定为离线或不健康的节点会移入该主机组。
- active:启用时 ProxySQL 监控主机组并在合适主机组间迁移节点。
- max_writers:writer_hostgroup 允许的最大节点数,超出部分移入 backup_writer_hostgroup。
- writer_is_also_reader:控制节点是否同时加入 reader_hostgroup 和 writer_hostgroup;特殊值 2 表示仅 backup_writer_hostgroup 节点加入读取组,排除 writer_hostgroup 节点。
- max_transactions_behind:节点落后写入节点的最大事务数,超出则被屏蔽以避免脏读(通过查询 MySQL 的 sys.gr_member_routing_candidate_status 表的 transactions_behind 字段判定)。
- comment:自定义备注字段。
ProxySQL 同样提供了若干用于监控组复制集群的配置变量,相关内容可查阅 mysql-monitor-variables 文档。
8. mysql_hostgroup_attributes
定义主机组专属设置,可覆盖对应主机组的全局配置,仅 ProxySQL 2.5 及以上版本可用。
sql
CREATE TABLE mysql_hostgroup_attributes (
hostgroup_id INT NOT NULL PRIMARY KEY,
max_num_online_servers INT CHECK (max_num_online_servers>=0 AND max_num_online_servers <= 1000000) NOT NULL DEFAULT 1000000,
autocommit INT CHECK (autocommit IN (-1, 0, 1)) NOT NULL DEFAULT -1,
free_connections_pct INT CHECK (free_connections_pct >= 0 AND free_connections_pct <= 100) NOT NULL DEFAULT 10,
init_connect VARCHAR NOT NULL DEFAULT '',
multiplex INT CHECK (multiplex IN (0, 1)) NOT NULL DEFAULT 1,
connection_warming INT CHECK (connection_warming IN (0, 1)) NOT NULL DEFAULT 0,
throttle_connections_per_sec INT CHECK (throttle_connections_per_sec >= 1 AND throttle_connections_per_sec <= 1000000) NOT NULL DEFAULT 1000000,
ignore_session_variables VARCHAR CHECK (JSON_VALID(ignore_session_variables) OR ignore_session_variables = '') NOT NULL DEFAULT '',
hostgroup_settings VARCHAR CHECK (JSON_VALID(hostgroup_settings) OR hostgroup_settings = '') NOT NULL DEFAULT '',
servers_defaults VARCHAR CHECK (JSON_VALID(servers_defaults) OR servers_defaults = '') NOT NULL DEFAULT '',
comment VARCHAR NOT NULL DEFAULT ''
)
各字段含义:
- hostgroup_id:应用以下列设置的主机组 ID。
- max_num_online_servers:超出指定 ONLINE 服务器数量时,主机组拒绝新连接,直至在线数低于阈值,可防范错误配置。
- autocommit:暂未实现。
- free_connections_pct:主机组内某台服务器最大连接数中,开放空闲连接的占比。
- init_connect:包含一条或多条 SQL 语句的字符串,分号分隔,ProxySQL 为该主机组的每个后端连接创建/初始化时执行。
- multiplex:该主机组的连接复用开关。
- connection_warming:控制该主机组是否持续新建连接直至达到预期预热连接数。
- throttle_connections_per_sec:该主机组每秒可新建的最大连接数。
- ignore_session_variables:暂未实现。
- hostgroup_settings:用于为主机组(hostgroup)指定配置项。若该配置项同时存在全局配置,则主机组级别的设置会覆盖全局配置。支持的取值:
- handle_warnings:与全局变量 mysql-handle_warnings 作用类似,支持与该全局设置相同的取值。
- monitor_slave_lag_when_null:与全局变量 mysql-monitor_slave_lag_when_null 作用类似,支持与该全局设置相同的取值。
- servers_defaults:指定 ProxySQL 监控模块发现并加入主机组的服务器默认值,支持 weight、max_connections、use_ssl。
- comment:自定义备注字段。
该表适用场景:
- 不同主机组的后端服务器版本不同。
- 不同主机组需要不同行为。
- 配合支持自动发现的 Aurora 或组复制集群使用。
第一种场景举例:可以创建一个由 MySQL 5.7 后端服务器组成的主机组,再创建另一个主机组配置 MySQL 8.0 后端(甚至是不同类型的数据库,例如一个主机组使用 MySQL,另一个使用 TiDB)。在这种情况下,可以通过调整 mysql_hostgroup_attributes 表中的 init_connect 字段,为不同主机组的后端设置要执行的不同类型 SQL 语句,从而让 ProxySQL 在与这些后端建立连接初始化时,为不同主机组设置不同的变量。
第二种场景举例:可能希望根据各主机组的业务负载,为不同主机组配置每秒可新建连接数(throttle_connections_per_sec);同时,也可以按主机组分别配置后端服务器上保留的空闲连接占比(free_connections_pct)。根据全局变量文档说明:"对于每个主机组 / 后端对,主机组管理器会在连接池中保留最多 mysql-free_connections_pct * mysql_servers.max_connections / 100 条连接"。
第三种场景举例:假设 ProxySQL 对接 AWS Aurora 集群,并且副本节点支持自动扩缩容。希望 ProxySQL 能将这些副本自动放入合适的主机组,同时还希望能自定义配置这些副本,而不是只使用 mysql_servers 表中的默认值。这一需求可以通过 servers_defaults 实现,例如:
sql
Admin> UPDATE mysql_hostgroup_attributes SET servers_defaults='{"weight":100,"max_connections":500,"use_ssl":1}' WHERE hostgroup_id=100;
Query OK, 0 rows affected (0.00 sec)
此后,被自动发现并加入主机组 100 的副本节点,将继承这里配置的默认参数。
9. mysql_query_rules
定义路由策略与属性。
sql
CREATE TABLE mysql_query_rules (
rule_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 0,
username VARCHAR,
schemaname VARCHAR,
flagIN INT CHECK (flagIN >= 0) NOT NULL DEFAULT 0,
client_addr VARCHAR,
proxy_addr VARCHAR,
proxy_port INT,
digest VARCHAR,
match_digest VARCHAR,
match_pattern VARCHAR,
negate_match_pattern INT CHECK (negate_match_pattern IN (0,1)) NOT NULL DEFAULT 0,
re_modifiers VARCHAR DEFAULT 'CASELESS',
flagOUT INT CHECK (flagOUT >= 0),
replace_pattern VARCHAR CHECK(CASE WHEN replace_pattern IS NULL THEN 1 WHEN replace_pattern IS NOT NULL AND match_pattern IS NOT NULL THEN 1 ELSE 0 END),
destination_hostgroup INT DEFAULT NULL,
cache_ttl INT CHECK(cache_ttl > 0),
cache_empty_result INT CHECK (cache_empty_result IN (0,1)) DEFAULT NULL,
cache_timeout INT CHECK(cache_timeout >= 0),
reconnect INT CHECK (reconnect IN (0,1)) DEFAULT NULL,
timeout INT UNSIGNED,
retries INT CHECK (retries>=0 AND retries <=1000),
delay INT UNSIGNED,
next_query_flagIN INT UNSIGNED,
mirror_flagOUT INT UNSIGNED,
mirror_hostgroup INT UNSIGNED,
error_msg VARCHAR,
OK_msg VARCHAR,
sticky_conn INT CHECK (sticky_conn IN (0,1)),
multiplex INT CHECK (multiplex IN (0,1,2)),
gtid_from_hostgroup INT UNSIGNED,
log INT CHECK (log IN (0,1)),
apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0,
attributes VARCHAR CHECK (JSON_VALID(attributes) OR attributes = '') NOT NULL DEFAULT '',
comment VARCHAR
)
各字段含义:
- rule_id:规则唯一标识,按 rule_id 顺序执行。
- active:仅 active=1 的规则会被查询处理模块识别并加载到运行时。
- username:按用户名过滤,非空时仅匹配对应用户的查询。
- schemaname:按库名过滤,非空时仅匹配对应默认库的查询。
- flagIN/flagOUT/apply:实现规则链式执行,初始 flagIN=0;匹配规则且设置 flagOUT 时,查询重新匹配对应 flagIN 的规则;匹配规则且 apply=1 时立即执行查询;无匹配则使用目标主机组或默认主机组。
- client_addr:按来源 IP 过滤。
- proxy_addr:按本地传入 IP 过滤。
- proxy_port:按本地传入端口过滤。
- digest:匹配指定查询摘要。
- match_digest:查询摘要正则匹配。
- match_pattern:查询文本正则匹配。
- negate_match_pattern:设为 1 时仅匹配不满足查询文本的查询。
- re_modifiers:正则引擎修饰符,CASELESS 不区分大小写,GLOBAL 全局替换。
- replace_pattern:替换匹配模式的内容,需配合 match_pattern 使用。
- destination_hostgroup:匹配查询路由至该主机组,事务开启且用户开启 transaction_persistent 时除外。
- cache_ttl:查询结果缓存时长(毫秒),1.1.x 版本为秒。
- cache_empty_result:是否缓存空结果集。
- cache_timeout:待实现。
- reconnect:未使用。
- timeout:查询执行最大超时(毫秒),超时自动终止。
- retries:查询执行失败时最大重试次数,未指定则使用全局 mysql-query_retries_on_failure。
- delay:查询执行延迟时长(毫秒),用于限流和服务质量控制。
- mirror_flagOUT/mirror_hostgroup:查询镜像相关设置。
- error_msg:拦截查询并返回指定错误信息。
- OK_msg:匹配规则的查询返回指定成功信息。
- sticky_conn:暂未实现。
- multiplex:0 禁用复用;1 无其他限制则启用;2 会话全程禁用复用。
- gtid_from_hostgroup:指定 GTID 一致性的主节点主机组。
- log:1 记录匹配查询到事件日志;0 不记录;NULL 遵循全局配置。
- apply:设为 1 时匹配并处理后不再校验后续规则。
- attributes:JSON 字段,配置查询规则的负载均衡。
- comment:规则描述备注。
负载均衡示例:
- 按端口将指定流量路由到不同主机组,使用 proxy_port 配合 attributes。
- 按比例分流测试规则,用 attributes 将 1% 匹配流量路由到指定主机组。
注意:切勿在用于捕获所有入站流量的第一条规则中设置 destination_hostgroup 或 apply 字段,否则会导致后续其他规则无法被匹配执行。
10. mysql_query_rules_fast_routing
mysql_query_rules 的扩展,用于快速路由策略与属性,在其后校验。
sql
CREATE TABLE mysql_query_rules_fast_routing (
username VARCHAR NOT NULL,
schemaname VARCHAR NOT NULL,
flagIN INT NOT NULL DEFAULT 0,
destination_hostgroup INT CHECK (destination_hostgroup >= 0) NOT NULL,
comment VARCHAR NOT NULL,
PRIMARY KEY (username, schemaname, flagIN)
)
各字段含义:
- username:按用户名过滤,仅匹配对应用户查询。
- schemaname:按库名过滤,仅匹配对应默认库查询。
- flagIN:与 mysql_query_rules 的 flagIN 逻辑一致,关联 flagOUT。
- destination_hostgroup:匹配查询路由至该主机组,事务开启且用户开启 transaction_persistent 时除外。
- comment:规则描述备注。
11. mysql_replication_hostgroups
用于定义传统主从异步/半同步复制的主机组;若使用组复制/InnoDB 集群或 Galera/Percona XtraDB 集群,应分别使用 mysql_group_replication_hostgroups 或 mysql_galera_hostgroups(2.x 版本)。
sql
CREATE TABLE mysql_replication_hostgroups (
writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>0),
check_type VARCHAR CHECK (LOWER(check_type) IN ('read_only','innodb_read_only','super_read_only','read_only|innodb_read_only','read_only&innodb_read_only')) NOT NULL DEFAULT 'read_only',
comment VARCHAR,
UNIQUE (reader_hostgroup)
)
表中每一行代表一对 writer_hostgroup 和 reader_hostgroup。ProxySQL 会监控指定主机组所有服务器的 check_type 变量,根据变量值(或双变量逻辑运算)将服务器分配到写入或读取主机组。
各字段含义:
- writer_hostgroup:写入节点所在主机组,只读检查返回 0 的节点分配至此。
- reader_hostgroup:读取节点所在主机组,读取流量应路由至此;只读检查返回 1 的节点分配至此。
- check_type:只读检查时校验的 MySQL 变量,支持逻辑运算,默认 read_only,也可使用 innodb_read_only、super_read_only。
- comment:自定义备注字段。
12. mysql_servers
定义所有后端服务器 MySQL 服务器或兼容 MySQL 协议的服务(如另一台 ProxySQL),服务器按主机组分组,主机组是功能相同的服务器集合。
sql
CREATE TABLE mysql_servers (
hostgroup_id INT CHECK (hostgroup_id>=0) NOT NULL DEFAULT 0,
hostname VARCHAR NOT NULL,
port INT CHECK (port >= 0 AND port <= 65535) NOT NULL DEFAULT 3306,
gtid_port INT CHECK ((gtid_port <> port OR gtid_port=0) AND gtid_port >= 0 AND gtid_port <= 65535) NOT NULL DEFAULT 0,
status VARCHAR CHECK (UPPER(status) IN ('ONLINE','SHUNNED','OFFLINE_SOFT', 'OFFLINE_HARD')) NOT NULL DEFAULT 'ONLINE',
weight INT CHECK (weight >= 0 AND weight <=10000000) NOT NULL DEFAULT 1,
compression INT CHECK (compression IN(0,1)) NOT NULL DEFAULT 0,
max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 1000,
max_replication_lag INT CHECK (max_replication_lag >= 0 AND max_replication_lag <= 126144000) NOT NULL DEFAULT 0,
use_ssl INT CHECK (use_ssl IN(0,1)) NOT NULL DEFAULT 0,
max_latency_ms INT UNSIGNED CHECK (max_latency_ms>=0) NOT NULL DEFAULT 0,
comment VARCHAR NOT NULL DEFAULT '',
PRIMARY KEY (hostgroup_id, hostname, port) )
各字段含义:
- hostgroup_id:后端服务器所属主机组,同一实例可属于多个主机组。
- hostname/port:后端服务器访问端点,port 为 0 时 hostname 视为 Unix Socket 路径。
- gtid_port:ProxySQL Binlog Reader 监听 GTID 跟踪的后端端口。
- status:服务器配置状态:
- ONLINE:正常运行。
- SHUNNED:短时间连接错误过多或复制延迟超阈值,临时禁用。
- OFFLINE_SOFT:拒绝新连接,保留现有连接至归还连接池或销毁,优雅下线。
- OFFLINE_HARD:拒绝新连接,立即释放空闲连接,等效从主机组删除。
- weight:服务器权重,权重越高被选中概率越大,默认随机加权负载均衡。
- compression:1 表示连接启用压缩。
- max_connections:ProxySQL 对该后端的最大连接数。
- max_replication_lag:大于 0 时定期监控复制延迟,超阈值临时屏蔽。
- use_ssl:1 表示后端连接使用 SSL。
- max_latency_ms:定期监控 ping 延迟,超阈值则从连接池排除(状态仍为 ONLINE)。
- comment:自定义备注字段。
注意:SHUNNED 节点恢复为 ONLINE,不仅需要节点可达,还需对应主机组连接池有活动。
13. mysql_servers_ssl_params
于 ProxySQL 2.6 引入,定义每台后端 MySQL 服务器专属 SSL 参数。
sql
CREATE TABLE mysql_servers_ssl_params (
hostname VARCHAR NOT NULL,
port INT CHECK (port >= 0 AND port <= 65535) NOT NULL DEFAULT 3306,
username VARCHAR NOT NULL DEFAULT '',
ssl_ca VARCHAR NOT NULL DEFAULT '',
ssl_cert VARCHAR NOT NULL DEFAULT '',
ssl_key VARCHAR NOT NULL DEFAULT '',
ssl_capath VARCHAR NOT NULL DEFAULT '',
ssl_crl VARCHAR NOT NULL DEFAULT '',
ssl_crlpath VARCHAR NOT NULL DEFAULT '',
ssl_cipher VARCHAR NOT NULL DEFAULT '',
tls_version VARCHAR NOT NULL DEFAULT '',
comment VARCHAR NOT NULL DEFAULT '',
PRIMARY KEY (hostname, port, username) )
各字段含义:
- hostname/port:后端服务器访问端点,port 为 0 时 hostname 视为 Unix Socket 路径。
- username:非空时仅适用于使用该用户的后端连接。
- ssl_ca:CA 证书文件路径。
- ssl_cert:客户端公钥证书文件路径。
- ssl_key:客户端私钥文件路径。
- ssl_capath:CA 证书目录路径。
- ssl_crl:证书吊销列表文件路径。
- ssl_crlpath:证书吊销列表目录路径。
- ssl_cipher:当前未使用。
- tls_version:当前未使用。
- comment:自定义备注字段。
在新建 MySQL 后端连接时,如果 mysql_servers.use_ssl 设为 1,则会建立 SSL 连接。在与后端建立 SSL 连接前,ProxySQL 会检查该后端是否在 mysql_servers_ssl_params 中配置,若已配置,则使用该表中指定的 SSL 参数。
具体而言,会对 mysql_servers_ssl_params 执行最多两次查找:
- 按 主机名 + 端口 + 用户名 查找
- 若不存在,则按 主机名 + 端口 查找
如果上述查找有结果,则使用 mysql_servers_ssl_params 中指定的 SSL 参数;若无结果,则使用默认 SSL 参数:
- mysql-ssl_p2s_ca
- mysql-ssl_p2s_capath
- mysql-ssl_p2s_cert
- mysql-ssl_p2s_key
- mysql-ssl_p2s_crl
- mysql-ssl_p2s_crlpath
注意:大多数列/配置项允许设为空字符串;此时建立 SSL 连接时将不使用该项配置。mysql_servers_ssl_params 表的配置属于 MYSQL SERVERS 模块,因此:
- 使用 LOAD MYSQL SERVERS TO RUNTIME 或等价命令加载到运行时。
- 使用 SAVE MYSQL SERVERS TO DISK 或等价命令保存到磁盘。
- 作为 mysql_servers 模块同步的一部分,在 ProxySQL 集群中自动复制。注意:仅同步 mysql_servers_ssl_params 表中的行记录,实际证书文件不会被复制(文件必须已存在于节点系统中)
如果 ProxySQL 无法打开 mysql_servers_ssl_params 中指定的文件,新建后端连接将会失败。常见失败原因:
- 文件不存在
- 路径错误
- 权限错误
- 证书无效
14. mysql_users
定义客户端连接 ProxySQL 及 ProxySQL 连接后端所用的 MySQL 用户。
sql
CREATE TABLE mysql_users (
username VARCHAR NOT NULL,
password VARCHAR,
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0,
default_hostgroup INT NOT NULL DEFAULT 0,
default_schema VARCHAR,
schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0,
transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1,
fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0,
backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1,
frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1,
max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000,
attributes VARCHAR CHECK (JSON_VALID(attributes) OR attributes = '') NOT NULL DEFAULT '',
comment VARCHAR NOT NULL DEFAULT '',
PRIMARY KEY (username, backend),
UNIQUE (username, frontend)
)
各字段含义:
- username/password:连接 MySQL 或 ProxySQL 的凭证。
- active:状态为 active = 0 的用户会在数据库中被保留记录,但不会加载到内存数据结构中。active = 0 等同于将该用户从内存数据结构中删除。
- use_ssl:1 表示用户必须使用 SSL 证书认证。
- default_hostgroup:用户查询无匹配规则时,流量路由至该主机组。
- default_schema:连接默认切换的库。
- schema_locked:暂未支持。
- transaction_persistent:开启后,事务内的查询始终留在当前主机组,不受其他规则影响。
- fast_forward:若启用该参数,将绕过查询处理层(查询重写、查询缓存),直接将 SQL 语句透传给后端数据库。此功能等效于使用 MySQL 代理,主要用于调试场景。使用时需注意以下说明:
- 无需独立端口。
- 按用户生效。
- 认证后启用。
- 2.4.6 版本起支持 SSL。
- 压缩需两端同时开启。
- frontend:1 表示该用户可用于客户端连接 ProxySQL。
- backend:1 表示该用户可用于 ProxySQL 连接后端 MySQL。
- max_connections:该用户允许的最大前端连接数。
- attributes:JSON 字段,用于存放该用户的额外配置参数。
- default-transaction_isolation:为此用户在后端连接中强制设置默认事务隔离级别。
- additional_password:允许为用户指定第二个密码,该功能在密码轮换场景下尤其实用。
- comment:自定义备注字段。
注意:当前所有用户需同时设置 frontend=1 和 backend=1,后续版本会分离;mysql_users 用户不应与 admin-admin_credentials、admin-stats_credentials 共用。