摘要
信创数据库上了 K8s,慢 SQL 排查直接倒退三年:业务报慢才知道有问题、登库查还要进 Pod、没有历史趋势、没法告警、排障全靠手敲 SQL。很多团队要么裸跑无监控,要么硬套 MySQL 监控模板,指标不对、采集失败、根本用不起来。
本文基于政务、金融生产项目落地经验,输出K8s 环境人大金仓 V9 / 达梦 DM9 全套慢 SQL 监控方案:Sidecar 模式无侵入部署、Prometheus 自动发现采集、Grafana 可视化看板、慢 SQL 自动捕获、分级告警规则全覆盖。所有配置、SQL、看板均可直接复制,照着做 1 小时就能搭完生产级慢 SQL 监控体系。
政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。所有配置均在 K8s 1.26 + 对应数据库企业版实测跑通,生产可用。
一、痛点直击:K8s 国产数据库慢 SQL 为什么难监控
📌 核心结论:不是数据库没有监控能力,是 K8s 场景下传统监控方案不好使,加上国产数据库生态不完善,导致很多团队裸跑。
1.1 四大核心痛点
- 排查效率低:出问题要 kubectl exec 进 Pod,手动敲 SQL 查,没有历史记录,事后无法回溯
- 部署麻烦:传统 Agent 方式不适合容器,独立部署又要维护网络、端口,K8s 漂移后还要改配置
- 生态不完善:MySQL 有成熟的 mysqld_exporter,金仓、达梦的官方 exporter 要么没有、要么功能弱,慢 SQL 指标要自己写
- 告警缺失:慢 SQL 突增没有告警,等业务反馈过来,故障已经扩大了
1.2 我们要达到的效果
- ✅ 不用进 Pod,Grafana 看板直接看所有慢 SQL
- ✅ 有历史趋势,能看什么时候开始慢、慢了多久
- ✅ 自动告警,慢 SQL 数量突增、TOP SQL 耗时异常第一时间通知
- ✅ 无侵入部署,不用改数据库镜像,Sidecar 直接加
- ✅ K8s 原生适配,Pod 漂移、扩容自动发现,不用改配置
二、架构选型:Sidecar 无侵入 + 云原生自动发现
2.1 整体架构
数据库Pod(StatefulSet)
├─ 数据库主容器(金仓/达梦)
└─ Exporter Sidecar容器(指标采集)
↓ 指标暴露 /metrics
Prometheus(ServiceMonitor自动发现)
↓
Grafana可视化看板 + Alertmanager分级告警
2.2 为什么选 Sidecar 模式
| 部署方式 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|
| Sidecar 同 Pod | 网络开销小、地址固定、随 Pod 自动部署、运维简单 | 每个 Pod 多一个容器 | ⭐⭐⭐⭐⭐ |
| 独立 Deployment | 资源共享、集中管理 | 网络配置复杂、漂移后地址变更 | ⭐⭐⭐ |
| 节点 Agent | 部署简单 | 容器化场景适配差、权限不好控 | ⭐⭐ |
💡 生产推荐 Sidecar:和数据库同生命周期,配置一次写进 StatefulSet,永远跟着数据库走,K8s 怎么漂移都不怕。
2.3 Exporter 选型
| 数据库 | 推荐 Exporter | 原理 |
|---|---|---|
| 人大金仓 V9 | postgres_exporter | 金仓兼容 PG 协议,自定义 SQL 扩展慢 SQL 指标 |
| 达梦 DM9 | dm_exporter / 自定义 JDBC exporter | 官方 exporter + 自定义 SQL 采集慢 SQL、锁等待 |
三、部署实战:人大金仓 V9 监控全配置
金仓兼容 PostgreSQL 协议,用 postgres_exporter + 自定义 SQL 就能完美适配,重点是把系统视图从 pg_改成 sys_。
3.1 第一步:创建专用监控用户(最小权限)
生产绝对不能用 system 账号做监控,建专用只读用户:
-- 金仓V9 执行
CREATE USER monitor WITH PASSWORD 'Monitor@2026';
GRANT pg_monitor TO monitor;
GRANT SELECT ON sys_stat_activity TO monitor;
GRANT SELECT ON sys_stat_database TO monitor;
GRANT SELECT ON sys_stat_bgwriter TO monitor;
3.2 第二步:自定义慢 SQL 采集配置
创建 ConfigMap,存放慢 SQL 采集规则,这是监控的核心:
# kingbase-exporter-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kingbase-exporter-queries
namespace: kingbase
data:
queries.yaml: |
slow_sql_count:
query: |
SELECT count(*) AS slow_sql_count
FROM sys_stat_activity
WHERE state != 'idle'
AND now() - query_start > interval '1s'
AND backend_type = 'client backend';
slow_sql_detail:
query: |
SELECT
pid,
usename,
datname,
state,
now() - query_start AS duration,
substring(query, 1, 200) AS sql_text
FROM sys_stat_activity
WHERE state != 'idle'
AND now() - query_start > interval '1s'
ORDER BY query_start ASC
LIMIT 20;
metrics:
- pid:
usage: "LABEL"
description: "会话ID"
- usename:
usage: "LABEL"
description: "用户名"
- duration:
usage: "GAUGE"
description: "SQL执行时长秒数"
db_hit_ratio:
query: |
SELECT
datname,
sum(blks_hit) * 100.0 / nullif(sum(blks_hit + blks_read), 0) AS hit_ratio
FROM sys_stat_database
GROUP BY datname;
metrics:
- datname:
usage: "LABEL"
- hit_ratio:
usage: "GAUGE"
description: "缓存命中率"
3.3 第三步:StatefulSet 追加 Sidecar 容器
在原有金仓 StatefulSet 的containers里追加 exporter:
# 追加到 spec.template.spec.containers 下
- name: kingbase-exporter
image: prometheuscommunity/postgres-exporter:v0.15.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9187
name: metrics
env:
- name: DATA_SOURCE_URI
value: "localhost:54321/postgres?sslmode=disable"
- name: DATA_SOURCE_USER
value: "monitor"
- name: DATA_SOURCE_PASS
valueFrom:
secretKeyRef:
name: kingbase-secret
key: monitor_password
- name: PG_EXPORTER_EXTEND_QUERY_PATH
value: "/etc/exporter/queries.yaml"
volumeMounts:
- name: exporter-queries
mountPath: /etc/exporter
resources:
requests:
cpu: "0.1"
memory: "128Mi"
limits:
cpu: "0.5"
memory: "512Mi"
# 追加到 volumes 下
- name: exporter-queries
configMap:
name: kingbase-exporter-queries
3.4 第四步:Metrics Service 暴露指标
给 Prometheus 采集用:
apiVersion: v1
kind: Service
metadata:
name: kingbase-metrics
namespace: kingbase
labels:
app: kingbase
metrics: "true"
spec:
type: ClusterIP
selector:
app: kingbase
ports:
- port: 9187
targetPort: 9187
name: metrics
四、部署实战:达梦 DM9 监控全配置
达梦用官方 dm_exporter 或通用 JDBC exporter,核心是通过系统视图v$sessions、v$sql采集慢 SQL。
4.1 第一步:创建监控用户
-- 达梦DM9 执行
CREATE USER monitor IDENTIFIED BY "Monitor@2026";
GRANT SELECT ANY DICTIONARY TO monitor;
GRANT SELECT ON v$sessions TO monitor;
GRANT SELECT ON v$sql TO monitor;
GRANT SELECT ON v$sysstat TO monitor;
4.2 第二步:自定义采集 SQL 配置
# dmdb-exporter-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: dmdb-exporter-queries
namespace: dmdb
data:
queries.yaml: |
slow_sql_count:
query: |
SELECT count(*) AS slow_sql_count
FROM v$sessions
WHERE state = 'ACTIVE'
AND sysdate - create_time > 1.0 / 86400;
slow_sql_detail:
query: |
SELECT
sess_id,
user_name,
state,
(sysdate - create_time) * 86400 AS duration_sec,
substr(sql_text, 1, 200) AS sql_text
FROM v$sessions
WHERE state = 'ACTIVE'
AND (sysdate - create_time) * 86400 > 1
ORDER BY create_time ASC
LIMIT 20;
cache_hit_ratio:
query: |
SELECT (1 - sum(phys_reads)/sum(logical_reads)) * 100 AS hit_ratio
FROM v$bufferpool;
4.3 第三步:StatefulSet 追加 Sidecar
推荐使用自定义 JDBC exporter 适配达梦:
# 追加到 spec.template.spec.containers 下
- name: dmdb-exporter
image: bitnami/jmx-exporter:latest # 或专用dm_exporter镜像
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9160
name: metrics
env:
- name: DB_URL
value: "jdbc:dm://localhost:5236"
- name: DB_USER
value: "monitor"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: dmdb-secret
key: monitor_password
- name: CONFIG_FILE
value: "/etc/exporter/queries.yaml"
volumeMounts:
- name: exporter-queries
mountPath: /etc/exporter
resources:
requests:
cpu: "0.1"
memory: "128Mi"
limits:
cpu: "0.5"
memory: "512Mi"
# volumes 追加
- name: exporter-queries
configMap:
name: dmdb-exporter-queries
4.4 第四步:Metrics Service
apiVersion: v1
kind: Service
metadata:
name: dmdb-metrics
namespace: dmdb
labels:
app: dmdb
metrics: "true"
spec:
type: ClusterIP
selector:
app: dmdb
ports:
- port: 9160
targetPort: 9160
name: metrics
五、Prometheus 采集与自动发现配置
K8s 环境用 ServiceMonitor 自动发现,不用手动写静态配置,扩缩容、漂移自动适配。
5.1 人大金仓 ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kingbase-metrics
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- kingbase
selector:
matchLabels:
metrics: "true"
endpoints:
- port: metrics
interval: 15s
scrapeTimeout: 10s
path: /metrics
5.2 达梦 ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: dmdb-metrics
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- dmdb
selector:
matchLabels:
metrics: "true"
endpoints:
- port: metrics
interval: 15s
scrapeTimeout: 10s
💡 采集频率建议 15 秒,既能捕捉慢 SQL 波动,又不会给数据库造成太大压力。
六、Grafana 可视化看板:核心指标全覆盖
6.1 看板核心面板设计
表格
| 面板区域 | 核心指标 | 作用 |
|---|---|---|
| 概览区 | 活跃连接数、缓存命中率、TPS、QPS | 一眼看数据库整体健康度 |
| 慢 SQL 区 | 慢 SQL 数量趋势、TOP10 慢 SQL 文本与耗时 | 直接定位最慢的 SQL |
| 资源区 | CPU 使用率、内存使用率、IO 等待 | 判断是资源问题还是 SQL 问题 |
| 锁等待区 | 锁等待数量、阻塞链 | 快速判断是不是锁阻塞导致的慢 |
| 表空间区 | 数据盘、WAL 盘、归档盘使用率 | 提前发现磁盘风险 |
6.2 核心 PromQL 示例
# 慢SQL数量
kingbase_slow_sql_count{namespace="kingbase"}
# 缓存命中率
avg(kingbase_db_hit_ratio{namespace="kingbase"}) by (datname)
# 活跃连接数
kingbase_connections_state{state="active"}
# 达梦慢SQL数量
dmdb_slow_sql_count{namespace="dmdb"}
6.3 看板落地建议
- 按数据库实例分变量切换,一套看板看所有实例
- 慢 SQL 面板开启自动刷新,5 秒刷新一次
- TOP SQL 面板显示完整 SQL 文本,点击可查看执行计划链接
七、慢 SQL 自动捕获与分级告警体系
光看板不够,还要主动告警,别等业务反馈才知道出问题。
7.1 三级告警规则
| 告警级别 | 触发条件 | 通知对象 | 响应时效 |
|---|---|---|---|
| 一般告警 | 慢 SQL 数量 > 5 且持续 5 分钟 | 开发 DBA | 工作日处理 |
| 严重告警 | 慢 SQL 数量 > 20 且持续 2 分钟 | 运维 + DBA | 30 分钟内响应 |
| 紧急告警 | 活跃连接数 > 80% 且慢 SQL 突增 3 倍 | 全组 | 立即响应 |
7.2 告警规则示例(PrometheusRule)
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: kingbase-slow-sql-rules
namespace: monitoring
spec:
groups:
- name: kingbase-slow-sql
rules:
- alert: KingbaseSlowSQLIncreasing
expr: increase(kingbase_slow_sql_count[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "人大金仓慢SQL数量突增"
description: "实例 {{ $labels.pod }} 慢SQL数量5分钟增长超过10条,请及时排查"
- alert: KingbaseConnectionsHigh
expr: kingbase_connections_state{state="active"} > 400
for: 1m
labels:
severity: critical
annotations:
summary: "人大金仓活跃连接数过高"
description: "实例 {{ $labels.pod }} 活跃连接数超过400,存在连接雪崩风险"
7.3 进阶:慢 SQL 自动抓执行计划
严重告警触发时,自动执行脚本抓取对应 SQL 的执行计划,附在告警里,不用人工登库查:
- Alertmanager 触发 webhook
- 调用运维脚本,进 Pod 抓取 SQL 执行计划、AWR 报告
- 告警通知附带分析结果,直接定位问题
八、生产级避坑:10 个监控落地常见坑
⚠️ 坑 1:用超级管理员账号做监控
- 风险:权限过大,存在安全隐患,等保不合规
- 整改:建专用只读监控用户,只授予必要的系统视图权限
⚠️ 坑 2:采集频率太高,把数据库拖慢
- 风险:每秒采集一次,复杂查询 SQL 本身就慢,反向影响业务
- 整改:15 秒采集间隔足够,慢 SQL 视图查询要加 limit,不要全表查
⚠️ 坑 3:金仓直接用 PG 原生 exporter 配置不改
- 风险:系统视图名不对,采集失败或指标为空
- 整改:所有 pg_前缀视图改成 sys_,对应金仓系统视图
⚠️ 坑 4:exporter 和数据库跨节点部署
- 风险:网络开销大,Pod 漂移后地址变了采集断了
- 整改:Sidecar 同 Pod 部署,localhost访问,稳定无感知
⚠️ 坑 5:只监控数量,不抓 SQL 文本
- 风险:只知道有慢 SQL,不知道是哪条,排障还要登库
- 整改:自定义 SQL 采集 TOP 慢 SQL 文本,看板直接能看
⚠️ 坑 6:慢 SQL 阈值设太低
- 风险:100ms 就算慢 SQL,告警风暴,没人看
- 整改:业务场景设置合理阈值,OLTP 系统 1 秒以上算慢 SQL
⚠️ 坑 7:没有历史数据,无法对比
- 风险:不知道是一直慢还是突然变慢,无法定位变更点
- 整改:Prometheus 至少保留 30 天历史数据,支持周同比、日环比
⚠️ 坑 8:监控指标不打标签
- 风险:多实例分不清哪个库的问题
- 整改:所有指标带上 namespace、pod、实例名标签,便于聚合筛选
⚠️ 坑 9:告警只发一次,不升级
- 风险:告警被忽略,故障扩大
- 整改:分级告警,持续不解决自动升级,严重告警电话通知
⚠️ 坑 10:只监控不治理
- 风险:看板再好看,慢 SQL 一直摆在那没人优化
- 整改:建立每周慢 SQL 治理机制,TOP SQL 定期优化
九、常用排查 PromQL 与 SQL 速查
9.1 PromQL 速查
# 慢SQL数量趋势
rate(kingbase_slow_sql_count[5m])
# 缓存命中率
avg(kingbase_db_hit_ratio) by (pod)
# 活跃连接数TOP5
topk(5, kingbase_connections_state{state="active"})
# 达梦慢SQL数量
dmdb_slow_sql_count{namespace="dmdb"}
9.2 数据库排查 SQL 速查
人大金仓查慢 SQL
SELECT
pid,
usename,
now() - query_start AS 执行时长,
state,
query
FROM sys_stat_activity
WHERE state != 'idle'
ORDER BY query_start ASC;
达梦查慢 SQL
SELECT
sess_id,
user_name,
(sysdate - create_time) * 86400 AS 执行时长秒,
state,
sql_text
FROM v$sessions
WHERE state = 'ACTIVE'
ORDER BY create_time ASC;
总结
K8s 环境下国产数据库慢 SQL 监控,不是简单装个 exporter 就完事,要做到能看见、能告警、能回溯、能定位。Sidecar 模式无侵入部署、自定义 SQL 精准采集、Prometheus 自动发现、Grafana 可视化、分级告警联动,整套体系跑起来,慢 SQL 排查效率提升 10 倍以上。
数据库监控不是为了好看板,是为了故障早发现、快定位、少影响业务。把监控做扎实,比出了事故再救火重要得多。
政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。
📚 专栏推荐:专注 SpringBoot3 + 人大金仓 + 达梦信创实战,持续输出生产级部署、性能调优、监控运维、避坑指南干货,关注不迷路。
觉得文章有用的话,欢迎点赞、收藏、关注三连,后续更新更多信创数据库云原生运维的硬核内容。