SQL Server 阻塞监控自动化解决方案
问题现象
问题现象
BI 系统在获取数据时频繁出现以下问题:
- 数据加载缓慢,转圈等待时间过长
- 查询操作超时,无法正常返回结果
- 使用传统方法
sp_who2排查时,问题已消失
问题原因
传统的被动排查方法存在以下局限性:
时效性差:等待运维人员登录服务器时,阻塞可能已经结束,无法捕获现场。
缺乏历史数据:无法追溯问题发生的频率、规律和趋势。
无法量化影响:不清楚阻塞的持续时间、影响范围和业务影响程度。
简单来说,需要一个”监控摄像头”来持续记录数据库会话的阻塞状态,以便事后回放和分析。
解决方案
建立自动化监控机制:
- 每分钟采集一次数据库会话阻塞状态
- 保留最近 7 天的历史记录
- 实现事后分析和问题追溯
- 提供量化的阻塞统计数据
实施步骤
步骤 1:创建监控数据库
为避免与业务数据混合,创建独立的工具数据库:
1 | CREATE DATABASE DBAUtility; |
步骤 2:创建监控数据表
创建表 BlockingSnapshots,用于存储阻塞快照数据:
1 | CREATE TABLE DBAUtility.dbo.BlockingSnapshots ( |
注意:实际使用时需根据需求添加索引以提升查询性能。
步骤 3:创建监控存储过程
步骤 3:创建监控存储过程
创建存储过程 CaptureBlockingSnapshot,实现以下功能:
- 查询系统 DMV 视图(
sys.dm_exec_requests、sys.dm_exec_sessions等),识别当前阻塞关系 - 追溯阻塞链,定位根源阻塞会话(Head Blocker)
- 获取阻塞源和被阻塞会话的 SQL 文本
- 将阻塞信息插入
BlockingSnapshots表 - 若当前无阻塞,记录正常状态快照(便于对比分析)
- 自动清理 7 天前的历史数据
提示:完整的存储过程代码请参见文末的相关文件。
步骤 4:配置自动执行作业
步骤 4:配置自动执行作业
使用 SQL Server Agent 创建定时作业,每分钟执行一次 CaptureBlockingSnapshot 存储过程。
遇到的问题
作业创建后执行失败,错误信息如下:
1 | 无法找到登录名 'CLOUD-MC\Administrator'. [SQLSTATE 42000] (错误 18456) |
原因分析:
根据测试发现,使用域账号作为作业所有者时,SQL Server Agent 在验证域账号时可能因为域控制器连接不稳定而失败。
解决方案:
将作业所有者更改为 sa 账户或其他本地 SQL 登录账户:
1 | USE msdb; |
步骤 5:验证监控运行状态
步骤 5:验证监控运行状态
等待几分钟后查询监控表,确认数据采集正常:
1 | SELECT TOP 20 |
预期结果:
- 每分钟生成一条新记录
- 无阻塞时
HasBlocking = 0 - 有阻塞时
HasBlocking = 1且包含详细的阻塞信息
使用方法
查询 1:最近阻塞时间点分布
查看最近 2 小时内发生阻塞的时间分布:
1 | SELECT SnapshotTime, COUNT(*) AS 阻塞会话数 |
查询 2:阻塞详情分析
查看最近 30 分钟内的阻塞详情,按等待时长排序:
1 | SELECT |
查询 3:阻塞频率统计
计算最近 1 小时内阻塞发生的频率:
1 | SELECT |
实际案例
问题场景
2025 年 11 月 17 日 1:30 ,用户反馈 BI 系统响应缓慢,报表无法正常加载。
排查过程
使用监控数据进行回溯分析:
1 | SELECT SnapshotTime, COUNT(*) AS 阻塞会话数 |
方案优势
- 被动变主动:无需等待问题复现,可随时回溯历史数据进行分析
- 可量化分析:精确统计阻塞频率、持续时间和影响范围,提供数据支持
- 精准定位:明确识别阻塞源 SQL 和阻塞链路,快速定位问题根因
注意事项
权限要求
执行账户需要具备以下权限:
1 | GRANT VIEW SERVER STATE TO [YourMonitoringAccount]; |
作业所有者配置
建议使用 sa 或本地 SQL 账户作为作业所有者,避免域账号验证问题:
1 | -- 查看当前作业所有者 |
存储空间管理
监控数据会持续增长,建议:
- 定期检查
DBAUtility数据库大小 - 根据实际情况调整保留天数(默认 7 天)
- 如需长期保留,可归档至历史表或数据仓库
扩展优化
1. 阈值告警
当阻塞等待时间超过阈值时,通过 Database Mail 发送邮件通知:
1 | -- 在存储过程中添加告警逻辑 |
2. 热点对象分析
统计哪些数据库对象经常被阻塞,指导索引和查询优化:
1 | SELECT |
3. 可视化监控
可将监控数据接入 Grafana、Power BI 等平台,实现图表化展示:
- 阻塞趋势图(时间序列)
- 阻塞热力图(时段分布)
- Top 阻塞源 SQL 排行
相关资源
完整的实现脚本和详细文档:
blocking_capture.sql- 包含建库、建表、存储过程的完整脚本create_job.sql- SQL Server Agent 作业创建脚本README.md- 详细的部署和使用说明文档