影评周公子 2026-02-25 21:50 采纳率: 99%
浏览 2
已采纳

如何查看MySQL当前活跃连接数及最大连接数配置?

在MySQL运维中,常需实时掌握数据库连接负载情况:如何准确查看当前活跃连接数(即正在执行请求的线程数),以及系统允许的最大连接数配置(max_connections)?尤其当应用出现“Too many connections”错误或响应延迟升高时,需快速判断是否触及连接上限。但实践中易混淆`Threads_connected`(已建立连接数)、`Threads_running`(活跃执行中的线程数)与`Threads_created`等状态变量;同时,`max_connections`可能被动态修改却未持久化,导致重启后失效。此外,部分用户误将`show processlist`结果行数等同于活跃连接,却忽略了Sleep状态连接的实际影响。那么,应使用哪些权威、精准且可复现的SQL命令或系统视图,在不同MySQL版本(5.7/8.0+)下安全获取这两项关键指标?
  • 写回答

1条回答 默认 最新

  • kylin小鸡内裤 2026-02-25 21:50
    关注
    ```html

    一、基础指标辨析:Threads_connected vs Threads_running vs Threads_created

    在MySQL状态变量中,Threads_connected表示当前已建立的TCP连接总数(含Sleep/Query/Init等所有状态),而Threads_running才是真正的“活跃连接数”——即正在执行SQL、持有锁、处于非空闲状态的线程(状态为QueryUpdatingSending data等)。Threads_created则累计自启动以来新创建的线程数,用于判断连接池复用效率。混淆三者将导致误判负载真实水位。

    二、权威命令获取:跨版本兼容的精准查询语句

    • MySQL 5.7+ & 8.0+:统一使用 SHOW GLOBAL STATUS LIKE 'Threads_%' 获取实时状态值;
    • 推荐单行精准查询(避免冗余输出):
      SELECT VARIABLE_VALUE AS threads_connected FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Threads_connected';
    • 双指标原子化获取(防竞态):
      SELECT (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Threads_running') AS active_threads, (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Threads_connected') AS total_connections, (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='max_connections') AS max_connections;

    三、max_connections 的持久化验证:动态值 ≠ 配置值

    检查维度命令/视图说明
    当前生效值SHOW VARIABLES LIKE 'max_connections';返回运行时值(可能由SET GLOBAL修改)
    配置文件原始值SELECT * FROM performance_schema.variables_info WHERE VARIABLE_NAME = 'max_connections' AND SOURCE NOT IN ('COMMIT', 'DYNAMIC');MySQL 8.0+ 支持溯源,SOURCE='CONFIG' 表示来自my.cnf
    是否已持久化SELECT * FROM performance_schema.persisted_variables WHERE VARIABLE_NAME = 'max_connections';仅MySQL 8.0.21+支持PERSIST,存在记录即代表重启不丢失

    四、Processlist 的深度解读:为何不能直接用 COUNT(*) 替代 Threads_running

    执行 SHOW FULL PROCESSLIST 或查询 information_schema.PROCESSLIST 时,需过滤 Command != 'Sleep' 才能逼近真实活跃连接。但注意:部分长期Sleep连接(如连接池保活)可能占用资源却不计入Threads_running;而某些短时Query状态线程可能因锁等待被阻塞,虽属Threads_running却无实际吞吐。因此,Threads_running是更可靠的瞬时并发度指标。

    五、高可用场景增强监控:结合Performance Schema定位连接瓶颈

    -- MySQL 8.0+ 推荐:识别TOP5阻塞型活跃会话(含等待事件)
    SELECT 
      p.ID, p.USER, p.HOST, p.DB, p.COMMAND, p.TIME, p.STATE,
      e.EVENT_NAME, e.WAIT_TIME, e.SOURCE
    FROM performance_schema.threads t
    JOIN information_schema.PROCESSLIST p ON t.PROCESSLIST_ID = p.ID
    LEFT JOIN performance_schema.events_waits_current e ON t.THREAD_ID = e.THREAD_ID
    WHERE p.COMMAND != 'Sleep' AND e.EVENT_NAME IS NOT NULL
    ORDER BY e.WAIT_TIME DESC LIMIT 5;

    六、运维SOP流程图:连接异常响应标准化路径

    graph TD A[收到 “Too many connections” 报警] --> B{检查 Threads_connected ≥ max_connections?} B -- 是 --> C[立即执行 SHOW PROCESSLIST WHERE Command!='Sleep'] B -- 否 --> D[排查应用连接泄漏或未close] C --> E[Kill 非关键 Sleep 连接 or 调整 wait_timeout] E --> F[验证 Threads_connected 是否回落] F -- 是 --> G[检查 max_connections 是否PERSISTED] G --> H[若否,追加 PERSIST 指令并同步配置文件] H --> I[完成闭环]

    七、版本差异与兼容性清单

    • MySQL 5.7:不支持 performance_schema.persisted_variablesvariables_info.SOURCE,需人工比对 my.cnfSHOW VARIABLES
    • MySQL 8.0.3+:默认启用 performance_schema,且 threads 表包含 PROCESSLIST_* 字段,替代旧式 information_schema.PROCESSLIST
    • MySQL 8.0.16+:引入 connection_control_failed_connections_threshold 可辅助识别暴力连接攻击导致的连接耗尽。

    八、生产环境最佳实践建议

    建议在Zabbix/Prometheus中采集以下4个核心指标构建连接健康看板:
    mysql_global_status_threads_connected(趋势告警阈值≥90% max_connections);
    mysql_global_status_threads_running(突增3倍基线触发SQL慢日志审计);
    mysql_global_variables_max_connections(变更自动触发CMDB同步);
    mysql_info_schema_processlist_count_where_command_sleep(评估连接池配置合理性)。

    九、典型误操作案例复盘

    某金融系统凌晨批量作业期间出现大量“Too many connections”,运维人员执行 KILL 后迅速恢复,但次日重现。根因分析发现:
    - 应用层HikariCP配置 maximumPoolSize=100,但MySQL max_connections=150
    - 因事务超时未正确rollback,导致127个连接长期卡在Rolling back状态(属Threads_running);
    - SHOW PROCESSLIST 中Sleep连接仅占32%,误判为“连接未打满”,实则活跃线程已饱和CPU与IO。

    十、一键诊断脚本(兼容5.7/8.0+)

    -- 安全、幂等、无副作用的连接健康快照
    SELECT 
      'CURRENT_STATUS' AS metric_type,
      VARIABLE_NAME AS name,
      VARIABLE_VALUE AS value
    FROM performance_schema.global_status 
    WHERE VARIABLE_NAME IN ('Threads_connected', 'Threads_running', 'Threads_created', 'Aborted_connects')
    UNION ALL
    SELECT 
      'CONFIGURATION' AS metric_type,
      VARIABLE_NAME AS name,
      VARIABLE_VALUE AS value
    FROM performance_schema.global_variables 
    WHERE VARIABLE_NAME = 'max_connections'
    UNION ALL
    SELECT 
      'PERSISTENCE' AS metric_type,
      'max_connections_persisted' AS name,
      IFNULL((SELECT VARIABLE_VALUE FROM performance_schema.persisted_variables WHERE VARIABLE_NAME='max_connections'), 'NOT_PERSISTED') AS value;
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 2月26日
  • 创建了问题 2月25日