14.4.5 连接复用与事务一致性处理
连接复用是ProxySQL提升吞吐的关键机制,通过后端连接池将前端会话与后端连接解耦,降低握手与认证开销;核心前提是事务内语义一致性与会话状态隔离,避免跨会话污染与路由漂移。
原理草图(连接复用与事务绑定)
复用机制与工作流程
- 前端连接建立后,ProxySQL按规则选择后端连接池中的可用连接进行绑定与复用。
- 会话结束或空闲时,后端连接回归连接池,等待下次复用。
- 复用前执行会话清理与状态重置,确保前后会话互不影响。
事务一致性保障要点
- 事务绑定:检测到BEGIN/START TRANSACTION后,前端连接被绑定到固定后端连接,直到COMMIT/ROLLBACK。
- 读写一致性:事务内所有SQL保持同一后端连接,避免读写分离导致的数据不一致。
- 会话变量隔离:处理SET、USE、SET NAMES等会话级命令,事务结束或连接回收时清理。
关键配置示例(连接复用与事务一致性)
-- 连接ProxySQL管理端
mysql -u admin -padmin -h 127.0.0.1 -P6032
-- 设置连接池与超时(数值可按业务调整)
UPDATE global_variables SET variable_value='200' WHERE variable_name='mysql-connection_pool_size';
UPDATE global_variables SET variable_value='10' WHERE variable_name='mysql-connect_timeout_server';
UPDATE global_variables SET variable_value='10' WHERE variable_name='mysql-default_query_timeout';
UPDATE global_variables SET variable_value='1' WHERE variable_name='mysql-enable_client_deprecate_eof';
-- 事务一致性:事务内不进行读写漂移
UPDATE mysql_query_rules SET apply=1 WHERE rule_id=1000; -- 假设已有规则
INSERT INTO mysql_query_rules (rule_id,active,match_pattern,flagIN,flagOUT,apply)
VALUES (2000,1,'^BEGIN|^START TRANSACTION',0,1,1);
INSERT INTO mysql_query_rules (rule_id,active,match_pattern,flagIN,flagOUT,apply)
VALUES (2001,1,'^COMMIT|^ROLLBACK',1,0,1);
LOAD MYSQL VARIABLES TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
SAVE MYSQL QUERY RULES TO DISK;
命令解释
- mysql-connection_pool_size:后端连接池大小,过小影响并发,过大占用资源。
- mysql-default_query_timeout:单条查询超时,防止长查询拖垮复用。
- 事务规则通过flagIN/flagOUT锁定事务语句在同一后端连接执行。
会话清理与复用验证示例
-- 模拟会话变量污染
mysql -u app -papp -h 127.0.0.1 -P6033
SET @x=1;
USE db1;
BEGIN;
SELECT * FROM t1 FOR UPDATE;
ROLLBACK;
-- 查看后端连接复用与状态
SELECT hostgroup_id, srv_host, srv_port, ConnUsed, ConnFree
FROM stats_mysql_connection_pool;
预期效果
- 事务内ConnUsed增加并保持绑定,事务结束后回落。
- ConnFree在无长事务情况下稳定增长,表示复用正常。
常见影响复用的场景
- 长事务或未提交事务导致连接长期占用,降低复用率。
- 大量会话级状态(临时表、用户变量、锁)增加清理成本。
- 使用SELECT ... FOR UPDATE等加锁语句,影响连接释放时机。
排错与验证思路(含命令)
-- 1) 查看事务阻塞或长事务
SELECT * FROM stats_mysql_processlist WHERE Command='Sleep' OR Time>30;
-- 2) 检查后端连接占用
SELECT hostgroup_id, ConnUsed, ConnFree, MaxConnUsed
FROM stats_mysql_connection_pool;
-- 3) 审计事务开始与结束
SELECT * FROM stats_mysql_query_digest
WHERE digest_text LIKE 'BEGIN%' OR digest_text LIKE 'COMMIT%' OR digest_text LIKE 'ROLLBACK%';
-- 4) 检查是否存在会话变量或临时表污染
SELECT * FROM stats_mysql_global WHERE Variable_name LIKE 'Conn%';
故障定位要点
- ConnUsed长期高企:多为长事务、未提交或锁等待。
- 事务日志不成对:应用未显式提交,需排查业务代码。
- 规则缺失:事务语句未被固定路由,导致跨实例漂移。
练习
1. 配置连接池大小为100,压测50并发,观察ConnUsed/ConnFree变化并截图记录。
2. 构造一个未提交事务,观察连接池占用与恢复过程,写出恢复步骤。
3. 新增一条事务规则,确保SELECT ... FOR UPDATE只走主库,验证读写一致性。