SQLServer如何监控阻塞会话
一、查询阻塞和被阻塞的会话
SELECT
r.session_id AS [Blocked Session ID],
r.blocking_session_id AS [Blocking Session ID],
r.wait_type,
r.wait_time,
r.wait_resource,
s1.program_name AS [Blocked Program Name],
s1.login_name AS [Blocked Login],
s2.program_name AS [Blocking Program Name],
s2.login_name AS [Blocking Login],
r.text AS [SQL Text]
FROM sys.dm_exec_requests AS r
LEFT JOIN sys.dm_exec_sessions AS s1 ON r.session_id = s1.session_id
LEFT JOIN sys.dm_exec_sessions AS s2 ON r.blocking_session_id = s2.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS r
WHERE r.blocking_session_id <> 0;
二、找出阻塞的具体SQL
SELECT
r.session_id,
r.blocking_session_id,
t.text AS [SQL Text],
r.wait_type,
r.wait_time,
r.wait_resource
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
WHERE r.blocking_session_id <> 0;
三、编写C#程序,每隔10秒监控SQL Server数据库中的阻塞会话,定位出阻塞的根源会话并终止它们,同时记录日志。
using System;
using System.Data.SqlClient;
using System.IO;
using System.Timers; class Program
{
private static Timer timer;
private static string connectionString = "your_connection_string_here"; static void Main(string[] args)
{
timer = new Timer(10000); // 每10秒执行一次
timer.Elapsed += CheckForBlockingSessions;
timer.AutoReset = true;
timer.Enabled = true; Console.WriteLine("Press [Enter] to exit the program.");
Console.ReadLine();
} private static void CheckForBlockingSessions(object source, ElapsedEventArgs e)
{
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open(); string query = @"
SELECT
r.session_id AS BlockedSessionID,
r.blocking_session_id AS BlockingSessionID,
r.text AS SqlText
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS r
WHERE r.blocking_session_id <> 0;"; using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int blockedSessionId = reader.GetInt32(0);
int blockingSessionId = reader.GetInt32(1);
string sqlText = reader.GetString(2); LogBlockingSession(blockedSessionId, blockingSessionId, sqlText);
KillSession(blockingSessionId);
}
}
}
}
}
catch (Exception ex)
{
LogError(ex.Message);
}
} private static void KillSession(int sessionId)
{
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string killQuery = $"KILL {sessionId};";
using (SqlCommand killCommand = new SqlCommand(killQuery, connection))
{
killCommand.ExecuteNonQuery();
LogKillSession(sessionId);
}
}
}
catch (Exception ex)
{
LogError($"Failed to kill session {sessionId}: {ex.Message}");
}
} private static void LogBlockingSession(int blockedSessionId, int blockingSessionId, string sqlText)
{
string logMessage = $"[{DateTime.Now}] Blocked Session ID: {blockedSessionId}, Blocking Session ID: {blockingSessionId}, SQL Text: {sqlText}";
File.AppendAllText("blocking_sessions.log", logMessage + Environment.NewLine);
Console.WriteLine(logMessage);
} private static void LogKillSession(int sessionId)
{
string logMessage = $"[{DateTime.Now}] Killed Session ID: {sessionId}";
File.AppendAllText("killed_sessions.log", logMessage + Environment.NewLine);
Console.WriteLine(logMessage);
} private static void LogError(string message)
{
string logMessage = $"[{DateTime.Now}] Error: {message}";
File.AppendAllText("errors.log", logMessage + Environment.NewLine);
Console.WriteLine(logMessage);
}
}
说明
- 连接字符串:替换
your_connection_string_here为实际的数据库连接字符串。 - 定时器:使用
System.Timers.Timer类设置每10秒执行一次检查。 - 检查阻塞会话:在
CheckForBlockingSessions方法中,查询阻塞会话和根源会话的信息。 - 终止会话:在
KillSession方法中,执行KILL命令来终止阻塞会话。 - 日志记录:日志记录包括阻塞会话的详细信息和终止会话的操作,以及错误信息。
注意事项
- 运行此程序需要确保有足够的权限来访问数据库和执行
KILL命令。 - 请仔细测试程序以确保其符合预期行为,尤其是在生产环境中。
- 日志文件的路径和权限需要根据实际情况进行配置。
周国庆
2024/5/28
SQLServer如何监控阻塞会话的更多相关文章
- sqlserver监控阻塞(死锁)具体情况
公司sqlserver的监控系统主要是采用zabbix监控,但是zabbix的监控只能通过性能计数器给出报警,而无法给出具体的阻塞情况,比如阻塞会话.语句.时间等,所以需要配合sqlserver的一些 ...
- sqlserver监控阻塞(死锁)具体情况(转)
公司sqlserver的监控系统主要是采用zabbix监控,但是zabbix的监控只能通过性能计数器给出报警,而无法给出具体的阻塞情况,比如阻塞会话.语句.时间等,所以需要配合sqlserver的一些 ...
- SQLSERVER性能监控级别步骤
SQLSERVER性能监控级别步骤 下面先用一幅图描述一下有哪些步骤和顺序 1.识别瓶颈 识别瓶颈的原因包括多个方面,例如,资源不足,需要添加或升级硬件: 工作负荷在同类资源之间分布不均匀,例如,一个 ...
- 如何定位Oracle数据库被锁阻塞会话的根源
首先再次明确下,数据库因为要同时保证数据的并发性和一致性,所以操作有锁等待是正常的. 只有那些长时间没有提交或回滚的事物,阻塞了其他业务正常操作,才是需要去定位处理的. 1.单实例环境 2.RAC环境 ...
- SQLServer数据库监控代码
SQLServer数据库监控代码: creation_time, total_worker_time, last_worker_time, max_worker_time, min_worker_ti ...
- 现在的SQLSERVER数据库监控软件有哪些?
现在的SQLSERVER数据库监控软件有哪些? 收集了一下当前SQLSERVER数据库监控软件,发现开源免费的真的是“没有” Questsoftware Quest's spotlight(收费) ...
- 【SQL Server DBA】日常巡检语句3:特定监控(阻塞、top语句、索引、作业)
原文:[SQL Server DBA]日常巡检语句3:特定监控(阻塞.top语句.索引.作业) 1.查询阻塞信息.锁定了哪些资源 --1.查看阻塞信息 select spid,loginame,wai ...
- Oracle阻塞会话源头查找-单机和RAC环境
在写 Oracle session相关数据字典(一) 这篇文章时,提到使用v$session视图的树形查询可以得到Oracle锁树,这样就便于我们找出阻塞会话的源头,但是仅仅可以在单机环境中使用.今 ...
- MySQL的共享锁阻塞会话案例浅析输入日志标题
这是问题是一个网友遇到的问题:一个UPDATE语句产生的共享锁阻塞了其他会话的案例,对于这个案例,我进一步分析.总结和衍化了相关问题.下面分析如有不对的地方,敬请指正.下面是初始化环境和数据的 ...
- zabbix自定义监控(当会话登录超过三个就报警)
安装过程在此省略. 1.agent端去修改配置文件 2.调用自定义内容 vim /etc/zabbix/zabbix_agentd.d/login.conf UserParameter=login-u ...
随机推荐
- jenkins 持续集成和交付——pipeline(五)
前言 整理一下pipeline. 正文 介绍 什么是pipeline呢? 根据前面的所得,我们知道,以前都是模板形式,但是如果有些复杂的项目,需要用更加自定义的写法,那么就有了pipeline,也就是 ...
- SpringBoot学习:文件上传和下载
maven导入依赖 首先创建一个maven项目,然后加入以下配置,就创建好了一个springboot项目 <parent> <groupId>org.springframewo ...
- esp8266,arduino,网页显示dht11温湿度,控制继电器开关,局域网智能家居
不说了,上代码,用arduino实现esp8266代码 #include <ESP8266WiFi.h> #include <WiFiClient.h> #include &l ...
- 欢迎 Llama 3:Meta 的新一代开源大语言模型
介绍 Meta 公司的 Llama 3 是开放获取的 Llama 系列的最新版本,现已在 Hugging Face 平台发布.看到 Meta 持续致力于开放 AI 领域的发展令人振奋,我们也非常高兴地 ...
- 评审恩仇录——IDE也能做代码评审?
简介: 云效Codeup推出了本地IDE插件端的评审,免除了黄药师来回华山的奔波之苦 现代科技公司的同事们平日一起交流开发规约和产品需求,肩上共同扛着业务发展和同行竞争的压力,这份还书贻剑的情谊如何能 ...
- 深度解析开源推荐算法框架EasyRec的核心概念和优势
简介:如何通过机器学习PAI实现快速构建推荐模型 作者:程孟力 - 机器学习PAI团队 随着移动app的普及,个性化推荐和广告成为很多app不可或缺的一部分.他们在改善用户体验和提升app的收益方面 ...
- KubeVela 成为 CNCF 沙箱项目,让云端应用交付更加简单
简介: KubeVela 就是这样一个面向用户的上层平台项目.对于业务开发者来说,KubeVela 简单.易用,它可以让开发者以极低的心智负担和上手成本在 Kubernetes 上定义与部署应用... ...
- [FE] Quasar 变通 loading 单纯使用遮罩效果的方法
Quasar 的 loading 组件是提供加载中的遮罩效果的. 如果你不想要 loading 的效果,只想保留遮罩效果,那么你可以通过 show() 方法的参数进行调整. 把 spinnerSize ...
- [FAQ] JS 时间戳格式化为 date
拷贝使用,不用引入第三方库 function formatDate (date = 0, fmt = 'yyyy-MM-dd hh:mm:ss') { date = new Date(+date) i ...
- js部分数组方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...