proxysql 无法直接实现事务级并发限流,需通过专用账号配置 max_connections 并配合应用层控制事务连接;必须执行 load mysql users to runtime 生效,且应优先利用 mysql 的 max_user_connections 从源头限制。

ProxySQL 的 mysql-users 表里怎么配事务级并发限流
ProxySQL 本身不直接限制“事务并发数”,它只对连接、语句或用户维度做限流。想控制事务数量,得把事务特征转化成 ProxySQL 能识别的模式——比如靠 transaction_begin 关键字匹配 + 用户级 max_connections 或 max_connections_per_user 配合使用。
常见错误是直接在 mysql_query_rules 里对 BEGIN 做限流,结果发现没用:因为 ProxySQL 默认不解析事务状态,BEGIN 只是一条普通语句,且后续的 COMMIT/ROLLBACK 不会触发规则重匹配。
- 真正可行的做法:给发起事务的用户单独建账号(如
app_txn_user),在mysql-users表中设max_connections = 10,再配合应用层确保每个事务用独立连接(避免连接复用掩盖并发) - 如果业务已用连接池(如 HikariCP),必须关掉
auto-commit=true并显式BEGIN,否则 ProxySQL 看不到事务上下文 -
max_connections_per_user是运行时生效的配置,需执行LOAD MYSQL USERS TO RUNTIME,否则改了表也不起作用
为什么不能靠 mysql-query-rules 匹配 BEGIN 实现事务限流
ProxySQL 的查询规则是单语句匹配,不具备事务生命周期感知能力。一个事务可能跨多条语句(BEGIN → 若干 UPDATE → COMMIT),而 ProxySQL 对每条语句独立判断,无法标记“这条 UPDATE 属于哪个尚未结束的事务”。
典型错误现象:mysql-query-rules 中加了 match_pattern='^BEGIN' + apply=1 + sticky_conn=1,但压测时仍出现上百并发事务——因为规则只拦了 BEGIN,拦不住后续语句,连接也未被真正阻塞。
- 匹配
BEGIN后设置destination_hostgroup到一个空 hostgroup,会导致语句失败,这不是限流,是中断 - 想靠
sticky_conn=1绑定事务到连接?它只保证同 session 后续语句发往同一 backend,不控制并发数 - MySQL 8.0+ 的
transaction_info状态变量 ProxySQL 拿不到,没法做条件路由
替代方案:用 MySQL 自身的 max_connections 和应用层协作
比强扭 ProxySQL 更稳的方式,是让 MySQL 实例层承担连接上限压力,再由应用控制事务粒度。ProxySQL 在这里只做路由和透明代理,不越位做事务调度。
场景举例:支付核心服务需要严格控制并发事务数 ≤ 50,但数据库实例允许 500 连接。这时不该让 ProxySQL “猜”哪些连接在跑事务,而是让应用用专用账号 pay_txn 连接,并在 MySQL 侧设 max_user_connections = 50。
- 执行
ALTER USER 'pay_txn'@'%' WITH MAX_USER_CONNECTIONS 50,该限制对事务/非事务连接一视同仁,但恰好卡住了并发事务的源头 - ProxySQL 可在此基础上加一层
mysql-users的default_hostgroup隔离,防止误连其他库 - 注意:MySQL 的
max_user_connections不影响 SUPER 权限用户,测试时别用 root 验证 - 若应用用了连接池,需调小
maximumPoolSize并开启connection-test-query='SELECT 1',避免空闲连接占满限额
容易被忽略的 ProxySQL 配置细节
很多人改完 mysql-users 就以为生效了,结果压测发现完全没限制——大概率卡在几个硬性步骤上。
- 必须执行
LOAD MYSQL USERS TO RUNTIME,仅INSERT INTO mysql-users不生效 - ProxySQL 启动时不会自动加载
mysql-users,首次配置后要SAVE MYSQL USERS TO DISK -
max_connections是针对“当前 ProxySQL 实例能转发给后端的连接总数”,不是单个后端节点;如果配了多个 MySQL 节点,这个值是全局共享的 - 查实时连接数用
SELECT * FROM stats_mysql_connection_pool,别只看SHOW PROCESSLIST,后者只反映 MySQL 侧,看不到 ProxySQL 持有的空闲连接
事务并发控制本质是应用、连接池、代理、数据库四层协同的事,ProxySQL 只负责其中一环。指望它单点解决,反而容易绕进状态同步和超时判断的坑里。











