10g中默认的pctfree为10,ORACLE会为一个BLOCK保留10%的空间以确保将来对于BLOCK中的数据的更新,如果这个值设置过小,可能会产生行迁移,导致性能下降.
下面做个试验,验证ITL与PCTFREE的关系
SYS@anqing2(rac2)> create table t1(a number,b varchar2(20)) pctfree 0;
Table created.
2 for i in 1..1000 loop
3 insert into t1 values(i,'DBA');
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
SYS@anqing2(rac2)> select distinct dbms_rowid.rowid_block_number(rowid) from t1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
73546
73547
由此可知t1表占用了2个block.
Session 1 中操作:
SYS@anqing2(rac2)> update t1 set b='I am DBA' where a<10;
9 rows updated.
Session 2 中操作:
SYS@anqing2(rac2)> update t1 set b='I am DBA' where a>10 and a<20;
9 rows updated.
Session 3 中操作:
SYS@anqing2(rac2)> update t1 set b='I am DBA' where a>20 and a<30;
-- 此时Session 的DML 操作hang住了
查看当前等待事件 v$session_wait 视图
SYS@anqing2(rac2)> select event from v$session_wait where event like '%ITL%';
EVENT
----------------------------------------------------------------
enq: TX - allocate ITL entry
此时出现了分配ITL条目的等待,因为PCTFREE为0,BLOCK中没有足够空间分配ITL,ORACLE只能重用ITL,但是这个时候由于没有COMMIT,无法重用ITL,所以会出现allocate ITL 等待事件,要解决此类问题,可以从新创建表,增大PCTFREE的值,或者更改应用设计,减少竞争。