今天和老周老肖吃饭之于谈论了一个问题,就是INITRANS,MAXINTRANS对高并发量的数据块的影响。
大家都知道在进行大量DML对同一个块的时候(不同行),不会出现TX:ROW LOCK,但是由于ITL的限制
这样的操作可能出现TX:ITL LOCK(MODE=4),以前我遇到过各种TX TM,但是ITL确实没有遇到过,我记得
10G的不管ASSM还是MSSM都是默认的最打MAXTRANS为255,所以没怎么关注,因为如果要达到这个值需要
255个TRANSACTION对同一个块进行修改,基本不可能。
但是我却忽略了一点:
DIS402 3-19
Before the block reaches PCTFREE, the free space is
used both for insertion of new rows and by the growth of the data block header.
可以发现PCTFREE除了存储可能的UPDATE数据还存储扩张的BLOCK header。
测试:
SQL> create tablespace testo1
2 datafile '/oradata/xuexi/XUEXI/datafile/testo1.dbf' size 50m segment space management AUTO;
SQL> create tablespace testo2
2 datafile '/oradata/xuexi/XUEXI/datafile/testo2.dbf' size 50m segment space management manual;
SQL> create table test2
2 initrans 100 maxtrans 200
3 tablespace testo1
4 as
5 select * from dba_users;
Table created
SQL>
SQL> create table test3
2 initrans 100 maxtrans 200
3 tablespace testo2
4 as
5 select * from dba_users;
SQL> select TABLE_NAME,FREELISTS,PCT_FREE,PCT_USED,INI_TRANS,MAX_TRANS from user_tables where table_name in('TEST2','TEST3');
TABLE_NAME FREELISTS PCT_FREE PCT_USED INI_TRANS MAX_TRANS
------------------------------ ---------- ---------- ---------- ---------- ----------
TEST2 10 100 255
TEST3 1 10 40 100 255
可以看到我们只能指定INI_TRANS,MAX_TRANS默认就是255,同时可以看到MSSM的PCT_FREE和PCT_USED都生效了因为他是FREELIST管理的(freelists=1),
而ASSM却只有PCT_FREE,而PCT_USED,freelists均为空,所以他是位图进行管理空块的,而PCT_FREE是必须因为剩余多少空间给UPDATE和扩张的ITL还是
它来指定,而为了避免FREELIST的争用,大家要尽量使用ASSM,默认的10G就是。
默认的INDEX的INI_TRANS=2,表的INI_TRANS=1,MAX_TRANS都是255,这样就出现一个问题,如果没有足够的PCTFREE来进行扩张ITL,即便MAX_TRANS为65555也没用,
所以如果出现ITL LOCK(MODE=4),大家应该考虑是:
1、增加PCTFREE
2、增加初始的块的ITL及提高INI_TRANS。
其实这样的情况很少,但是遇到还是要注意。
及
SQL> alter table test2 pctfree 40 initrans 150;
Table altered
SQL> select TABLE_NAME,FREELISTS,PCT_FREE,PCT_USED,INI_TRANS,MAX_TRANS from user_tables where table_name in('TEST2');
TABLE_NAME FREELISTS PCT_FREE PCT_USED INI_TRANS MAX_TRANS
------------------------------ ---------- ---------- ---------- ---------- ----------
TEST2 40 150 255
但是这个操作只对后来分配的BLOCK生效,如果对现有的表,只有MOVE了,根据需求看看是否NOLOGGING
SQL> alter table test2 move pctfree 30 initrans 170;
Table altered
当然索引也可以一样处理
SQL> select TABLE_NAME,index_name,FREELISTS,PCT_FREE,INI_TRANS,MAX_TRANS from user_indexes ;
TABLE_NAME INDEX_NAME FREELISTS PCT_FREE INI_TRANS MAX_TRANS
------------------------------ ------------------------------ ---------- ---------- ---------- ----------
TEST3 TEST_IN 10 2 255
注意索引没有PCT_USED,是否进行插入数据不是PCT_USED控制的,是根据ROWID确定的。同时对于索引来说,其pctfree仅仅是在create或rebuild时生效,对与后续的插入、修改之类的操作来说是无效的,pctfree的设置也仅仅是为了延缓由于insert等操作而导致的的索引块分裂。
SQL> alter index test_in pctfree 30;
alter index test_in pctfree 30
ORA-02243: invalid ALTER INDEX or ALTER MATERIALIZED VIEW option
所以索引只能修改INITRANS
SQL>
SQL>
SQL> alter index test_in initrans 170;
Index altered