SQL Server 阻塞排除的 2 方法
背景知识:
是什么造成了阻塞?
从锁的观点来看、可访问对象前一定要对对象加锁不管你是读还是写,如果用户A以经持有对象,说明A以在对象上加锁,如果这时B
也想访问这个对象、它也要对对象加锁。重点来了如果A用户加的是排它锁,B用户可以做的就是乖乖等A用完再说。B乖乖等这个问题
就是阻塞,是因为这两把锁不可以共存才造成了阻塞。
场景再现:
为在再现场景我们要开三个通向数据的连接。就是说要打开三个managerment studio 或是开三个sqlcmd。我用ssms(SQL Server Managerment Studio)为例
先为场景做点准备,代码如下。
use Studio;
go
create table TestTable (ID int not null,String nchar(10));
go
declare @i as int =1;
while @i<10
begin
insert into TestTable(ID,String) values(@i,REPLICATE(cast(@i as nchar(1)),10));
set @i = @i +1;
end;
go
select T.ID,T.String from TestTable as T;
go

连接A运行如下代码:
begin tran
update dbo.TestTable
set String = 'AAA'
where ID=1;
go --可以看到A会一直持有第一行上的排它锁,直到事务被commit 或 rollback!
连接B运行如下代码:
update dbo.TestTable
set String = 'BBB'
where ID=1;
go -- 因A以在ID=1这一行上有排它锁,所以B只可以乖乖的等,这就造成了阻塞。下图可以看出B等了2分多钟了。

C连接用来解除阻塞,运行代码马上就讲。
方法 1、 从锁入手
第一步、看谁在等待资源,以确定谁被阻塞、运行如下代码
select
tra.request_session_id as [SessionID],-- 会话名
DB_NAME(tra.resource_database_id) as [DBName],-- 数据库名
tra.resource_type as [resourceType],-- 资源类型
tra.resource_associated_entity_id as [ResourceID],--资源ID
tra.request_status as [Status] --状态
from sys.dm_tran_locks as tra
where tra.request_session_id>50;
go

-- 下图中可以看出有一行是wait 说明它在等别人,释放资源。
所以 54 是在等别人,它等谁呢?从图上可以看出 51 持有54在等待对象的排它锁,说明54在等51。
第二步、定位等的是哪个资源:
运行如下代码
select OBJECT_NAME(565577053);--565577053来自于图上的倒数第二行。
go
第三步、查看因为什么操作造成阻塞:
到目前为止,sys.dm_tran_locks只能帮我们到这里下,我们需要新的武器
sys.dm_exec_connections
select
con.session_id as [SessionID],
con.connect_time as[ConnectTime],
con.most_recent_sql_handle as [SqlHandle]
from sys.dm_exec_connections as con
where session_id in (51,54);
go

most_recent_sql_handle 返回连接最后执行SQL语句的指针,注意它不一定就是移动存造成阻塞的原因,它只是最后执行
的SQL语句。
要看代码这就要用到我们的第三件武器了 sys.dm_exec_sql_text( )函数
select
con.session_id as [SessionID],
sqlt.text
from sys.dm_exec_connections as con cross apply sys.dm_exec_sql_text(con.most_recent_sql_handle) as sqlt
where session_id in (51,54);
go

第四步:
解除阻塞,经过上面的三步阻塞的原因基本上以有所了解了。
我们只要把长期占着资源的连接kill(杀死)掉就行了,本例中,是51号连接长占资源不放,所以要kill它。
kill 51;
go
方法 2、
下面我们从任务(task)的角度来看问题、阻塞也就是一个任务在等待另一个任务的执行完成,只要找到它在等谁,再把引起等待的任务kill、当然
任务是不可以kill的,但是我们不是可以曲线救国吗?kill掉它的连接啊,对吧。
第一步:
找到引起阻塞的进程ID
select
task.session_id,
task.wait_duration_ms,task.
blocking_session_id
from sys.dm_os_waiting_tasks as task
where task.blocking_session_id is not null;
go
-- 方法1时我以把阻塞排除,下图是一个新的阻塞,所以session_ID上会不一样。

第二步:
接下来就是用
sys.dm_exec_connections, sys.dm_exec_sql_text,kill来排除阻塞了,用法如方法1中所说。
第三步:
kill 52;
SQL Server 阻塞排除的 2 方法的更多相关文章
- 需要我们了解的SQL Server阻塞原因与解决方法
需要我们了解的SQL Server阻塞原因与解决方法 上篇说SQL Server应用模式之OLTP系统性能分析.五种角度分析sql性能问题.本章依然是SQL性能 五种角度其一“阻塞与死锁” 这里通过连 ...
- sql server 阻塞与锁
SQL Server阻塞与锁 在讨论阻塞与加锁之前,需要先理解一些核心概念:并发性.事务.隔离级别.阻塞锁及死锁. 并发性是指多个进程在相同时间访问或者更改共享数据的能力.一般情况而言,一个系统在互不 ...
- Sql Server 2012 的新分页方法分析(offset and fetch) - 转载
最近在分析 Sql Server 2012 中 offset and fetch 的新特性,发现 offset and fetch 无论语法的简洁还是功能的强大,都是相当相当不错的 其中 offset ...
- 最简单删除SQL Server中所有数据的方法
最简单删除SQL Server中所有数据的方法 编写人:CC阿爸 2014-3-14 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间 ...
- SQL Server日志文件庞大收缩方法(实测好用)
原文:SQL Server日志文件庞大收缩方法(实测好用) 这两个命令连续执行,间隔时间越少越明显(可多次运行),直到达到效果 --截断 BACKUP LOG CloudMonitor TO DISK ...
- SQL Server 性能优化之——系统化方法提高性能
SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...
- SQL server分页的四种方法
SQL server分页的四种方法 1.三重循环: 2.利用max(主键); 3.利用row_number关键字: 4.offset/fetch next关键字 方法一:三重循环思路 先取前20页, ...
- SQL Server 阻塞分析
一.加锁(locking).阻塞(blocking).死锁(deadlock)定义 加锁:用于管理多个连接的进程.当连接需要访问一块数据时,在这些数据上放置某种类型的锁. 阻塞 ...
- Sql Server 阻塞的常见原因和解决办法
1. 由于语句运行时间太长而导致的阻塞,语句本身在正常运行中,只须等待某些系统资源 解决办法: a. 语句本身有没有可优化的空间 b. Sql Server 整体性能如何,是不是有资源瓶颈影响了语句执 ...
随机推荐
- project euler 25 fibonacci
数学方法: Saying that a number contains 1000 digits is the same as saying that it's greater than 10**999 ...
- 用IO流拷贝歌曲
package lianxi; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOEx ...
- 夏宇闻教授谈FPGA工程师的入门学习
1. 必须清楚自己究竟适合不适合做工程师. 看看自己的性格特点,是不是特别安静,又耐得住寂寞.因为FPGA工程师是一个辛苦的工作,不但要通过不断学习研究提升自己的设计水平,还要经常性的熬夜加班敲写代码 ...
- python每次处理一个字符的三种方法
python每次处理一个字符的三种方法 a_string = "abccdea" print 'the first' for c in a_string: print ord(c) ...
- Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found
Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found 利用Qt Creator编译工程时,出现如题目所示的错误,其中红色部 ...
- Linux环境Nginx安装多版本PHP
php5.4.44 所谓多版本多版本PHP就是php5.4和5.5以及其他版本在同一台服务器. 假如php5.5是主版本已经安装在/usr/local/php目录下,那么再安装其他版本的php再指定不 ...
- 【C语言】输入一组整数,求出这组数字子序列和中最大值
//输入一组整数.求出这组数字子序列和中最大值 #include <stdio.h> int MAxSum(int arr[],int len) { int maxsum = 0; int ...
- 关于iOS多线程,你看我就够了
在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项.当然也会给出几种多线程的案例,在实际使用中感受它们的区别.还有一点需要说明的是,这篇文章将会使 用 Swift ...
- VLC各个Module模块之间共享变量的实现方法
在做VLC开发的时候,想使用一个模块访问另外一个模块的数据, 比如在网络模块得到了一些数据,想在其他模块得到这些数据进行处理,这时候就需要两个模块共享一些变量. 查看VLC的源码,发现VLC专门有va ...
- 理解MVC路由配置(转)
在上一篇文章中,我简短的谈了一下MVC的底层运行机制,如果对MVC还不是很了解的朋友,可以作为入门的参照.接下来,我开始介绍关于URL路由的相关知识.URL路由不是MVC独有的,相反它是独立于MVC而 ...