识别和解决Oracle ITL死锁

识别和解决Oracle ITL死锁,oracle,oracle10g,database-deadlocks,Oracle,Oracle10g,Database Deadlocks,我有一个Oracle DB包,它经常导致我认为是ITL(感兴趣的事务列表)死锁。跟踪文件的相关部分如下所示 Deadlock graph: ---------Blocker(s)-------- ---------Waiter(s)--------- Resource Name process session holds waits process session holds waits TM-0000cb52-00000000

我有一个Oracle DB包,它经常导致我认为是ITL(感兴趣的事务列表)死锁。跟踪文件的相关部分如下所示

Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TM-0000cb52-00000000        22     131           S       23     143          SS
TM-0000ceec-00000000        23     143    SX             32     138    SX   SSX
TM-0000cb52-00000000        30     138    SX             22     131           S
session 131: DID 0001-0016-00000D1C session 143: DID 0001-0017-000055D5
session 143: DID 0001-0017-000055D5 session 138: DID 0001-001E-000067A0
session 138: DID 0001-001E-000067A0 session 131: DID 0001-0016-00000D1C
Rows waited on:
Session 143: no row
Session 138: no row
Session 131: no row
此表上没有位图索引,因此这不是原因。据我所知,缺少“Rows waiting on”加上Waiter waitis列中的“S”可能表明这是一个ITL死锁。此外,该表的写入频率相当高(大约8次插入或同时更新,每分钟240次),因此很有可能出现国际交易日志死锁

我已将表及其索引的INITRANS参数增加到100,并将表上的PCT_FREE从10增加到20(然后重新生成索引),但死锁仍然存在。死锁似乎最常发生在更新期间,但这可能只是巧合,因为我只跟踪了几次

我的问题有两个:
1) 这实际上是ITL死锁吗?
2) 如果是国际交易日志死锁,还可以做些什么来避免它



事实证明,这根本不是ITL死锁问题,而是未索引外键的问题。我发现这一点要感谢dpbradley的回答,这让我意识到这不是ITL问题,并促使我找出导致“无行”死锁的其他原因。

ITL压力的最佳指示来自性能视图:

select event, total_waits, time_waited, average_wait
 from v$system_event
 where event like 'enq: TX%'
 order by 2 desc;
显示TX争用等待,以及

select OBJECT_NAME, SUBOBJECT_NAME, TABLESPACE_NAME, 
       OBJECT_TYPE, STATISTIC_NAME, VALUE
  from v$segment_statistics 
  where statistic_name = 'ITL waits'
  and value > 0
  order by value desc;
显示所涉及的表和索引

(与所有
v$
视图一样,结果来自实例启动时的时间点。)

如果这表明您确实有ITL等待,那么INITRANS和PCTFREE参数是要打开的主要旋钮(但是INITRANS=100对我来说听起来很高,而且这些参数确实占用了空间)


如果ITL等待不是问题,则需要检查应用程序代码。

最好的选择是根据需要增加它(从默认值10开始,递增10)。如果您看到ITL等待时间减少,那么您已经设置好了。通常,在Oracle和SQL Server中,这些相关参数都是通过反复试验来调整的。实时调整这些参数不会有太大问题,除非资源非常繁忙。您可以使用以下查询查看每次增量后,ITL等待是否消失或大幅减少:

SELECT t.OWNER, t.OBJECT_NAME, t.OBJECT_TYPE, t.STATISTIC_NAME, t.VALUE
  FROM v$segment_statistics t
  WHERE t.STATISTIC_NAME = 'ITL waits' AND t.VALUE > 0
  ORDER BY t.value desc;
我们使用此方法对由于ITL等待而导致的Oracle死锁场景进行了多次调整。注意:如果为索引修改了initrans,请确保重新生成索引。还要确保统计数据不过时


为了快速检查,可以使用SQL调优顾问查看查询/索引和统计信息的完整状态

你可能想考虑在服务器故障上发布这个。我最初的反应是,这就是问题所在,但这个问题也有编程的味道。无论如何,您可能会看到另一双不在这里的眼睛。第一个查询显示23000+个“enq:TX-configuration”等待,但第二个查询仅显示1个ITL等待(在我没有看到死锁的表的索引上)。如果我理解正确,这似乎表明这实际上不是ITL死锁?是的,我从您的编辑中看到,您已经发现了潜在的问题。未编制索引的FK当然可能是一个锁定问题-有大量的脚本会在模式中报告未编制索引的外键。