3. 慢查询监控体系:Prometheus + Grafana 监控慢查询指标、慢查询日志采集与告警
慢查询监控体系是数据库性能保障的“眼睛”与“神经”。本章聚焦于如何利用 Prometheus 与 Grafana 构建端到端的慢查询监控栈,覆盖指标暴露、日志采集、可视化仪表盘与告警规则四个核心环节。以下内容将按照“指标定义 → 采集部署 → 可视化 → 告警”的工程链路展开。
3.1 监控体系架构总览
下图展示了慢查询监控体系的核心组件与数据流。从数据库实例到最终告警通知,共经过四个层次:指标暴露层、采集与存储层、可视化层、告警与通知层。
3.2 慢查询关键指标定义与暴露
Prometheus 监控慢查询的核心在于定义正确的指标类型。对于数据库慢查询,主要关注以下三类指标:
| 指标类别 | 指标名称示例 | 类型 | 说明 |
|---|---|---|---|
| 慢查询计数 | mysql_global_status_slow_queries |
Counter | 自实例启动以来的慢查询累计次数 |
| 慢查询速率 | rate(mysql_global_status_slow_queries[1m]) |
派生指标 | 每分钟慢查询发生速率,用于告警阈值 |
| 查询延迟分布 | mysql_global_status_slow_launch_time |
Gauge | 最近慢查询的启动时间(秒),反映延迟趋势 |
| gRPC 尾延迟 | grpc_server_handling_seconds_bucket |
Histogram | gRPC 请求延迟分布,用于计算 p99/p999 |
| 慢查询日志行数 | log_entries_total{job="slow-query-log"} |
Counter | 通过 Promtail 采集的慢查询日志条目数 |
实践建议:对于 MySQL,务必开启
slow_query_log=ON 并设置 long_query_time=1(单位秒)。对于 gRPC 服务,使用 Prometheus 客户端库的 Histogram 类型,并合理配置 Bucket 边界(如 1ms、5ms、10ms、50ms、100ms、500ms、1s、5s)。
3.3 慢查询日志采集:Promtail + Loki 方案
慢查询日志属于非结构化文本数据,不适合直接存入 Prometheus。推荐使用 Loki + Promtail 进行日志采集与存储。采集流程如下:
- 配置数据库慢查询日志输出:确保 MySQL 的
slow_query_log_file路径可读,且日志格式包含执行时间、锁时间、返回行数、扫描行数等关键字段。 - 部署 Promtail:在数据库主机上运行 Promtail,配置
scrape_config指向慢查询日志文件。 - 日志解析与标签:使用 Promtail 的
pipeline_stages对日志行进行正则解析,提取query_time、rows_examined、rows_sent等字段作为标签。 - 发送至 Loki:Promtail 将解析后的日志行推送至 Loki 集群,支持按时间与标签检索。
以下是一个 Promtail 配置示例,用于采集 MySQL 慢查询日志:
scrape_configs:
- job_name: mysql-slow-query
static_configs:
- targets: [localhost]
labels:
job: mysql-slow
__path__: /var/log/mysql/mysql-slow.log
pipeline_stages:
- regex:
expression: '^# Time: (?P<time>\S+)\s+# User@Host: (?P<user>\S+)\s+# Query_time: (?P<query_time>\S+)\s+# Lock_time: (?P<lock_time>\S+)\s+# Rows_sent: (?P<rows_sent>\d+)\s+# Rows_examined: (?P<rows_examined>\d+)'
- labels:
query_time:
rows_sent:
rows_examined:
- timestamp:
source: time
format: RFC3339
3.4 Grafana 仪表盘设计
Grafana 仪表盘是慢查询监控的“驾驶舱”。推荐设计以下面板:
| 面板名称 | 数据源 | 查询语句(PromQL / LogQL) | 可视化类型 |
|---|---|---|---|
| 慢查询速率 | Prometheus | rate(mysql_global_status_slow_queries[5m]) |
时间序列折线图 |
| 慢查询延迟分布 | Prometheus | histogram_quantile(0.99, rate(mysql_global_status_slow_launch_time_bucket[5m])) |
热力图 / 柱状图 |
| gRPC p99 延迟 | Prometheus | histogram_quantile(0.99, rate(grpc_server_handling_seconds_bucket[5m])) |
时间序列折线图 |
| 慢查询日志 TOP-N | Loki | sum by (query_time) (count_over_time({job="mysql-slow"} |= "Query_time:" [1h])) |
表格 / 条形图 |
| 慢查询日志详情 | Loki | {job="mysql-slow"} |= "SELECT" | logfmt |
日志面板 |
关键仪表盘布局建议:顶部放置全局速率与延迟概览(折线图),中部放置慢查询日志 TOP-N 与分布热力图,底部放置原始日志面板用于根因下钻。每个面板设置 1m、5m、15m 时间范围快捷按钮。
3.5 告警规则配置
基于 Prometheus 的 Alertmanager 实现慢查询告警。以下是一组推荐的告警规则:
groups:
- name: slow_query_alerts
rules:
- alert: HighSlowQueryRate
expr: rate(mysql_global_status_slow_queries[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "慢查询速率过高 (实例 {{ $labels.instance }})"
description: "过去5分钟慢查询速率达到 {{ $value | humanize }} 次/秒,超过阈值 10"
- alert: HighP99Latency
expr: histogram_quantile(0.99, rate(grpc_server_handling_seconds_bucket[5m])) > 1.0
for: 1m
labels:
severity: critical
annotations:
summary: "gRPC p99 延迟超过 1s (服务 {{ $labels.service }})"
description: "当前 p99 延迟为 {{ $value | humanize }} 秒"
- alert: SlowQueryLogSpike
expr: sum(rate(log_entries_total{job="mysql-slow"}[5m])) > 50
for: 3m
labels:
severity: warning
annotations:
summary: "慢查询日志条目激增"
description: "过去5分钟慢查询日志速率达到 {{ $value | humanize }} 条/分钟"
告警调优注意:阈值应根据业务基线动态调整。建议先运行 1-2 周收集历史数据,使用 Prometheus 的
avg_over_time 或 Grafana 的告警降噪功能(Alerting → Silence / Mute Timing)避免告警风暴。对于 gRPC 尾延迟告警,建议设置 for: 1m 以上,避免瞬时抖动触发误报。
3.6 慢查询监控体系自检清单
部署完成后,使用以下清单验证监控体系是否完整:
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| 慢查询指标暴露 | curl http://localhost:9104/metrics | grep slow_query |
返回 mysql_global_status_slow_queries 等指标 |
| 日志采集 | Grafana Explore → Loki 数据源 → 查询 {job="mysql-slow"} |
返回最近慢查询日志行 |
| 仪表盘数据 | 打开 Grafana 仪表盘,选择最近 1 小时 | 所有面板显示非空数据 |
| 告警触发 | 手动执行一条慢查询(如 SELECT SLEEP(2)) |
Alertmanager 收到告警通知 |
通过以上步骤,即可构建一套覆盖指标、日志、可视化与告警的完整慢查询监控体系,为后续根因定位与尾延迟压测提供坚实的数据基础。