ProxySQL 2.7.3 配置参数详解
分类详解 ProxySQL 2.7.3 的 admin 接口、mysql_variables、mysql_servers、mysql_users、mysql_query_rules 与健康检查监控参数,并给出生产模板与 FAQ(已实测)
ProxySQL 2.7.3 配置参数详解
目标:分类拆解 ProxySQL 2.7.3 的核心配置——admin 接口、
mysql_variables、mysql_servers、mysql_users、mysql_query_rules、健康检查(Monitor)与性能/流量统计,并给出可直接上线的生产模板。本篇中的回显均已在 ProxySQL 2.7.3 上实测。
⚠️ 提醒:ProxySQL 本身不存业务数据,配置运行后请务必让后端 MySQL 数据可靠落盘(本文后端为 MySQL 8.0.46,
appdb库,proxyuser/monitor两账号)。
一、三层配置模型(理解 ProxySQL 的钥匙)
所有配置都存在 三层,修改需要按层推进:
| 层 | 说明 | 修改后命令 |
|---|---|---|
| RUNTIME | 当前生效的配置(内存) | LOAD ... TO RUNTIME |
| MEMORY | 已变更的“影子”配置 | UPDATE/INSERT ... (直接写的是 MEMORY 层) |
| DISK | 持久化到 /var/lib/proxysql/proxysql.db | SAVE ... TO DISK |
💡 说明:
INSERT/UPDATE只改 MEMORY;LOAD ... TO RUNTIME让配置立即生效;SAVE ... TO DISK固化,供进程重启后回放。三层命令按TABLES分类:MYSQL SERVERS / MYSQL USERS / MYSQL QUERY RULES / MYSQL VARIABLES / ADMIN VARIABLES / PROXYSQL SERVERS。
二、admin 接口参数(管理端口 6032)
admin_variables=
{
admin_credentials="admin:admin" # 管理账号(分号分隔多组;默认仅本机)
mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
}
| 参数 | 默认 | 说明 |
|---|---|---|
admin_credentials | admin:admin | 管理账号密码;user:pass(本机)或 user:pass:admin,多个用 ; 分隔 |
admin-stats_credentials | stats:stats | 只读统计账号(仅可看 stats/monitor) |
mysql_ifaces | 127.0.0.1:6032 | 管理监听:IP:port 或 ; 连接 Unix Socket |
admin_version | 2.7.3 | 版本(只读) |
-- 查看管理相关变量
SELECT variable_name, variable_value FROM global_variables
WHERE variable_name LIKE 'admin-%credentials%';
-- +------------------------+---------------------------+
-- | variable_name | variable_value |
-- +------------------------+---------------------------+
-- | admin-admin_credentials | admin:admin |
-- | admin-stats_credentials | stats:stats |
-- +------------------------+---------------------------+
⚠️ 注意:
admin默认仅允许来自本机的管理连接;远程管理需在admin-admin_credentials中显式授权或绑定非回环地址。生产建议:关闭远程 admin,走 SSH/堡垒机。
三、mysql_variables(运行行为)
mysql_variables=
{
threads=4 # 工作线程数
max_connections=4096 # ProxySQL 与客户端最大连接数
interfaces="0.0.0.0:6033" # 业务端口
default_schema="information_schema"
server_version="5.7.0" # 向客户端宣称的后端版本(做兼容钩子)
connect_timeout_server=3000 # 连接后端超时(ms)
monitor_username="monitor"
monitor_password="monitor"
monitor_connect_interval=60000
monitor_ping_interval=10000
monitor_read_only_interval=1500
monitor_read_only_timeout=500
ping_interval_server_msec=120000
ping_timeout_server=500
commands_stats=true # 开启命令分类统计
sessions_sort=true
connect_retries_on_failure=10
}
四、mysql_servers(后端服务器)
mysql_servers 描述后端 MySQL 与所属 hostgroup。hostgroup 是路由的最小单位:读写分离就是“写 SQL→写 hostgroup、读 SQL→读 hostgroup”。
INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight,max_connections,comment) VALUES
(10,'192.168.10.30',3306,1,100,'writer'),
(20,'192.168.10.31',3306,1,100,'reader');
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SELECT hostgroup_id,hostname,port,weight,status,max_connections,comment FROM mysql_servers;
-- +--------------+----------------+------+--------+--------+------------------+--------+
-- | hostgroup_id | hostname | port | weight | status | max_connections | comment|
-- +--------------+----------------+------+--------+--------+------------------+--------+
-- | 10 | 192.168.10.30 | 3306 | 1 | ONLINE | 100| writer |
-- | 20 | 192.168.10.31 | 3306 | 1 | ONLINE | 100| reader |
-- +--------------+----------------+------+--------+--------+------------------+--------+
| 字段 | 说明 |
|---|---|
hostgroup_id | 后端所属 hostgroup(0-1e9) |
hostname/port | 后端地址 |
weight | 权重(越大分配越多连接) |
status | ONLINE/OFFLINE_SOFT/OFFLINE_HARD/SHUNNED/OFFLINE |
max_connections | ProxySQL 向后端建立的连接上限 |
max_replication_lag | 超过该主从延迟值则临时剔除 |
💡 说明:通过
mysql_replication_hostgroups定义{writer_hostgroup, reader_hostgroup},ProxySQL 会自动把read_only=ON的从库判为 reader,见集群篇。
五、mysql_users(代理接入账号)
接入 6033 的客户端凭 mysql_users 认证,且该账号必须真实存在于后端 MySQL(ProxySQL 提供“解密密码到后端认证”能力)。default_hostgroup 是未命中任何查询规则时的默认落库组。
INSERT INTO mysql_users(username,password,default_hostgroup,max_connections)
VALUES ('proxyuser','ProxyPass2024',10,100);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
SELECT username,default_hostgroup,max_connections,active FROM mysql_users;
-- +-----------+------------------+------------------+--------+
-- | username | default_hostgroup| max_connections | active |
-- +-----------+------------------+------------------+--------+
-- | proxyuser | 10 | 100 | 1 |
-- +-----------+------------------+------------------+--------+
| 字段 | 说明 |
|---|---|
username / password | 客户端连 6033 时使用的账号密码 |
default_hostgroup | 无规则命中时的默认 hostgroup |
use_ssl | 后端连接是否加密 |
max_connections | 该账号最大同时连接数 |
active | 是否启用 |
transaction_persistent | 事务内是否固定同一连接(推荐 1,避免中途换后端破坏事务语义) |
💡 说明:密码以加密哈希形式存于 SQLite;修改后必须
LOAD MYSQL USERS TO RUNTIME才对后端认证生效。
六、mysql_query_rules(查询路由,核心中的核心)
规则按 rule_id 从小到大匹配,active=1 才生效,apply=1 表示命中后停止继续匹配。读写分离 2.7.3 的典型规则:
INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply,comment) VALUES
(1,1,'^SELECT .* FOR UPDATE',10,1,'写/加锁查询->主库'),
(2,1,'^SELECT',20,1,'读查询->从库');
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
SELECT rule_id,active,match_pattern,destination_hostgroup,apply FROM mysql_query_rules ORDER BY rule_id;
-- +---------+--------+--------------------------+----------------------+-------+
-- | rule_id | active | match_pattern | destination_hostgroup | apply |
-- +---------+--------+--------------------------+----------------------+-------+
-- | 1 | 1 | ^SELECT .* FOR UPDATE | 10 | 1 |
-- | 2 | 1 | ^SELECT | 20 | 1 |
-- +---------+--------+--------------------------+----------------------+-------+
| 字段 | 说明 |
|---|---|
match_pattern/negate_match_pattern | 正则(^ 锚定开头);命中与否 |
match_digest | 按 SQL 摘要(digest)匹配 |
destination_hostgroup | 命中后路由到的 hostgroup |
mirror_hostgroup | 镜像(影子)执行到另一组 |
cache_ttl | 命中查询的结果缓存秒数 |
apply | 命中后是否停止后续规则 |
timeout | 该规则下查询超时(ms) |
comment | 注释 |
💡 说明:规则字段非常丰富(含
schemaname、client_addr、flagIN/flagOUT级联、multiplex、account、server_capabilities等),可做更细颗粒分流。
七、健康检查(Monitor 模块)
ProxySQL 持续对每个后端进行 connect/ping/read_only 探测,把状态写到 monitor.* 表;SHUNNED 即由失误探测触发。需在 mysql_variables 配置 monitor_username/password,并让该账号在后端有 SELECT, REPLICATION CLIENT 权限,方可正确抓取并识别只读从库。
| 表 | 用途 | 关键列 |
|---|---|---|
monitor.mysql_server_connect_log | 连接耗时 | connect_success_time_us, connect_error |
monitor.mysql_server_ping_log | ping 延时 | ping_success_time_us |
monitor.mysql_server_read_only_log | 只读探测 | read_only |
monitor.mysql_server_replication_lag_log | 主从延迟 | time_start_us |
实测回显(探测成功,connect_error 为 NULL,表示健康):
SELECT hostname,port,connect_success_time_us,connect_error
FROM monitor.mysql_server_connect_log
ORDER BY time_start_us DESC LIMIT 2;
-- +----------------+------+----------------------+--------------+
-- | hostname | port | connect_success_time_us| connect_error|
-- +----------------+------+----------------------+--------------+
-- | 192.168.10.30 | 3306 | 1050 | NULL |
-- | 192.168.10.31 | 3306 | 1140 | NULL |
-- +----------------+------+----------------------+--------------+
SELECT hostname,port,ping_success_time_us,ping_error
FROM monitor.mysql_server_ping_log
ORDER BY time_start_us DESC LIMIT 2;
-- +----------------+------+--------------------+-----------+
-- | hostname | port | ping_success_time_us| ping_error|
-- +----------------+------+--------------------+-----------+
-- | 192.168.10.30 | 3306 | 202 | NULL |
-- | 192.168.10.31 | 3306 | 292 | NULL |
-- +----------------+------+--------------------+-----------+
⚠️ 注意:若 monitor 账号缺失或密码错误,
connect_error会记录Access denied for user 'monitor'且后端可能被SHUNNED;请为每个后端都创建 monitor 账号并授权。
八、连接池与流量统计(判断是否在路由)
SELECT hostgroup,srv_host,srv_port,status,ConnUsed,ConnFree,ConnOK,ConnERR,Queries,Latency_us
FROM stats_mysql_connection_pool;
-- +-----------+----------------+---------+--------+---------+---------+-------+-------+---------+------------+
-- | hostgroup | srv_host | srv_port| status | ConnUsed| ConnFree|ConnOK|ConnERR| Queries | Latency_us |
-- +-----------+----------------+---------+--------+---------+---------+-------+-------+---------+------------+
-- | 10 | 192.168.10.30 | 3306 | ONLINE | 0 | 1 | 1| 0 | 5 | 0 |
-- | 20 | 192.168.10.31 | 3306 | ONLINE | 0 | 1 | 1| 0 | 4 | 0 |
-- +-----------+----------------+---------+--------+---------+---------+-------+-------+---------+------------+
命令统计(验证读写命令分布):
SELECT Command,Total_Time_us,Total_cnt FROM stats_mysql_commands_counters WHERE Total_cnt>0;
-- +---------+--------------+-----------+
-- | Command | Total_Time_us| Total_cnt |
-- +---------+--------------+-----------+
-- | INSERT | 9938 | 3 |
-- | SELECT | 18036 | 6 |
-- +---------+--------------+-----------+
全量回显(含列名)亦可通过 SELECT * FROM stats_mysql_query_digest 按 digest 统计 SQL。
九、生产模板(一步提交)
-- 1) 后端组
INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight,comment) VALUES
(10,'192.168.10.30',3306,1,'writer'),
(20,'192.168.10.31',3306,1,'reader');
LOAD MYSQL SERVERS TO RUNTIME;
-- 2) 账号
INSERT INTO mysql_users(username,password,default_hostgroup,transaction_persistent) VALUES
('proxyuser','ProxyPass2024',10,1);
LOAD MYSQL USERS TO RUNTIME;
-- 3) 规则
INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply,comment) VALUES
(1,1,'^SELECT .* FOR UPDATE',10,1,'write'),
(2,1,'^SELECT',20,1,'read');
LOAD MYSQL QUERY RULES TO RUNTIME;
-- 4) 固化到磁盘
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;
SAVE MYSQL VARIABLES TO DISK;
SAVE ADMIN VARIABLES TO DISK;
验证读写分离(命中不同 hostgroup):
mysql -uproxyuser -pProxyPass2024 -h127.0.0.1 -P6033 -e "SELECT node FROM appdb.nodeinfo;"
# READER-NODE ← 从库
mysql -uproxyuser -pProxyPass2024 -h127.0.0.1 -P6033 -e "SELECT node FROM appdb.nodeinfo FOR UPDATE;"
# WRITER-NODE ← 主库
常见问题(FAQ)
| 问题 | 说明/解决 |
|---|---|
| 改了 mysql_servers 不生效 | 未 LOAD MYSQL SERVERS TO RUNTIME |
| 重启后配置回默认 | MEMORY 层未 SAVE ... TO DISK |
后端全部 SHUNNED | monitor 账号/权限缺失或后端不可达,查 monitor.* 日志 |
| 写操作跑到从库 | 规则漏了 FOR UPDATE/写类型;把规则放最前并 apply=1 |
| 事务中途换后端 | 客户端 transaction_persistent=1 |
stats 账号连不上 | 用 stats:stats 而非 admin 凭据 |
| 需要限流/缓存 | 用规则 cache_ttl、timeout、mirror_hostgroup |
参考链接
- admin 接口:https://proxysql.com/documentation/global-variables/admin-variables/
- mysql_servers / mysql_users / mysql_query_rules:https://proxysql.com/documentation/
- Monitor 模块:https://proxysql.com/documentation/monitor-module/