检测SQLServer的阻塞与查看MSSQL会话信息

来源:这里教程网 时间:2026-03-02 12:24:20 作者:

select t.session_id as waiting_session_id, db_name(l.resource_database_id),t.wait_duration_ms/60 as duration_in_seconds,t.waiting_task_address,l.request_mode,l.resource_type,l.resource_associated_entity_id,l.resource_description lock_resource_desc,t.wait_type,t.blocking_session_id,t.resource_description as blocking_resource_desc  from sys.dm_os_waiting_tasks t join sys.dm_tran_locks l on t.resource_address = l.lock_owner_addresswhere t.session_id > 50 而后分别用不同会话运行以下语句: 会话1: begin transelect * from t1;update t1 set name = 'DDDDDD' where id = 1 会话2:alter table t1 add  col2 varchar(100) 可以使用以上的sys.dm_os_waiting_tasks与sys.dm_tran_locks相关的语句,查询到对应的信息: 一般来说,解决阻塞问题主要有以下几个方案: 1. 杀掉会话2. 让SQLServer的事务尽量短小3. 事务应当持有的锁的数量应当最小化4. 如果是读写阻塞可以考虑使用读写分离或者业务能容忍的话使用read uncommitted隔离级别 -- 监控脚本:查询当前访问 SQL Server 2017 的客户端及其执行的 SQL 语句 -- 作者:Grok -- 日期:2025-08-31 -- 说明:此脚本使用动态管理视图(DMV)实时监控用户会话(排除系统会话 session_id <= 50)。 -- 输出包括客户端 IP、主机名、程序名、登录名、会话状态、当前执行的 SQL 语句等。 -- 建议:作为 SQL Agent Job 定期运行,或在 SSMS 中手动执行。 -- 权限要求:需要 VIEW SERVER STATE 权限。 SELECT      s.session_id AS [Session ID],                  -- 会话 ID     c.client_net_address AS [Client IP],           -- 客户端 IP 地址     s.host_name AS [Host Name],                    -- 客户端主机名     s.program_name AS [Program Name],              -- 连接程序名(如 'Microsoft SQL Server Management Studio' 或应用名)     s.login_name AS [Login Name],                  -- 登录用户名     s.status AS [Session Status],                  -- 会话状态(running, sleeping, suspended 等)     r.blocking_session_id AS [Blocking Session ID],-- 如果被阻塞,显示阻塞会话 ID(0 表示无阻塞)     r.wait_type AS [Wait Type],                    -- 等待类型(如果在等待,如 LCK_M_S 表示锁等待)     r.wait_time AS [Wait Time (ms)],               -- 等待时间(毫秒)     DB_NAME(r.database_id) AS [Database Name],     -- 当前数据库名     r.command AS [Command Type],                   -- 命令类型(如 SELECT, UPDATE)     SUBSTRING(t.text, (r.statement_start_offset/2) + 1,                 ((CASE r.statement_end_offset                  WHEN -1 THEN DATALENGTH(t.text)                 ELSE r.statement_end_offset END                  - r.statement_start_offset)/2) + 1) AS [Executing SQL Statement],  -- 当前执行的 SQL 语句片段     t.text AS [Full Batch Text],                   -- 完整批处理 SQL 文本     r.start_time AS [Request Start Time],          -- 请求开始时间     r.cpu_time AS [CPU Time (ms)],                 -- 已使用 CPU 时间(毫秒)     r.total_elapsed_time AS [Elapsed Time (ms)],   -- 总执行时间(毫秒)     r.reads AS [Physical Reads],                   -- 物理读次数     r.writes AS [Writes],                          -- 写次数     r.logical_reads AS [Logical Reads]             -- 逻辑读次数 FROM      sys.dm_exec_sessions s LEFT JOIN      sys.dm_exec_requests r ON s.session_id = r.session_id LEFT JOIN      sys.dm_exec_connections c ON s.session_id = c.session_id OUTER APPLY      sys.dm_exec_sql_text(r.sql_handle) t  -- 获取 SQL 文本 WHERE      s.session_id > 50  -- 排除系统会话,只监控用户会话     AND s.is_user_process = 1  -- 只包括用户进程 ORDER BY      r.total_elapsed_time DESC,  -- 按执行时间降序排序,突出慢查询     s.session_id;              -- 其次按会话 ID 排序 -- 使用说明: -- 1. 在 SSMS 中运行此查询,即可实时查看客户端和 SQL 语句。 -- 2. 如果需要自动化监控,可创建 SQL Agent Job,每 1-5 分钟运行,并将结果插入日志表: --    CREATE TABLE MonitoringLog (LogTime DATETIME, SessionID INT, ClientIP VARCHAR(50), SQLText NVARCHAR(MAX), ...); --    INSERT INTO MonitoringLog SELECT GETDATE(), session_id, client_net_address, text, ... FROM ...; -- 3. 如果有阻塞,关注 Blocking Session ID > 0 的行,进一步调查阻塞链。 -- 4. 性能提示:此查询开销低,但高峰期频繁运行可能略增负载;限制 TOP 100 以优化。 -- 5. 扩展:结合 Extended Events 捕获历史数据: --    CREATE EVENT SESSION [SessionMonitor] ON SERVER  --    ADD EVENT sqlserver.sql_statement_completed( WHERE session_id > 50 );

相关推荐