AWS RDS CPU 飙升?别慌!一文教大家揪出“元凶”用户
大家好,在云原生时代,AWS RDS 凭借其易用性和高可用性,成为了许多团队的首选数据库解决方案。但便利的背后,也隐藏着一些“甜蜜的烦恼”。其中最令人头疼的莫过于:数据库 CPU 使用率突然飙升到 100%。
此时,告警系统开始疯狂“轰炸”,应用响应变得迟缓,SRE 和开发同学的心跳也跟着 CPU 曲线一起加速。别担心,这并不是一个无解的难题。高 CPU 占用率只是一个“果”,我们要做的,就是顺藤摸瓜,找到导致这个结果的“因”——那个消耗了大量资源的数据库用户和它背后的“坏查询”。
今天,我将带大家走一遍完整的排查流程,从 AWS 提供的可视化工具到传统的 SQL 命令,让大家在面对 CPU 飙升时能够从容不迫,快速定位问题。
第一站:AWS Performance Insights —— “第一响应人”
当我们收到 CPU 告警时,第一个应该去的地方不是数据库客户端,而是 AWS RDS 控制台的 Performance Insights。这是 AWS 官方提供的强大性能监控和诊断工具,对于排查 RDS 问题来说,它是无可替代的“神器”。
为什么首选它?
Performance Insights 能以可视化的方式展示数据库的负载情况,并能按照 SQL 查询、等待事件、主机和用户等维度进行切分。对于我们“抓捕元凶用户”的目标来说,这简直是量身定做。
如何使用?
- 打开 Performance Insights:登录 AWS 控制台,进入 RDS 服务,选择出问题的数据库实例,然后点击“Performance Insights”选项卡。
- 定位问题时间段:在顶部的时间选择器中,框选出 CPU 飙升的时间窗口。
- 分析数据库负载(Database Load):主图表展示的是“平均活动会话数”(Average Active Sessions, AAS)。可以把它简单理解为数据库在某一时刻有多少个会话在同时工作。如果负载图的颜色主要是绿色(代表 CPU),说明大部分负载都消耗在 CPU 计算上。
- 切分负载来源:这是最关键的一步!在图表下方的 “Top dimensions” 区域,将“Slice by”的维度从默认的“Waits”切换到 “Users”。
具体示例:
切换到按用户切分后,可能会看到类似下图的场景(请脑补一张图):user_app 占据了 80% 的负载,而其他用户如 user_admin、rdsadmin 等几乎可以忽略不计。
结论: 罪魁祸首就是 user_app!
锁定用户后,我们可以继续保持按 user_app 筛选,然后将维度切换回“SQL”,此时 Performance Insights 会列出该用户执行的所有查询中,消耗资源最多的那几条。通常,排名第一的查询就是导致 CPU 飙升的直接原因。
实用建议:
养成定期查看 Performance Insights 的习惯,而不是等到出问题才看。它可以帮我们发现潜在的性能瓶颈,防患于未然。
第二站:SHOW FULL PROCESSLIST —— 经典侦探的实时快照
如果 Performance Insights 由于某些原因(比如新创建的实例数据不足)无法提供足够信息,或者我们想查看当前正在发生的情况,那么古老而可靠的 SHOW FULL PROCESSLIST 命令就该登场了。
它能做什么?
这个命令会显示当前 MySQL 实例中所有正在运行的线程(即连接)。我们可以实时看到哪个用户、从哪个 IP、正在执行什么 SQL 语句,以及执行了多久。
如何使用?
通过任何 MySQL 客户端连接到我们的 RDS 实例,然后执行:
SHOW FULL PROCESSLIST;
关键要看哪些列?
User: 执行查询的数据库用户。这是我们最关心的列之一。Host: 连接来源的 IP 地址。可以帮我们判断请求来自哪台应用服务器。db: 当前连接的数据库名。Command: 线程当前的状态,如Query、Sleep、Connect。Time: 线程处于当前状态的秒数。这个值非常重要! 如果一个查询的Time很长(比如几十秒甚至更久),它很可能是一个慢查询,正在大量消耗 CPU。Info: 包含了完整的 SQL 语句。如果这里是NULL,说明线程当前没有执行任何操作。
实用建议:
在 CPU 高峰期,连续多次执行 SHOW FULL PROCESSLIST。如果总是看到同一个用户执行的某条复杂查询(并且 Time 值持续增长),那基本就可以断定是它在“捣乱”。但它的缺点是只能抓取“快照”,对于执行极快但频率极高的查询可能无能为力。
第三站:Performance Schema —— 深入骨髓的“法医级”分析
对于更复杂、更隐蔽的问题,Performance Insights 和 SHOW PROCESSLIST 可能不够用。这时,我们需要请出最终武器:Performance Schema。
Performance Schema 是 MySQL 内置的性能监控引擎,它以极低的开销收集数据库运行时的详细事件数据。我们可以把它想象成一个对数据库内核进行“埋点”的系统。
准备工作:
默认情况下,AWS RDS for MySQL 的 Performance Schema 是开启的,但我们可能需要检查一下参数组(Parameter Group),确保相关的 performance_schema 开关处于 ON 状态。
如何利用 Performance Schema 找用户?
我们可以查询 Performance Schema 提供的各种汇总表,来统计每个用户的资源消耗情况。下面这个查询非常实用,它可以按用户聚合,统计总的执行时间、查询次数和平均延迟。
-- 该查询统计自上次重置以来,每个用户的总执行时间和查询次数
-- 注意:SUM_TIMER_WAIT 的单位是皮秒 (picoseconds)
SELECT
USER,
SUM(COUNT_STAR) AS total_queries,
SUM(SUM_TIMER_WAIT) / 1000000000000 AS total_execution_time_seconds
FROM
performance_schema.events_statements_summary_by_user_by_event_name
WHERE
EVENT_NAME LIKE 'statement/sql/%' AND USER IS NOT NULL
GROUP BY
USER
ORDER BY
total_execution_time_seconds DESC;
+--------------------------------+---------------+------------------------------+ | USER | total_queries | total_execution_time_seconds | +--------------------------------+---------------+------------------------------+ | rdsadmin | 120091841 | 21770.3277 | | admin | 1339134 | 2791.0276 | | rdsrepladmin | 22 | 0.0012 | | event_scheduler | 0 | 0.0000 | +--------------------------------+---------------+------------------------------+ 查询解读:
events_statements_summary_by_user_by_event_name: 这是 Performance Schema 的一张核心汇总表,按用户和事件类型聚合了语句的统计信息。SUM(SUM_TIMER_WAIT):SUM_TIMER_WAIT记录了事件的总耗时,单位是皮秒,所以我们需要除以 10^12 转换成秒。ORDER BY ... DESC: 按总执行时间降序排列,消耗时间最多的用户会排在最前面。
实用建议:
Performance Schema 的数据是累积的。为了分析一个特定时间段的问题,我们可以在问题开始前手动清空汇总表(TRUNCATE TABLE performance_schema.events_statements_summary_by_user_by_event_name;),然后在问题结束后再执行上面的查询。这样得到的数据就非常精确了。
总结与行动计划
面对 AWS RDS MySQL 的 CPU 飙升问题,我们不必惊慌。一个清晰的排查思路至关重要:
- 首选 Performance Insights:它是最高效、最直观的工具。通过按“Users”切分负载,通常能在几分钟内定位到问题用户和查询。
- 辅助使用
SHOW FULL PROCESSLIST:用于实时观察当前正在执行的查询,尤其适合抓取长时间运行的“慢SQL”。 - 深挖 Performance Schema:当问题更复杂,需要定量分析时,通过查询其汇总表,可以从根本上理解各个用户的资源消耗模式。
一旦我们找到了那个“元凶”用户和它背后的SQL,下一步就是优化它——添加索引、改写查询逻辑、或者从业务层面减少调用频率。但这一切,都始于精准的定位。
希望这篇文章能成为大家工具箱中的一件利器。记住,强大的工具结合清晰的思路,再复杂的性能问题也能迎刃而解。