MySQL - 显示进程列表
MySQL - 使用 SHOW PROCESSLIST 进行监控
Section titled “MySQL - 使用 SHOW PROCESSLIST 进行监控”MySQL 是一个多用户数据库系统,多个客户端可以同时连接并执行操作。每个到服务器的连接都在自己的线程中运行。SHOW PROCESSLIST 命令是一个实时诊断工具,它为你提供这些线程及其当前正在做什么的快照。
什么是 MySQL 进程列表?
Section titled “什么是 MySQL 进程列表?”进程列表显示了当前在 MySQL 服务器内执行的线程集合。当你需要回答以下问题时,它是你的首选工具:
- 谁连接到了我的数据库?
- 当前正在运行哪些查询?
- 某个查询是否卡住或运行了很长时间?
- 为什么我收到“连接过多”错误?
要查看所有线程,你需要 PROCESS 权限。没有此权限,你只能看到自己的线程。这是一项重要的安全功能。
SHOW PROCESSLIST 命令
Section titled “SHOW PROCESSLIST 命令”此命令显示有关当前进程的信息。它对于调试实时性能问题非常宝贵。
SHOW [FULL] PROCESSLISTFULL 关键字是可选的。如果你省略它,Info 字段(包含 SQL 语句)将被截断为 100 个字符。要查看完整的查询,你必须使用 SHOW FULL PROCESSLIST。
在 MySQL 客户端中使用 \G 作为分隔符会将输出垂直格式化,这更易于阅读。
SHOW FULL PROCESSLIST\G*************************** 1. row *************************** Id: 8 User: app_user Host: app-server-1.internal:48916 db: my_appCommand: Query Time: 25 State: Sending data Info: SELECT * FROM large_table JOIN another_table ON ... WHERE ...*************************** 2. row *************************** Id: 9 User: root Host: localhost db: NULLCommand: Query Time: 0 State: executing Info: SHOW FULL PROCESSLIST*************************** 3. row *************************** Id: 10 User: app_user Host: app-server-2.internal:51342 db: my_appCommand: Sleep Time: 120 State: Info: NULL解释输出结果
Section titled “解释输出结果”理解这些列是诊断问题的关键:
- Id:连接标识符。你可以使用此 ID 和
KILL命令(例如,KILL 8;)来终止一个有问题的进程。 - User/Host:连接用户和来源主机。这有助于识别查询的来源(例如,应用程序服务器、定时任务)。
- db:线程的默认数据库。
- Command:线程正在执行的命令类型。
Query表示它正在主动运行一个语句。Sleep非常常见,表示连接处于空闲状态,正在等待客户端的下一个命令。大量的Sleep线程可能表明应用程序连接池存在问题。 - Time:线程处于当前状态的秒数。对于
Query命令而言,较高的Time值是长时间运行查询的危险信号。 - State:线程正在做什么的描述。这对于调试至关重要。长时间处于
Locked(锁定)、Copying to tmp table(复制到临时表)或Creating sort index(创建排序索引)等状态表明存在性能瓶颈。 - Info:正在执行的实际 SQL 语句(如果无则为
NULL)。始终使用FULL关键字来查看完整的查询。
现代替代方案:性能模式
Section titled “现代替代方案:性能模式”SHOW PROCESSLIST 是一个很好的初步查看工具。对于更深入、历史性的和聚合的性能分析,现代 MySQL 版本提供了 Performance Schema(性能模式)。它是一个强大的检测引擎,以一组数据库表的形式收集性能数据。
例如,SELECT * FROM performance_schema.threads; 提供了与 SHOW PROCESSLIST 类似的信息,但以可查询的表格式呈现。Performance Schema 更复杂,但为高级调优提供了更大的洞察力。
使用客户端程序监控进程
Section titled “使用客户端程序监控进程”你也可以从应用程序中执行 SHOW PROCESSLIST 来构建自定义监控仪表板或健康检查。
PHPNodeJSJavaPython
// 假设一个已连接的 $mysqli 对象$sql = "SHOW FULL PROCESSLIST";$result = $mysqli->query($sql);
if ($result) { $processes = $result->fetch_all(MYSQLI_ASSOC); print_r($processes); $result->free();}
// 假设一个来自 mysql2/promise 的已连接 'connection' 对象async function showProcesses(connection) { try { const [rows] = await connection.execute('SHOW FULL PROCESSLIST'); console.log('Current Processes:', rows); } catch (err) { console.error('Failed to get process list:', err); }}
// 假设一个已连接的 'conn' 对象 (java.sql.Connection)String sql = "SHOW FULL PROCESSLIST";try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) {
ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount();
while (rs.next()) { for (int i = 1; i <= columnCount; i++) { System.out.printf("%s: %s, ", rsmd.getColumnName(i), rs.getString(i)); } System.out.println(); }} catch (SQLException e) { e.printStackTrace();}
# 假设一个来自 mysql-connector-python 的已连接 'connection' 对象和 'cursor' 对象try: cursor.execute("SHOW FULL PROCESSLIST") # 使用字典游标使输出易于处理 print("Current Processes:") for process in cursor.fetchall(): print(process)except mysql.connector.Error as err: print(f"Error: {err}")