我的日常开发记录日志
首页
  • Laravel
  • Thinkphp
  • Swoole
  • Workman
  • php
  • HTML
  • CSS
  • JavaScript
  • Vue
  • ES6
  • 小程序
  • Mysql
  • Redis
  • Es
  • MongoDb
  • Git
  • Composer
  • Linux
  • Nginx
  • Docker
  • Vpn
  • 开发实战
  • 开发工具类
  • 友情链接
💖关于
💻收藏
  • 分类
  • 标签
  • 归档数据
GitHub (opens new window)

我的日常开发记录日志

never give up
首页
  • Laravel
  • Thinkphp
  • Swoole
  • Workman
  • php
  • HTML
  • CSS
  • JavaScript
  • Vue
  • ES6
  • 小程序
  • Mysql
  • Redis
  • Es
  • MongoDb
  • Git
  • Composer
  • Linux
  • Nginx
  • Docker
  • Vpn
  • 开发实战
  • 开发工具类
  • 友情链接
💖关于
💻收藏
  • 分类
  • 标签
  • 归档数据
GitHub (opens new window)
  • mysql

    • Mysql
    • 哈希分表
    • 严格模式
    • 单表数据过大的解决方案
    • 分表分库带来的新问题
    • 数据容量查询
    • 海量数据生成和删除
    • mysql编辑的sql
    • showprocess用法
    • redis

    • mongodb

    • es

    • 数据库
    • mysql
    窝窝侠
    2025-04-29

    showprocess用法

    # MySQL的SHOW FULL PROCESSLIST命令终极详解:从入门到实战

    在MySQL数据库管理中,实时监控连接状态和查询执行情况是优化性能、排查问题的核心技能。SHOW FULL PROCESSLIST命令是这一领域的“瑞士军刀”,但许多开发者仅停留在基础用法,未能充分挖掘其潜力。本文将深入解析其底层原理、返回列的每一个细节、实战场景中的高级用法,并辅以真实案例,助你彻底掌握这一工具。


    # 一、SHOW FULL PROCESSLIST的底层机制

    # 1. 命令的本质
    • 线程模型:MySQL为每个客户端连接分配一个独立线程(或线程池中的线程)。SHOW FULL PROCESSLIST本质上是从information_schema.processlist表(或更底层的PERFORMANCE_SCHEMA)中提取当前所有线程的快照信息。
    • 瞬时性:结果仅反映命令执行瞬间的状态,无法捕获瞬间完成的查询。
    # 2. 与SHOW PROCESSLIST的区别
    • 信息截断规则:SHOW PROCESSLIST默认截断Info列超过1024字符的查询(旧版本为100字符),而FULL版本保留完整SQL。
    • 权限差异:两者权限要求相同,但FULL版本可能因返回大量文本对网络传输略有影响。
    # 3. 性能影响
    • 资源消耗:在极高并发场景(如数万连接)下频繁执行可能短暂增加服务器负载,但通常可忽略。
    • 替代方案:使用sys.session视图(需安装sys库)或PERFORMANCE_SCHEMA中的线程表可更高效查询。

    # 二、返回列全解析:每个值的深层含义

    以下为SHOW FULL PROCESSLIST输出的完整列结构及其所有可能的取值解析:

    列名 类型 详细说明与典型值
    Id BIGINT 线程ID,全局唯一。用途:KILL {Id}终止连接。注意:ID可能被复用(连接关闭后)。
    User VARCHAR 认证用户名。可能的值:
    - system user(后台线程,如主从复制线程)
    - unauthenticated user(未完成认证的连接)。
    Host VARCHAR 客户端地址格式为host:port。特殊值:
    - localhost(Unix Socket连接)
    - IP:port(TCP/IP连接)。
    db VARCHAR 当前默认数据库。若未USE db则为NULL。注意:即使切换数据库,某些操作可能仍保留原库上下文。
    Command VARCHAR 线程执行的命令类型。完整分类:
    - Query:执行SQL语句(包括SELECT/INSERT等)
    - Sleep:空闲等待
    - Binlog Dump:主库发送binlog
    - Connect:从库连接主库
    - Daemon:内部守护线程(如InnoDB后台线程)
    - Fetch:从游标读取数据
    - Field List:SHOW FIELDS命令执行中
    Time INT 当前状态持续时间(秒)。关键指标:
    - Sleep线程的Time反映空闲时间
    - Query线程的Time反映查询执行时间。
    State VARCHAR 线程状态(超过200种可能值)。核心状态解析:
    - Sending data:读取数据并发送到客户端(可能涉及磁盘IO)
    - Creating sort index:执行ORDER BY排序
    - locked:等待行锁(InnoDB)
    - Waiting for table metadata lock:DDL操作阻塞
    - Copying to tmp table:使用临时表(如大表GROUP BY)
    - Statistics:优化器正在生成执行计划
    Info VARCHAR 正在执行的SQL语句。注意事项:
    - 可能为NULL(如Sleep状态)
    - 预处理语句显示为?占位符
    - 需开启full_log才能捕获完整语句。

    # 三、实战场景与高级技巧

    # 场景1:定位慢查询杀手

    问题:数据库CPU突然飙升至90%,如何快速定位?

    -- 按执行时间排序,抓取前10个长耗时查询
    SELECT * FROM information_schema.processlist 
    WHERE COMMAND = 'Query' AND TIME > 10 
    ORDER BY TIME DESC LIMIT 10;
    
    1
    2
    3
    4

    分析:

    • 检查Info列中的SQL,结合EXPLAIN分析执行计划。
    • 关注State为Sending data或Creating tmp table的查询,可能是全表扫描或内存不足。
    # 场景2:解决元数据锁(MDL)阻塞

    现象:多个查询卡在Waiting for table metadata lock状态。 根因:长时间未提交的事务持有MDL锁,或ALTER TABLE未完成。 解决步骤:

    1. 查找阻塞源:
      SELECT * FROM performance_schema.metadata_locks 
      WHERE LOCK_STATUS = 'GRANTED' AND OWNER_THREAD_ID IS NOT NULL;
      
      1
      2
    2. 终止持有锁的线程(谨慎操作):
      KILL {阻塞线程ID};
      
      1
    # 场景3:识别异常连接

    案例:发现大量来自未知IP的连接,怀疑被暴力破解。

    -- 按Host统计连接数
    SELECT Host, COUNT(*) AS Connections 
    FROM information_schema.processlist 
    GROUP BY Host ORDER BY Connections DESC;
    
    1
    2
    3
    4

    行动:

    • 封锁异常IP:通过防火墙或iptables限制访问。
    • 终止连接:KILL {Id};
    • 审计日志:检查general_log确认攻击行为。
    # 场景4:优化连接池配置

    指标:大量Sleep线程且Time值高。 分析:

    • 应用连接池未正确配置,导致空闲连接未释放。
    • 调整连接池参数(如wait_timeout、max_connections)。

    # 四、自动化监控与工具链集成

    # 1. 实时监控脚本(Python示例)
    import pymysql
    import time
    
    def monitor_processlist(interval=5):
        conn = pymysql.connect(host='localhost', user='admin', password='secure')
        while True:
            with conn.cursor() as cursor:
                cursor.execute("SHOW FULL PROCESSLIST")
                processes = cursor.fetchall()
                for p in processes:
                    if p[4] == 'Query' and p[5] > 30:  # 超过30秒的查询
                        print(f"Long running query (ID {p[0]}): {p[7]}")
            time.sleep(interval)
    
    monitor_processlist()
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 2. 与Prometheus/Grafana集成
    • 使用mysqld_exporter采集processlist指标。
    • 关键监控项:
      • 每个State的线程数
      • 最大查询执行时间(max_time)
      • 按用户/IP统计的连接数
    # 3. 高级工具推荐
    • pt-kill:自动终止符合条件的慢查询。
    • innotop:实时监控MySQL的TUI工具。
    • Percona Monitoring and Management (PMM):企业级监控平台。

    # 五、避坑指南与最佳实践

    1. 谨慎使用KILL

      • KILL CONNECTION {Id}:终止连接并回滚事务(默认行为)。
      • KILL QUERY {Id}:仅停止当前查询,保持连接。
      • 风险:强制终止可能破坏事务完整性,导致数据不一致。
    2. 避免全表扫描

      • 若State频繁出现Sending data,检查索引覆盖:
        EXPLAIN SELECT /* 你的查询 */;
        
        1
    3. 处理Locked状态

      • 使用SHOW ENGINE INNODB STATUS查看锁详情。
      • 优化事务粒度,避免长时间持有锁。
    4. 临时表与内存优化

      • State为Copying to tmp table时,考虑增加tmp_table_size和max_heap_table_size。

    # 六、总结与延伸学习

    掌握SHOW FULL PROCESSLIST只是起点,真正的数据库优化需结合:

    • 执行计划分析:EXPLAIN、EXPLAIN ANALYZE
    • 锁监控:SHOW ENGINE INNODB STATUS、sys.innodb_lock_waits
    • 日志分析:慢查询日志(slow_query_log)、General Log
    在线编辑 (opens new window)
    上次更新: 2025/04/29, 14:13:12
    mysql编辑的sql
    Redis

    ← mysql编辑的sql Redis→

    最近更新
    01
    vue3中尖括号和冒号的使用细则
    04-29
    02
    sd使用
    02-22
    03
    显卡天梯图
    02-06
    更多文章>
    🖥️

    © 2025窝窝侠 💌 豫ICP备20005263号-2 🛀 Theme by 💝 Vdoing && 小胖墩er

    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×