此等待事件发生的版本从10.2到11.2,在任何平台都会出现
产生的原因:在OLTP RAC系统上,高并发应用下,与表相关的索引会发生很高的TX队列的争用。这通常在所有实例并发应用大量的INNSERT或DELETE操作。因为当插入新行到index块里索引块可能需要做splits动作。
事物将会有mode 4的TX lock,直到之前的session做完index block splits为止。
index block &&split的概念:
索引的数据块分为root block、branch block、leaf block
root block:是一个索引的入口
branch block:,通过此键值来查找B-TREE的 leaf block
leaf block:存放数据的索引块,实际数据存放在leaf block中,leaf blocks hold
index block split发生在一个新的记录需要插入到索引块中不能找到free space,那么会话将开始index block split。在开始split时,这个session将会尝试清空此block的keys来检查是否有足够的空间。
splieter会有如下大概操作:
分配新块
复制一定百分比的rows到新的buffer里。
添加新的buffer到索引结构并且提交操作。
索引分裂可能原因:
a、索引所在表的应用所给的压力较大
b、表所对应的索引不正常的正常,即在B-TREE的一边增长造成不平衡。
索引分裂类型:
leaf block split 细化为 leaf node 90-10splits和leaf node 50-50 splits
Branch Block 50-50Split
Root Block 50-50Split
--可通过此语句来查询其情况
SELECT Names.Name, Stats.Value, Stats.Statistic#
FROM V$sesstat Stats, V$statname Names
WHERE --stats.sid = (SELECT sid FROM v$mystat WHERE rownum = 1) AND
Names.Statistic# = Stats.Statistic#
AND Names.Name LIKE '%split%'
ORDER BY Stats.Statistic#;
leaf node 90-10splits:插入到索引leaf block叶子块中的索引键是该块中最大的键值(包括块中已删除的索引键值)。在此种情况下实施90-10split,原叶子块仍保持99%的full,
而到另一个空的叶子块中插入该条新的最大键值记录。
leaf node 50-50splits:当插入到索引叶子块中的索引键值不是该块中的最大值时(包括块中已删除的索引键值),将发生 50/50split分裂,这意味着有一半索引记录仍存在当前块,
而另一半数据移动到新的叶子块中。
Branch Block 50-50 Split 由于不断的索引叶块分裂需要将新的leaf block的信息加入到branch block中,当branch block没有足够空间容纳新的记录时,又会引发branch block的 Split。
branch block的split50-50的,即将一半记录移动到新的branch block中。
Root Block 50-50 Split root block 根块实际是一种特殊的branch block, 当root block 50-50split分裂发生时将分配2个新的数据块, 分裂将一半的数据移动到一个新块中,另一半数据移动到另一个新块中。
并更新原来的root block,使之指向那2个新的数据块,实际上是2个branch block了
enq:TX-index contention等待事件案例如下
Top 5 Timed Foreground Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avg
wait % DB
Event Waits Time(s) (ms) time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
enq: TX - index contention 1,263,737 179,494 142 29.9 Concurrenc===>在top1上
db file sequential read 29,316,282 132,125 5 22.0 User I/O
buffer busy waits 2,255,337 87,767 39 14.6 Concurrenc
DB CPU 51,053 8.5
log file sync 4,144,556 26,134 6 4.4 Commit
根、枝、叶的分裂情况较为严重
nstance Activity Stats DB/Inst: STDDB/stddb1 Snaps: 51155-51156
-> Ordered by statistic name
Statistic Total per Second per Trans
-------------------------------- ------------------ -------------- -------------
leaf node 90-10 splits 9,182 5.1 0.0
leaf node splits 332,103 183.2 0.1
branch node splits 1,632 0.9 0.0
root node splits 3 0.0 0.0
相关segment的等待情况
Segments by Row Lock Waits DB/Inst: STDDB/stddb1 Snaps: 51155-51156
-> % of Capture shows % of row lock waits for each top segment compared
-> with total row lock waits for all segments captured by the Snapshot
Row
Tablespace Subobject Obj. Lock % of
Owner Name Object Name Name Type Waits Capture
---------- ---------- -------------------- ---------- ----- ------------ -------
TRSEN TS_IDX_YTE IDX4_E_TRSEN_DIG _2014_11_2 INDEX 1,115,929 75.76==>发生争用的索引
TRSEN E_HIS_11 T_E_OP_RECORD_HAND 2014_11_17 TABLE 42,574 2.89
TRSEN TS_IDX_YTE IDX04_T_E_EXT_IS INDEX 27,442 1.86
TRSEN TS_IDX_YTE IDX03_T_E_EXT_IS INDEX 26,256 1.78
TRSEN TS_TRSEN T_SMS_SS_1_LOCKS TABLE 24,796 1.68
-------------------------------------------------------------
Segments by ITL Waits DB/Inst: STDDB/stddb1 Snaps: 51155-51156
-> % of Capture shows % of ITL waits for each top segment compared
-> with total ITL waits for all segments captured by the Snapshot
Tablespace Subobject Obj. ITL % of
Owner Name Object Name Name Type Waits Capture
---------- ---------- -------------------- ---------- ----- ------------ -------
TRSEN TS_IDX_YTE IDX4_E_TRSEN_DIG _2014_11_2 INDEX 7,219 81.36==>伴随的ITLwaits信息
TRSEN E_HIS_11 T_E_EXTREME_ISSUE_ 2014_11_14 TABLE 1,161 13.08
TRSEN TS_IDX_YTE IDX_WK_BIZ_CONTAINER 2014_11_17 INDEX 147 1.66
TRSEN TS_IDX_YTE IDX_T_E_WK_BIZ_SIG 2014_11_17 INDEX 81 .91
TRSEN TS_IDX_YTE IDX_WK_BIZ_HANDON 2014_11_17 INDEX 49 .55
-------------------------------------------------------------
Segments by Buffer Busy Waits DB/Inst: STDDB/stddb1 Snaps: 51155-51156
-> % of Capture shows % of Buffer Busy Waits for each top segment compared
-> with total Buffer Busy Waits for all segments captured by the Snapshot
Buffer
Tablespace Subobject Obj. Busy % of
Owner Name Object Name Name Type Waits Capture
---------- ---------- -------------------- ---------- ----- ------------ -------
TRSEN TS_IDX_YTE IDX4_E_TRSEN_DIG _2014_11_2 INDEX 1,986,465 83.67===>伴随的buffer busy waits信息
TRSEN TS_IDX_YTE IDX04_T_E_EXT_IS INDEX 45,572 1.92
TRSEN STL_HIS_11 IDX1_STL_E_OPS_A 2014_11_17 INDEX 43,749 1.84
TRSEN TS_IDX_YTE IDX03_T_E_EXT_IS INDEX 42,478 1.79
TRSEN TS_IDX_YTS IDX2_STL_E_OPS_A 2014_11_17 INDEX 40,138 1.69
-------------------------------------------------------------
从上面的并发信息来看,由于应用压力很大加上索引非平衡split导致了enq:TX-index contention事件。虽然有enq: TX - allocate ITL等待,但是可通过buffer busy waits可确定是做split导致,因为在
做index split时,会写index数据到new buffer里,故有此等待的出现来佐证确实是索引分裂导致
解决方案:
1.将索引重新创建为反向索引,反向索引可能会导致不必要的问题,不建议使用
2.Hash(散列)分区索引
3.如果索引关键字是从序列(sequence)生成的,则增加序列的高速缓存大小,在应用程序支持时,使用“无序”序列
4.定期rebuild索引来减轻这样现象