
生产环境中使用的是DB2. 但是,最近经常发生一种奇怪的死锁现象: 某个select sql语句将始终死锁.
根据过去的经验,通常更新/删除和其他更新sql语句将出现死锁问题. 而且,此select sql语句是非常常见的sql,无需进行大量数据处理.
分析这种僵局,有很多困难.
1. 由于生产环境中的数据量很大,因此我们无法将生产环境中相关表的数据导入测试环境. 换句话说,无法模拟数据量.
2. 没有日志输出. 因为生产环境的日志输出级别为ERROR.
3. 该测试无法在生产环境中执行,因为客户不允许这样做.
4. 无法在生产环境中启用快照和其他功能. 因为这会影响性能.

您可以想象,在没有快照和其他功能的情况下,分析死锁只能依靠分析代码. 但是此过程非常复杂,仅凭分析代码是毫无头绪的.
阶段1: 我们怀疑是数据量
由于生产环境中有大量数据,因此该过程还有许多其他表过程. 那么我们想知道大数据量是否会导致系统负载过高并导致死锁?
因此死锁的发现和解决,当发生死锁时,我们可以获得CPU,硬盘,网络等的负载信息. 未找到任何线索.
第2阶段: 制作一个测试程序,使用多线程模拟多用户在测试环境中执行此过程.
为了在开发环境中重现此僵局,我们制作了一个多线程测试程序来模拟多用户操作. 不幸的是,它没有被复制.
阶段3: 分析测试环境和产品环境之间的差异

这时我们怀疑这仍然是由数据量引起的问题. 因此,我们尝试使开发环境的数据与产品环境一样多.
运行测试后,它仍然没有出现.
阶段4: 分析用户的操作日志
如果没有办法,我们必须分析用户的操作日志,以期找到一些线索. 努力的工作有回报,我们发现当两个人同时出现时
执行此操作时,基本上会发生死锁. 因此,我们认为这仍然是两个人同时操作引起的问题. 但是为什么要在开发环境中对其进行仿真
许在没有死锁的情况下工作?
第5阶段: 我发现设置有问题

我们再次修改了测试程序以增加模拟用户的数量,但是不幸的是,该问题并未得到重现. 此时我们注意到: 这是一个开发环境吗?
设置与产品环境的设置不同吗?我们比较了两个的设置: 发现许多参数不同. 但是我们只专注于锁
设置
,即包含LOCK关键字的设置.
阶段6: 保持测试环境和产品环境设置一致
我们将所有与锁相关的设置更改为与产品环境相同的设置. 但是,此死锁尚未重现. 最终,一个人发现“ cur_commit”设置
不同. 因此,我搜索了文档,发现了cur_commit的特征.

当cur_commit = false时,以下情况将导致死锁:
线程1插入数据A,然后线程2插入数据B.
程2提交某些内容之前,线程1查询数据A,这将导致死锁.
在开发环境中死锁的发现和解决,cur_commit = true,因此我们无法模拟这种现象.
因此,我们还将cur_commit更改为false.
第7阶段: 使用测试过程进行仿真
我们修改了测试程序以模拟上述两个线程的操作,并成功重现了此死锁. 错误日志信息也与产品环境一致.
第8阶段: 使用屏幕操作进行模拟
然后,我们修改程序并使用屏幕进行操作,并成功重现了此死锁.
解决方案非常简单,即在查询语句中添加条件作为索引,不会出现死锁.
由于该表中的数据量不大,因此性能几乎没有影响.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-228609-1.html
竟然老旧军舰
当时日本军舰都有速射炮
真正打海战是不行的