- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
最近在一个客户端的OLTP box (Sql server 2005)上遇到了死锁的情况发现这是由两个不同的线程调用两个存储过程引起的。
1、向X表插入数据的Insert sp。
Insert Into X (col1 , col2 , col3 )
Values ('value 1' , 'value 2' , 'value 3' )
2、Delete sp,从X表中删除数据。
DELETE X
FROM X T1 WITH (NOLOCK)
INNER JOIN Y T2 WITH (NOLOCK)
ON T1.[col2] = T2.[col2]
WHERE t2.date < 'date time value'
X 表有一个唯一的聚簇主键和两个非聚簇的非唯一索引。我通过将 t1222 tace 标志设置为 on 来分析死锁,输出总结如下;
Insert sp 在列 1 的非聚集索引上获得了 IX 锁。 在此期间,删除 sp 正在等待第 1 列的同一非聚集索引上的 X 锁。
删除 sp 获取了列 2 的非聚集索引上的 U 锁。 在此期间,Insert sp 正在等待第 2 列的同一非聚集索引上的 IX 锁。
任何避免死锁的想法或建议都将不胜感激。
编辑
跟踪标志 t1222 的输出
deadlock-list
deadlock victim=process3c77d68
process-list
process id=process3c12c58 taskpriority=0 logused=1044 waitresource=PAGE: 17:8:7726 waittime=1250 ownerId=5169682909 transactionname=user_transaction lasttranstarted=2011-02-03T03:34:03.443 XDES=0xfe64d78b0 lockMode=IX schedulerid=2 kpid=9544 status=suspended spid=219 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-02-03T03:34:03.457 lastbatchcompleted=2011-02-03T03:34:03.453 clientapp=.Net SqlClient Data Provider hostname=HQMTSRV026 hostpid=3308 loginname=EASUser isolationlevel=read committed (2) xactid=5169682909 currentdb=17 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=adhoc line=1 stmtend=296 sqlhandle=0x0200000084ce2a1d0e95a5623fa3a9c0981d422e33cab999
(@1 int<c/>@2 varchar(8000)<c/>@3 nvarchar(4000))INSERT INTO [VB_Audit_TransactionDetail]([ItemID]<c/>[TransactionID]<c/>[ItemValue]) values(@1<c/>@2<c/>@3)
frame procname=adhoc line=1 stmtend=296 sqlhandle=0x02000000afcb1733f435fb93e13556600acf32bb32e10020
Insert Into VB_Audit_TransactionDetail (ItemID <c/> TransactionID <c/> ItemValue ) Values (4 <c/> '0255978c-f56e-477e-b361-8abe62433cff' <c/> N'HQOLB006' )
frame procname=EAS.dbo.SP_Insert line=13 stmtstart=482 stmtend=522 sqlhandle=0x03001100805efa5997d69400719600000100000000000000
exec (@CommandText)
inputbuf
Proc [Database Id = 17 Object Id = 1509580416]
process id=process3c77d68 taskpriority=0 logused=364 waitresource=PAGE: 17:6:334008 waittime=1234 ownerId=5169682116 transactionname=user_transaction lasttranstarted=2011-02-03T03:34:03.053 XDES=0xa8e297cd0 lockMode=X schedulerid=12 kpid=10300 status=suspended spid=327 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-02-03T03:33:41.137 lastbatchcompleted=2011-02-03T03:33:41.133 clientapp=Microsoft SQL Server hostname=HQSSISSRV002 hostpid=7632 loginname=NBKDOM\SQLCSRVC isolationlevel=read committed (2) xactid=5169682116 currentdb=17 lockTimeout=4294967295 clientoption1=671350816 clientoption2=128056
executionStack
frame procname=EAS.dbo.PurgeAuditTransactionTables line=59 stmtstart=4202 stmtend=4728 sqlhandle=0x030011006354a2313d11ae00979a00000100000000000000
DELETE [dbo].[Audit_TransactionDetail]
FROM [dbo].[Audit_TransactionDetail] T1 WITH (NOLOCK)
INNER JOIN [dbo].[Audit_NBKTransaction] T2 WITH (NOLOCK)ON T1.[TransactionID] = T2.[TransactionID]
WHERE TransactionPostedDateTime < @LastReplicationDateTime
frame procname=adhoc line=1 sqlhandle=0x0100110096968c0560c430ff190000000000000000000000
EXEC PurgeAuditTransactionTables '02 Feb 2011 19:00:13:870'
inputbuf
EXEC PurgeAuditTransactionTables '02 Feb 2011 19:00:13:870'
resource-list
pagelock fileid=8 pageid=7726 dbid=17 objectname=EAS.dbo.Audit_TransactionDetail id=lock4f79500 mode=U associatedObjectId=886415243542528
owner-list
owner id=process3c77d68 mode=U
waiter-list
waiter id=process3c12c58 mode=IX requestType=wait
pagelock fileid=6 pageid=334008 dbid=17 objectname=EAS.dbo.Audit_TransactionDetail id=lock846afca00 mode=IX associatedObjectId=604940266831872
owner-list
owner id=process3c12c58 mode=IX
waiter-list
waiter id=process3c77d68 mode=X requestType=wait
还有一件重要的事;删除和插入语句总是涉及 2 个不同的数据集。
最佳答案
与其发布您对死锁图的理解的描述,不如发布死锁图本身。 XML,而不是图形渲染的位图。乍一看,涉及的 IX 锁存在冲突这一事实表明正在发生锁升级,这表明没有索引来为 DELETE 服务,或者连接上的索引临界点已命中。但话又说回来,这只是由于信息不足而引起的猜测。要给出任何有意义的答案,需要实际的死锁 XML 和所涉及对象的确切模式定义。
更新后
您仍然没有提供所要求的信息:涉及的所有对象的确切架构,包括聚簇索引和所有非聚簇索引定义。在那之前,最初的怀疑是成立的:DELETE 正在执行表扫描并且已经升级到页面锁定粒度。这是由于错误的索引。
您对“删除和插入语句总是触及 2 个不同的数据集”的评价在两个帐户上是错误的:
作为旁注,审计表几乎总是需要按事件日期/时间进行聚类,因为对它们的所有查询都需要特定的时间间隔(“……和……之间发生了什么”),并且项目搜索可以是ID 中的非聚集主键满足。清除审计记录,即使正确集群,也充满了性能问题,需要批处理以避免日志爆炸。最好的解决方案是部署一个 automated sliding window using partitioning ,但这也带来了自身的挑战。
关于sql-server - 如何避免由于非聚集非唯一索引导致的 Insert/Delete 语句之间的死锁!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5305397/
我正在尝试使用 Spark 从 Cassandra 读取数据。 DataFrame rdf = sqlContext.read().option("keyspace", "readypulse
这是代码: void i_log_ (int error, const char * file, int line, const char * fmt, ...) { /* Get erro
我必须调试一个严重依赖 Gtk 的程序。问题是由于某些原因,在使用 GtkWindow 对象时开始出现许多运行时警告。问题是,即使 Gtk 提示严重错误,它也不会因这些错误而中止。我没有代码库的更改历
我正在尝试从已有效编译和链接的程序中检索二进制文件。我已经通过 GL_PROGRAM_BINARY_LENGTH 收到了它的长度。该文档说有两个实例可能会发生 GL_INVALID_OPERATION
我有一个托管在 Azure 环境中的服务。我正在使用控制台应用程序使用该服务。这样做时,我得到了异常: "The requested service, 'http://xxxx-d.yyyy.be/S
我有以下代码,它被 SEGV 信号杀死。使用调试器表明它被 main() 中的第一个 sem_init() 杀死。如果我注释掉第一个 sem_init() ,第二个会导致同样的问题。我试图弄清楚是什么
目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用核心数据进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数
我对 Xamarin.Forms 还是很陌生。我在出现的主页上有一个非常简单的功能 async public Task BaseAppearing() { if (UserID
这是我的代码的简化版本。 public class MainActivity extends ActionBarActivity { private ArrayList entry = new Arr
我想弄明白为什么我的两个 Java 库很难很好地协同工作。这是场景: 库 1 有一个类 A,其构造函数如下: public A(Object obj) { /* boilerplate */ } 在以
如果网站不需要身份验证,我的代码可以正常工作,如果需要,则在打印“已创建凭据”后会立即出现 EXC_BAD_ACCESS 错误。我不会发布任何内容,并且此代码是直接从文档中复制的 - 知道出了什么问题
我在使用 NSArray 填充 UITableView 时遇到问题。我确信我正在做一些愚蠢的事情,但我无法弄清楚。当我尝试进行简单的计数时,我得到了 EXC_BAD_ACCESS,我知道这是因为我试图
我在 UITableViewCell 上有一个 UITextField,在另一个单元格上有一个按钮。 我单击 UITextField(出现键盘)。 UITextField 调用了以下方法: - (BO
我有一个应用程序出现间歇性崩溃。崩溃日志显示了一个堆栈跟踪,这对我来说很难破译,因此希望其他人看到了这一点并能为我指出正确的方向。 基本上,应用程序在启动时执行反向地理编码请求,以在标签中显示用户的位
我开发了一个 CGImage,当程序使用以下命令将其显示在屏幕上时它工作正常: [output_view.layer performSelectorOnMainThread:@selector(set
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
我有一个中继器,里面有一些控件,其中一个是文本框。我正在尝试使用 jquery 获取文本框,我的代码如下所示: $("#").click(function (event) {}); 但我总是得到 nu
在以下场景中观察到 TTS 初始化错误,太随机了。 已安装 TTS 引擎,存在语音集,并且可以从辅助功能选项中播放示例 tts。 TTS 初始化在之前初始化和播放的同一设备上随机失败。 在不同的设备(
maven pom.xml org.openjdk.jol jol-core 0.10 Java 类: public class MyObjectData { pr
在不担心冲突的情况下,可以使用 MD5 作为哈希值,字符串长度最多为多少? 这可能是通过为特定字符集中的每个可能的字符串生成 MD5 哈希来计算的,长度不断增加,直到哈希第二次出现(冲突)。没有冲突的
我是一名优秀的程序员,十分优秀!