mysql cpu飙升如何查看是哪个sql导致的呢?cpu高了可能导致正常的sql也超时了,得找到引起的原因?你有哪些思路

1 个回答

  • 沙之影
    明知不可为而为之就是我最大的诚意
    MySQL CPU 飙升可能由某些复杂或频繁执行的 SQL 查询导致。为了定位具体引发问题的 SQL,可以结合 MySQL 的性能监控工具和诊断方法进行分析。以下是清晰的步骤: ### **1. 快速排查当前运行的 SQL** #### **1.1 使用 `SHOW PROCESSLIST`** - 查看当前活跃线程,找到执行时间较长或状态为 `Running` 的 SQL。 **命令:** ```sql SHOW FULL PROCESSLIST; ``` **重点字段:** - **Id:** 线程 ID,可用来终止线程。 - **Time:** SQL 执行时间,值较大可能是问题所在。 - **State:** 显示当前线程状态(如 `Sorting`, `Sending data`)。 - **Info:** 正在执行的 SQL 语句。 **快速终止可疑线程:** ```sql KILL <thread_id>; ``` #### **1.2 `performance_schema` 查看当前线程的 SQL** **启用 `performance_schema`:** ```sql SELECT * FROM performance_schema.events_statements_current WHERE SQL_TEXT IS NOT NULL; ``` **结果包含:** - **SQL_TEXT:** 当前执行的 SQL。 - **TIMER_WAIT:** SQL 已经运行的时间(纳秒)。 ### **2. 分析慢查询** #### **2.1 启用慢查询日志** 确认慢查询日志已开启: ```sql SHOW VARIABLES LIKE 'slow_query_log'; ``` 如果未启用: ```sql SET GLOBAL slow_query_log = 'ON'; ``` 设置记录阈值(如超 1 秒的查询): ```sql SET GLOBAL long_query_time = 1; ``` 查看慢查询日志路径: ```sql SHOW VARIABLES LIKE 'slow_query_log_file'; ``` #### **2.2 分析慢查询日志** 使用 `mysqldumpslow` 工具快速分析慢查询日志: ```bash mysqldumpslow -s c -t 10 /path/to/slow_query.log ``` 参数说明: - `-s c`: 按查询次数排序。 - `-t 10`: 显示最常见的前 10 条慢查询。 ### **3. 利用 `performance_schema` 定位高消耗 SQL** #### **3.1 查看高 CPU 消耗的 SQL** **查询消耗时间最长的语句:** ```sql SELECT SQL_TEXT, SUM_TIMER_WAIT/1000000000 AS TOTAL_EXEC_TIME_MS, EXEC_COUNT, SUM_LOCK_TIME/1000000 AS LOCK_TIME_MS FROM performance_schema.events_statements_summary_by_digest ORDER BY TOTAL_EXEC_TIME_MS DESC LIMIT 10; ``` **结果分析:** - **SQL_TEXT:** 对应的 SQL 语句。 - **TOTAL_EXEC_TIME_MS:** 累计执行时间(毫秒)。 - **EXEC_COUNT:** 执行次数,频繁执行可能导致 CPU 飙升。 - **LOCK_TIME_MS:** 累计锁等待时间。 #### **3.2 查看特定用户或主机的 SQL 活动** **按用户统计:** ```sql SELECT USER, SUM_TIMER_WAIT/1000000000 AS TOTAL_EXEC_TIME_MS, EXEC_COUNT FROM performance_schema.events_statements_summary_by_user_by_event_name ORDER BY TOTAL_EXEC_TIME_MS DESC LIMIT 5; ``` **按主机统计:** ```sql SELECT HOST, SUM_TIMER_WAIT/1000000000 AS TOTAL_EXEC_TIME_MS, EXEC_COUNT FROM performance_schema.events_statements_summary_by_host_by_event_name ORDER BY TOTAL_EXEC_TIME_MS DESC LIMIT 5; ``` ### **4. 分析资源消耗** #### **4.1 查询 I/O 密集型 SQL** ```sql SELECT SQL_TEXT, SUM_ROWS_READ, SUM_ROWS_SENT, SUM_ROWS_EXAMINED FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_ROWS_READ DESC LIMIT 10; ``` **结果分析:** - **SUM_ROWS_READ:** 读取行数最多的 SQL。 - **SUM_ROWS_EXAMINED:** 检索行数最多的 SQL,可能存在表扫描问题。 #### **4.2 分析表锁争用** ```sql SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_STAR AS LOCK_COUNT, SUM_TIMER_WAIT/1000000 AS LOCK_TIME_MS FROM performance_schema.table_lock_waits_summary_by_table ORDER BY LOCK_TIME_MS DESC LIMIT 5; ``` ### **5. 检查系统资源与索引问题** #### **5.1 查看 MySQL 全局状态** ```sql SHOW GLOBAL STATUS LIKE 'Threads%'; SHOW GLOBAL STATUS LIKE 'Handler%'; ``` **重点:** - `Threads_running`: 当前活跃线程数,值过高说明可能存在性能瓶颈。 - `Handler_read_rnd_next`: 高值可能表明存在大量全表扫描。 #### **5.2 检查是否存在未使用索引** ```sql EXPLAIN SELECT ...; -- 检查 SQL 执行计划 ``` 关注是否有 `Using index` 标记,如果没有,可能需要优化索引。 ### **6. 快速缓解高 CPU 问题的措施** 1. **终止耗资源的线程:** - 通过 `SHOW PROCESSLIST` 或 `performance_schema` 找到运行时间过长的线程并终止。 2. **优化慢查询:** - 检查慢查询日志,定位导致问题的 SQL。 - 优化表设计、添加索引或调整查询逻辑。 3. **限制并发量:** - 通过 `max_connections` 控制总连接数。 - 临时调整 `innodb_thread_concurrency` 限制并发线程数。 4. **缓存结果:** - 对于重复执行的查询,可以使用查询缓存或应用层缓存。 5. **垂直拆分或分库分表:** - 如果数据库压力过大,可以对表或业务进行拆分。 ### **总结** 1. **排查当前运行的 SQL:** 使用 `SHOW PROCESSLIST` 或 `performance_schema` 查看当前线程及其执行的 SQL。 2. **分析慢查询:** 开启慢查询日志,结合 `mysqldumpslow` 找到问题 SQL。 3. **定位高资源消耗 SQL:** 通过 `performance_schema` 查看高 CPU、高 I/O 的 SQL 查询。 4. **系统资源分析:** 检查全局状态、线程数及索引使用情况。 5. **优化查询和数据库配置:** 针对问题 SQL 优化索引和表设计,必要时限制并发或启用缓存。 通过以上方法,能够快速定位引发 CPU 飙升的根因,并针对性地优化或解决问题。
    发布于 2024-11-17 18:17 •IP属地 北京
    举报
    评论
    收藏