SQL2008中SQL应用之-阻塞(Blocking)应用分析_mssql2005

通常短时间的阻塞没有问题,且是较忙的应用程序所需要的。然而,设计糟糕的应用程序会导致长时间的阻塞,这就不必要地锁定了资源,而且阻塞了其他会话读取和更新它们。

在SQL Server中,一个阻塞的进程会无限期地保持阻塞,或者直到它超时(根据set lock_timeout)、服务器关闭、进程被杀死、连接完成了更新或者其他发生在原始事务上的操作导致它释放了资源上的锁。

发生长时间阻塞的原因如下:

1、在一个没有索引的表上的过量的行锁会导致SQL Server得到一个锁,从而阻塞其他事务。

2、应用程序打开一个事务,并在事务保持打开的时候要求用户进行反馈或交互。这通常是让最终用户在GUI上输入数据而保持事务打开的时候发生。此时,事务引用的任何资源都会被占据。

3、事务BEGIN后查询的数据可能在事务事务开始前被调用

4、查询不恰当地使用锁定提示。例如,应用程序仅使用很少的行,但却使用一个表锁提示

5、应用程序使用长时间运行的事务,在一个事务中更新了很多行或很多表(把一个大量更新的事务变成多个更新较少的事务有助于改善并发性)

一、找到并解决阻塞进程

下面我们演示使用SQL Server动态管理视图sys.dm_os_waiting_tasks找出阻塞进程,该视图用于代替早期SQL Server版本中的系统存储过程sp_who

找出阻塞的进程后,我们使用sys.dm_exec_sql_text动态管理函数和sys.dm_exec_Connections(DMV)找出正在执行的查询的SQL文本,然后强制结束进程。

强制结束进程,我们使用kill命令。kill的用法,请参看MSDN:http://msdn.microsoft.com/zh-cn/library/ms173730.aspx

该命令有三个参数:

session ID    要终止的进程的会话 ID。session ID 是在建立连接时为每个用户连接分配的唯一整数 (int)。在连接期间,会话 ID 值与该连接捆绑在一起。连接结束时,则释放该整数值,并且可以将它重新分配给新的连接。使用 KILL session ID 可终止与指定的会话 ID 关联的常规非分布式事务和分布式事务。
UOW    标识分布式事务的工作单元 (UOW) ID。UOW 是可从 sys.dm_tran_locks 动态管理视图的 request_owner_guid 列中获取的 GUID。也可从错误日志中或通过 MS DTC 监视器获取 UOW。有关监视分布式事务的详细信息,请参阅 MS DTC 文档。使用 KILL UOW 可终止孤立的分布式事务。这些事务不与任何真实的会话 ID 相关联,与虚拟的会话 ID = '-2' 相关联。可使标识孤立事务变得更为简单,其方法是查询 sys.dm_tran_locks、sys.dm_exec_sessions 或 sys.dm_exec_requests 动态管理视图中的会话 ID 列。
WITH STATUSONLY    生成由于更早的 KILL 语句而正在回滚的指定 session ID 或 UOW 的进度报告。KILL WITH STATUSONLY 不终止或回滚 session ID 或 UOW,该命令只显示当前的回滚进度。

在第一个查询窗口:

复制代码 代码如下:

BEGIN TRAN
UPDATE Production.ProductInventory
SET Quantity = 400
WHERE ProductID = 1 AND
LocationID = 1

第二个窗口:

复制代码 代码如下:

UPDATE Production.ProductInventory
SET Quantity = 406
WHERE ProductID = 1 AND
LocationID = 1

第三个窗口:

复制代码 代码如下:

SELECT blocking_session_id, wait_duration_ms, session_id
FROM sys.dm_os_waiting_tasks
WHERE blocking_session_id IS NOT NULL

/*
blocking_session_id wait_duration_ms session_id
52 23876 54
*/

可以看出是SessionID为52的会话阻塞了SessionID为54的会话。

那么,52正在干啥坏事呢?在第三个窗口中执行:

复制代码 代码如下:

SELECT t.text
FROM sys.dm_exec_connections c
CROSS APPLY sys.dm_exec_sql_text (c.most_recent_sql_handle) t
WHERE c.session_id = 54

/*
text
(@1 int,@2 tinyint,@3 tinyint)UPDATE [Production].[ProductInventory] set [Quantity] = @1 WHERE
[ProductID]=@2 AND [LocationID]=@3
*/

注意:这并不是第一个查询窗口中的原SQL语句,SQL Server进行了自动参数化计划缓存(预编译)。
我们强制终止会话。在第三个窗口中执行:

复制代码 代码如下:

kill 52

注意:窗口一的语句和窗口二的语句均终止。

提示:第三个语句中,使用sys.dm_exec_connections(DMV)返回了Session ID为53的most_recent_sql_handle列。这是SQL文本在内存中的指针。作为sys.dm_exec_sql_text动态管理函数的输入参数使用。从sys.dm_exec_sql_text返回了text列,该列显示了阻塞进程的SQL文本。如果阻塞成串,必须通过blocking_session_id和session_ID列仔细查看每一个阻塞进程,直到发现原始的阻塞进程。

二、配置语句等待锁释放的时长

如果有一个事务或语句被阻塞,意味着它在等待资源上的锁被释放。我们可以事先通过set lock_Timeout来设定需要等待的时间。

语法如下:SET LOCK_TIMEOUT time_period

参数以毫秒为单位。超过时会返回锁定错误。示例:

在第一个窗口中执行:

复制代码 代码如下:

USE AdventureWorks
BEGIN TRAN
UPDATE Production.ProductInventory
SET Quantity = 400
WHERE ProductID = 1 AND
LocationID = 1

在第二个窗口中执行:

复制代码 代码如下:

USE AdventureWorks
SET LOCK_TIMEOUT 1000
UPDATE Production.ProductInventory
SET Quantity = 406
WHERE ProductID = 1 AND
LocationID = 1

/*
1秒后的执行结果
Msg 1222, Level 16, State 51, Line 3
Lock request time out period exceeded.
The statement has been terminated.
*/

解析:在这个示例中,我们设置了锁超时时间为1000毫秒,即1秒。这个设置不会影响资源被进程占有的时间,只会影响等待另一个进程释放资源访问的时间。

时间: 2024-09-17 21:07:19

SQL2008中SQL应用之-阻塞(Blocking)应用分析_mssql2005的相关文章

SQL2008中SQL应用之-锁定(locking) 应用分析_mssql2005

一.锁的基本概念: 锁定(Locking)是一个关系型数据库系统的常规和必要的一部分,它防止对相同数据作 并发更新 或在更新过程中查看数据, 从而保证被更新数据的完整性.它也能防止用户读取正在被修改的数据 .Sql Server动态地管理锁定,然而,还是很有必要 了解Transact- SQL查询如何影响SQL Server中的锁定.在此,简单介绍下锁的基本常识. 锁定有助于防止并发问题的发生.当一个用户试图读取另一个用户正在修改的数据,或者修改另一个用户正在读取的数据时,或者尝试修改另一个事务

SQL2008中SQL应用之- 死锁(Deadlocking)_mssql2008

在另一方释放资源前,会话1和会话2都不可能继续.所以,SQL Server会选择死锁中的一个会话作为"死锁牺牲品". 注意:死锁牺牲品的会话会被杀死,事务会被回滚. 注意:死锁与正常的阻塞是两个经常被混淆的概念. 发生死锁的一些原因: 1.应用程序以不同的次序访问表.例如会话1先更新了客户然后更新了订单,而会话2先更新了订单然后更新了客户.这就增加了死锁的可能性. 2.应用程序使用了长时间的事务,在一个事务中更新很多行或很多表.这样增加了行的"表面积",从而导致死锁

SQL2008中通过DBCC OPENTRAN和会话查询事务_mssql2005

同样,对事务日志进行备份也只会截断不活动事务的那部分事务日志,所以打开的事务会导致日志变多(甚至达到物理限制),直到事务被提交或回滚. 要找到最早的活动事务,可以使用DBCC OPENTRAN命令.详细用法见MSDN:http://msdn.microsoft.com/zh-cn/library/ms182792.aspx 给出一个示例: 复制代码 代码如下: CREATE TABLE T_Product(PKID int, PName Nvarchar(50)); GO BEGIN TRAN

SQL Server中SELECT会真的阻塞SELECT吗?

在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.TEST WHERE OBJECT_ID =1 这个查询语句,其申请.释放的锁资源的过程如下所示:     而且从最常见的锁模式的兼容性表,我们可以看到IS锁与S锁都是兼容的,也就是说SELECT查询是不会阻塞SELECT查询的. 现有的授权模式 请求的模式 IS S U IX SIX X 意向共享

Oracle RAC环境下的阻塞(blocking blocked)介绍和实例演示_oracle

RAC环境下的阻塞不同于单实例情形,因为我们需要考虑到位于不同实例的session.也就是说之前查询的v$session,v$lock相应的应变化为全局范围来查找.本文提供了2个查询脚本,并给出实例演示那些session为阻塞者,哪些为被阻塞者.有关阻塞的概念以及单实例环境下的阻塞请参考:Oracle 阻塞(blocking blocked) 1.演示环境 scott@DEVDB> select * from v$version where rownum<2; BANNER ---------

RAC环境下的阻塞(blocking blocked)

      RAC环境下的阻塞不同于单实例情形,因为我们需要考虑到位于不同实例的session.也就是说之前查询的v$session,v$lock相应的应变化为全局范围来查找.本文提供了2个查询脚本,并给出实例演示那些session为阻塞者,哪些为被阻塞者.有关阻塞的概念以及单实例环境下的阻塞请参考:Oracle 阻塞(blocking blocked)   1.演示环境 scott@DEVDB> select * from v$version where rownum<2; BANNER -

SqlServer中如何解决session阻塞问题_MsSql

简介 对于数据库运维人员来说创建session或者查询时产生问题是常规情况,下面介绍一种很有效且不借助第三方工具的方式来解决类似问题. 最近开始接触运维工作,所以自己总结一些方案便于不懂数据库的同事解决一些不太紧要的数据库问题.类似方法很多理论也很多,我就不做深究,就是简单写一个方案,便于菜鸟使用的. 阻塞理解 在Sql Server 中当一个数据库会话中的事务正锁定一个或多个其他会话事务想要读取或修改的资源时,会产生阻塞(Blocking).通常短时间的阻塞没有问题,且是较忙的应用程序所需要的

SqlServer中如何解决session阻塞问题

简介 对于数据库运维人员来说创建session或者查询时产生问题是常规情况,下面介绍一种很有效且不借助第三方工具的方式来解决类似问题. 最近开始接触运维工作,所以自己总结一些方案便于不懂数据库的同事解决一些不太紧要的数据库问题.类似方法很多理论也很多,我就不做深究,就是简单写一个方案,便于菜鸟使用的. 阻塞理解 在Sql Server 中当一个数据库会话中的事务正锁定一个或多个其他会话事务想要读取或修改的资源时,会产生阻塞(Blocking).通常短时间的阻塞没有问题,且是较忙的应用程序所需要的

后缀-sql2008中mdf文件怎么打开?

问题描述 sql2008中mdf文件怎么打开? 如题,我在做课程设计,急求大神回复帮忙啊,Microsoft SQL Server Query File (.sql)的文件后缀可以顺利打开,用的是vs2012和sql server2008 解决方案 点击新建的数据库,右键附加,然后选择mdf文件的位置,燃机确定,就可以了 解决方案二: 在sql server里面新建一个数据库,然后附加数据库文件 解决方案三: 日语一级证9日语一级证10日语以级证4 解决方案四: 其实MDF就是一个数据库的数据文