14.4.1 连接池与会话生命周期管理
连接池是 ProxySQL 提升吞吐与稳定性的核心机制,前端接入连接与后端 MySQL 连接解耦,减少频繁建连/断连开销。会话生命周期从前端连接建立开始,经路由分配后端连接,执行查询、保持或释放,再回收至连接池以供复用。
原理草图(连接池与会话生命周期)
连接池基础概念
- 前端连接:客户端到 ProxySQL 的连接,负责认证、规则匹配与会话状态。
- 后端连接:ProxySQL 到 MySQL 实例的连接,按 HostGroup 维护连接池。
- 连接复用:空闲后端连接回到池中,复用避免重复握手与认证。
- 连接状态:空闲、使用中、阻塞、需重连或标记失败。
生命周期关键阶段
1. 建立:客户端连接到 ProxySQL,完成用户认证与规则匹配。
2. 分配:根据路由规则与主机组状态分配后端连接。
3. 执行:执行 SQL,记录统计与延迟指标。
4. 释放:事务结束或语句完成,后端连接返回池中。
5. 回收:空闲超时或超过最大存活时间触发销毁重建。
核心参数与行为(含解释)
-- 查看当前连接相关变量
SELECT variable_name, variable_value
FROM global_variables
WHERE variable_name IN (
'mysql-max_connections',
'mysql-max_connections_per_server',
'mysql-connection_idle_timeout',
'mysql-connection_max_age_ms',
'mysql-ping_interval_server_msec',
'mysql-ping_timeout_server'
);
-- 参数解释:
-- mysql-max_connections: 前端最大连接数
-- mysql-max_connections_per_server: 单后端实例最大连接数
-- mysql-connection_idle_timeout: 后端连接空闲多久回收(秒)
-- mysql-connection_max_age_ms: 后端连接最大存活时间(毫秒)
-- mysql-ping_interval_server_msec: 后端健康检查间隔(毫秒)
-- mysql-ping_timeout_server: 后端健康检查超时(秒)
安装与基础验证示例
# Ubuntu/Debian 安装 ProxySQL
sudo apt-get update
sudo apt-get install -y proxysql
# 启动与状态检查
sudo systemctl enable --now proxysql
sudo systemctl status proxysql
# 连接管理端口(默认 6032)
mysql -u admin -padmin -h 127.0.0.1 -P 6032 -e "SELECT @@version;"
预期效果:返回 ProxySQL 版本信息,说明管理端口可用。
配置连接池与会话生命周期示例
-- 连接到 ProxySQL 管理端口 6032
-- 1) 调整连接相关变量
UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-max_connections';
UPDATE global_variables SET variable_value='200' WHERE variable_name='mysql-max_connections_per_server';
UPDATE global_variables SET variable_value='30' WHERE variable_name='mysql-connection_idle_timeout';
UPDATE global_variables SET variable_value='600000' WHERE variable_name='mysql-connection_max_age_ms';
-- 2) 生效并持久化
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
-- 3) 查看生效情况
SELECT variable_name, variable_value
FROM runtime_global_variables
WHERE variable_name IN ('mysql-max_connections','mysql-max_connections_per_server',
'mysql-connection_idle_timeout','mysql-connection_max_age_ms');
预期效果:运行时变量与配置一致,后端连接在空闲 30 秒后回收,最长 10 分钟重建。
连接池统计与命令解释
-- 查看连接池健康与统计(每个 HostGroup/Server 的连接状态)
SELECT hostgroup, srv_host, srv_port, status, ConnUsed, ConnFree, ConnOK, ConnERR
FROM stats_mysql_connection_pool;
-- ConnUsed: 使用中的后端连接数
-- ConnFree: 空闲后端连接数
-- ConnOK: 建连成功次数
-- ConnERR: 建连失败次数
会话一致性与事务处理示例
-- 客户端侧示例:事务期间绑定后端连接
BEGIN;
SELECT * FROM orders WHERE id=1 FOR UPDATE;
UPDATE orders SET status='paid' WHERE id=1;
COMMIT;
-- 说明:
-- 事务内固定后端连接,避免跨连接导致会话状态丢失
-- 读写分离时需确保事务内路由到主库
排错要点与命令
-- 1) 后端连接耗尽排查
SELECT hostgroup, srv_host, ConnUsed, ConnFree
FROM stats_mysql_connection_pool
ORDER BY ConnUsed DESC;
-- 2) 观察前端连接数
SHOW VARIABLES LIKE 'mysql-max_connections';
SELECT * FROM stats_mysql_global WHERE variable_name='Client_Connections_created';
-- 3) 检查连接泄漏(长时间不释放)
SELECT * FROM stats_mysql_processlist WHERE time > 60;
-- 4) 后端不可达排查
SELECT hostgroup, srv_host, status, ConnERR
FROM stats_mysql_connection_pool
WHERE status <> 'ONLINE';
常见原因:后端实例不可达、慢查询导致连接长时间占用、事务未提交或客户端断开未正确清理。
演练练习
1. 将 mysql-connection_idle_timeout 设置为 10 秒,制造空闲连接回收现象,观察 ConnFree 变化。
2. 压测创建 500 并发短连接(如 mysqlslap),记录 ConnUsed 峰值与 ConnFree 变化。
3. 故意将后端 MySQL 停止,观察 ConnERR 增长,并恢复后验证连接池自动恢复。
示例脚本:短连接压测与观察
# 安装 mysqlslap(以 MySQL 客户端包为例)
sudo apt-get install -y mysql-client
# 运行短连接压测
mysqlslap -h 127.0.0.1 -P 6033 -u appuser -p'pass' \
--concurrency=200 --iterations=5 --query="SELECT 1"
# 观察连接池变化
mysql -u admin -padmin -h 127.0.0.1 -P 6032 \
-e "SELECT hostgroup, srv_host, ConnUsed, ConnFree FROM stats_mysql_connection_pool;"
运维建议
- 规划前端连接与后端连接比例,避免后端连接池耗尽导致排队。
- 对高并发短连接,提升连接池上限并缩短空闲回收时间。
- 对长事务与慢查询,适当增大后端连接数并优化 SQL。
- 变更参数后务必执行 LOAD MYSQL VARIABLES TO RUNTIME 与 SAVE MYSQL VARIABLES TO DISK。