此实例承载SharePoint 2007数据库(SP)。我们一直在针对SP内容数据库中一个频繁使用的表遇到许多SELECT / INSERT死锁。我缩小了涉及的资源,这两个过程都需要对非聚集索引进行锁定。
INSERT在SELECT资源上需要IX锁,而SELECT在INSERT资源上需要S锁。死锁图描述了三个资源:1。SELECT中的两个(生产者/消费者并行线程)和2.)INSERT。
我附上了死锁图供您查看。因为这是Microsoft代码和表结构,所以我们无法进行任何更改。
但是,我已经在MSFT SP站点上阅读了他们建议将MAXDOP实例级别的配置选项设置为1。由于此实例在许多其他数据库/应用程序之间共享,因此不能禁用此设置。
因此,我决定尝试防止这些SELECT语句并行执行。我知道这不是解决方案,而是临时的修改,以帮助进行故障排除。因此,这样做后,我将“并行计算的成本阈值”从我们的标准25提高到了40,即使工作负载没有改变(SELECT / INSERT频繁发生),死锁也消失了。我的问题是为什么?
SPID 356 INSERT在属于非聚集索引的页面上具有IX锁
SPID 690 SELECT执行ID 0在属于同一非聚集索引的页面上具有S锁
现在
SPID 356希望在SPID 690资源上获得IX锁,但由于SPID 356被SPID 690执行ID 0阻止而无法获得IX锁
SPID 690执行ID 1希望在SPID 356资源上获得S锁,但由于SPID 690执行ID无法获得它SPID 356阻止了1,现在我们陷入僵局。
如果有人可以帮助我理解为什么我会非常感激。
EventReceivers表。
id uniqueidentifier否16
名称nvarchar否512
SiteId uniqueidentifier否16
WebId uniqueidentifier否16
HostId uniqueidentifier否16
HostType int否4
ItemId int否4
DirName nvarchar否512
LeafName nvarchar否256
Type int否4
SequenceNumber int否4
汇编nvarchar否512
类nvarchar否512
数据nvarchar否512
过滤器nvarchar否512
SourceId tContentTypeId否512
SourceType int否4
Credential int否4
ContextType varbinary否16
ContextEventType varbinary否16
ContextId varbinary否16
ContextObjectId varbinary否16
ContextCollectionId varbinary否16
index_name index_description index_keys
EventReceivers_ByContextCollectionId非聚集在PRIMARY SiteId上,ContextCollectionId
EventReceivers_ByContextObjectId非聚集在PRIMARY SiteId上,ContextObjectId
EventReceivers_ById非聚集,唯一在PRIMARY SiteId
上,IRIM事件类型ContextId,ContextType,ContextEventType,SequenceNumber,Assembly,Class
EventReceivers_IdUnique非聚集,唯一,唯一键位于PRIMARY Id上
proc_InsertEventReceiver
和proc_InsertContextEventReceiver
做什么?为了减少并行度,为什么不直接影响这些语句(使用MAXDOP 1),而不是对服务器范围的设置进行混淆呢?