1. 问题背景与监控方案设计
最近在维护一套SQL Server监控系统时,我遇到了一个相当棘手的问题:Prometheus不断发出数据库重启告警,但实际检查发现数据库根本没有重启过。这个现象持续了将近一周,严重影响了我们的监控可信度。今天我就把这个排查过程和解决方案完整分享出来,希望能帮助遇到类似问题的同行。
我们的监控目标是实时检测SQL Server实例是否在15分钟内发生过重启。整套监控方案由三个核心组件构成:
- 数据采集层:使用sql_exporter作为采集器,通过自定义SQL查询从SQL Server的系统视图获取实例启动时间
- 指标处理层:Prometheus负责存储和计算采集到的指标
- 告警层:基于PromQL规则判断是否触发告警
具体实现上,我们最初设计的采集SQL是这样的:
sql复制SELECT DATEDIFF(s, '1970-01-01', sqlserver_start_time) AS start_time_seconds
FROM sys.dm_os_sys_info;
这个查询的逻辑很直观:计算SQL Server启动时间到Unix纪元(1970-01-01)的秒数差值,作为监控指标。在Prometheus中,我们使用以下PromQL规则来检测重启:
promql复制changes(mssql_instance_start_time_seconds[15m])>0
这条规则的意思是:如果在15分钟时间窗口内,启动时间秒数指标发生了变化(changes()函数返回值大于0),就认为实例发生了重启。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题现象与初步排查
系统运行初期一切正常,但大约两周后,我们开始频繁收到数据库重启告警。最奇怪的是,每次收到告警后检查:
- Windows系统事件日志中没有SQL Server服务重启记录
- SQL Server错误日志中也没有异常关闭和重启的痕迹
- 数据库连接池和应用都没有出现断连情况
这明显是一个"假告警"问题。为了找出原因,我首先检查了Prometheus中的原始指标数据。通过Grafana查询mssql_instance_start_time_seconds指标的历史值,发现这个指标确实会不时地发生微小变化,尽管数据库实际上
