SqlServer 表选项LOCK_ESCALATION对分区的影响

SqlServer 表选项LOCK_ESCALATION对分区的影响,第1张

概述SqlServer 使用锁管理器跟踪数据库对象是否被锁住.通常一个查询将锁住一行或者一页,当锁超过一定范围之后,SqlServer尝试将锁升级为表锁来保证对内存的使用.锁升级有时会导致堵塞或者死锁.在SQL Server profiler中我们可以用[Lock:Escalation]事件来跟踪锁的升级. 在SQL Server 2005 中,可以使用跟踪标志 1211 来禁用整个实例中的锁升级.而


sqlServer 使用锁管理器跟踪数据库对象是否被锁住.通常一个查询将锁住一行或者一页,当锁超过一定范围之后,sqlServer尝试将锁升级为表锁来保证对内存的使用.锁升级有时会导致堵塞或者死锁.在sql Server profiler中我们可以用[Lock:Escalation]事件来跟踪锁的升级.



在sql Server 2005 中,可以使用跟踪标志 1211 来禁用整个实例中的锁升级.而在sql Server 2008中,可以使用新的选择来禁止某个表的锁升级

ALTER table SET (LOCK_ECALATION = auto | table | disABLE)


auto

选项允许 sql Server 数据库引擎选择适合于表架构的锁升级粒度。

(auto:如表已分区,将使用分区的hobt锁,但并发情况增加。)

如果该表已分区,则允许将锁升级到分区。 锁升级到分区级别之后,该锁以后将不会升级到 table 粒度。

如果该表未分区,则会将锁升级到 table 粒度

table

无论表是否已分区,都会在表级粒度完成锁升级。 默认值为 table

disABLE

在大多数情况下禁止锁升级。 表级别的锁未完全禁止。

例如,当扫描在可序列化隔离级别下没有聚集索引的表时,数据库引擎必须使用表锁来保证数据的完整性。




经过几次插入数据测试,使我要更改的这个条件的数据达到6500行,这样才进行锁升级。否则键锁和页锁非常多。

--分区1:6500行select COUNT(*) from dbo.AABB where $partition.pf_sID(sID)=1

--先测试表:tableALTER table dbo.AABB SET (LOCK_ESCALATION = table);

begin tran 	update dbo.AABB set num=1	where sID=0x0105000000000005150000002B5CA2768377FDF37E993215F4010000	SELECT resource_type,resource_subtype,resource_description,request_mode,resource_associated_entity_ID	from sys.dm_tran_locks 	where resource_database_ID=DB_ID() and request_session_ID=@@SPID  	order by resource_type,resource_descriptionrollback tran


可以看到,对象表使用了排他锁,这样整个表都不能访问了!


--再测试表:autoALTER table dbo.AABB SET (LOCK_ESCALATION = auto);



这才是正常的!!只锁定其中1个分区,其他分区还可以访问和修改!(关联的分区ID不一样,因测试换了几次表)

当我们把表分区的时候,设置表选项 ALTER table dbo.[tablename] SET (LOCK_ESCALATION = auto);这样可以在不同分区并行访问!


附加脚本:

--	查看分区情况select OBJECT_name(object_ID) as tab,COUNT(partition_number) as part   from sys.partitions   where index_ID in(0,1)  and OBJECT_name(object_ID) not like 'conflict%'  and OBJECT_name(object_ID) not like 'sys%'  group by object_ID order by tab  --	批量设置表选项——启用锁升级到分区DECLARE @tbname	VARCHAR(50)DECLARE cur SCRolL CURSOR FOR 		select OBJECT_name(object_ID) as tab	from sys.partitions   	where index_ID in(0,1)  	and OBJECT_name(object_ID) not like 'conflict%'  	and OBJECT_name(object_ID) not like 'sys%'  	group by object_ID 	having COUNT(partition_number)>1	order by tabOPEN curFETCH NEXT FROM cur INTO @tbnameWHILE @@FETCH_STATUS = 0BEGIN	PRINT ('ALTER table dbo.'+@tbname+' SET (LOCK_ESCALATION = auto); ')	FETCH NEXT FROM cur INTO @tbnameENDCLOSE curDEALLOCATE cur



附加说明:

触发锁升级:(数据库引擎不会将行锁或键范围锁升级到页锁,而是将它们直接升级到表锁)

A 单个 Transact-sql 语句在单个无分区表或索引上获得至少 5,000 个锁

B 单个 Transact-sql 语句在已分区表的单个分区上获得至少 5,000 个锁,并且 ALTER table SET LOCK_ESCALATION 选项设为 auto

C 数据库引擎实例中的锁的数量超出了内存或配置阈值

D 如果由于锁冲突导致无法升级锁,则数据库引擎每当获取 1,250 个新锁时便会触发锁升级

总结

以上是内存溢出为你收集整理的SqlServer 表选项LOCK_ESCALATION对分区的影响全部内容,希望文章能够帮你解决SqlServer 表选项LOCK_ESCALATION对分区的影响所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1160761.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存