DB2死锁解决方案的完整记录

生产环境中使用的数据库是DB2,但最近出现了一种奇怪的死锁现象:SELECT SQL语句总是存在死锁。

根据以往的经验,通常是在更新SQL语句更新/删除选择的SQL语句是一种很常见的SQL死锁的问题,没有任何大数据量的处理。

分析死锁有许多困难的地方。



1。由于生产环境中的大量数据,我们无法将生产环境中相关表的数据导入到测试环境中,也就是说,不可能模拟数据量。

2。没有日志输出,因为生产环境的日志输出级别是错误的。

3,不能在生产环境中测试,因为客户是不允许的。

4,生产环境数据库不能打开快照等功能,因为它影响性能。



可以想象,在没有快照和其他功能的情况下,死锁的分析依赖于对代码的分析,但这是一个非常复杂的过程,并且没有分析代码的线索。



第1阶段:我们怀疑数据量的原因



因为生产环境中的数据量非常大,所以还有许多其他的表要处理,那么我们是否怀疑大量的数据会导致系统过载,导致死锁呢

因此,我们得到了CPU、硬盘、网络等的负载信息,没有发现任何线索。



2阶段:做一个测试程序,使用多线程模拟多用户在测试环境中做这个。



为了重现开发环境中的死锁,我们做了一个多线程测试程序,模拟多用户操作,不幸的是,仍然没有重现。



第3阶段:测试环境数据库和产品环境数据库之间的差异分析



在这一点上,我们怀疑数据量的问题,因此我们尽可能多地开发开发环境的数据,就像产品环境一样。

运行测试之后,它仍然没有被复制。



第4阶段:用户操作日志的分析



在没有任何方式的情况下,我们必须分析用户的操作日志,希望能找到线索。Kung Fu不忍心,我们发现当两个人同时在一起的时候。

当这个操作完成时,基本上会出现死锁,所以我们判断两个人同时操作的问题,但是为什么开发环境是模拟的呢

很多人操作,却不送生死锁



第5阶段:发现数据库设置的问题



我们还修改了测试程序以增加模拟用户的数量,但不幸的是,我们还没有重现这个问题。

数据库设置与产品环境中的数据库设置不同吗我们比较两个数据库的设置:找到了很多不同的参数,但是我们只关心锁。

还设置了锁关键字的设置。



阶段6:保持测试环境数据库和产品环境数据库的一致性



我们已经改变了所有的锁相关的设置对产品的环境。但僵局仍然没有再现。最后,一个人发现,cur_commit 这个设置

不同。然后文档的查询和cur_commit被发现的特点。

当cur_commit = false,下列条件导致死锁:

线程1插入数据A,线程2插入数据B。

当线程2还没有提交东西时,线程1查询数据A,导致死锁。

在开发环境中,cur_commit = true,所以我们没有能够模拟这种现象。

所以,我们改变了cur_commit假。



第7阶段:使用测试程序来模拟



我们修改了测试程序,模拟了上述两个线程的操作,成功地再现了死锁,错误的日志信息和产品环境也是一致的。



第8阶段:使用图片操作来模拟



然后我们修改程序,使用屏幕进行操作,并成功地再现了死锁。



解uff1a



简单的解决方案是将查询语句中的条件添加到索引中,并且不会出现死锁。

由于该表中的数据量很少,对性能的影响很小。