如何基于MySQL进程起止时间在Grafana绘制内存占用时序图
解决Grafana中进程累计内存堆叠时序图的MySQL实现方案
核心逻辑
要实现矩形堆叠图,需先生成符合__interval间隔的连续时间序列,再逐一计算每个时间间隔内所有运行中进程的内存总和,同时按进程名称分组以支持堆叠展示。
完整SQL代码
WITH RECURSIVE time_intervals AS ( -- 初始化:过去2天的起始时间,对齐到__interval的整数倍 SELECT DATE_SUB(NOW(), INTERVAL 2 DAY) - INTERVAL MOD(UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 2 DAY)), __interval) SECOND AS interval_start UNION ALL -- 递归生成后续时间点,直到当前时刻 SELECT interval_start + INTERVAL __interval SECOND FROM time_intervals WHERE interval_start + INTERVAL __interval SECOND <= NOW() ) SELECT UNIX_TIMESTAMP(ti.interval_start) * 1000 AS time, -- 转换为Grafana兼容的毫秒级时间戳 SUM(p.memory) AS total_memory, p.name AS process_name FROM time_intervals ti LEFT JOIN processes p -- 判断进程是否在当前时间间隔内运行(时间范围重叠) ON p.starttime < ti.interval_start + INTERVAL __interval SECOND AND p.endtime > ti.interval_start -- 过滤过去2天内启动的进程 AND p.starttime >= DATE_SUB(NOW(), INTERVAL 2 DAY) WHERE ti.interval_start >= DATE_SUB(NOW(), INTERVAL 2 DAY) GROUP BY ti.interval_start, p.name ORDER BY ti.interval_start;
关键细节解释
- 时间序列生成:利用MySQL 8.0+支持的递归CTE创建连续的时间间隔,确保每个间隔严格对齐
__interval,避免时间轴错位。 - 进程匹配规则:通过
starttime < 间隔结束时间和endtime > 间隔开始时间的条件,准确覆盖跨多个时间间隔运行的进程。 - 堆叠图适配:按
process_name分组后,Grafana会自动将不同进程的内存占用堆叠显示,实现矩形堆叠图效果。 - 性能优化:建议对
starttime和endtime字段建立联合索引,减少大表查询时的时间范围匹配耗时。
适配Grafana的注意点
__interval是Grafana的动态变量,需确保其值为合法的秒数(如60代表1分钟间隔)。- 若使用MySQL 5.x版本(不支持递归CTE),可通过预先创建时间维度表替代递归生成时间序列。
内容的提问来源于stack exchange,提问作者KamilCuk
相关产品推荐
相关产品推荐

