Free list&HWM(high water mark) 一个表若预分配100万个block(如果用较大的initial extent参数),则oracle不会将全部100万个block都放到free list链表上,否则维护量太大,而是使用HWM(高水位)进行解决。 HWR是一个标记,用来标记segment中有多少block是“已被用过”的,有多少block是“从未被用过”的。只要一block被用过,其就位于HWM以下了,即使块中数据全删除,该块也仍位于HWM以下,即HWM只升不降。 HWM的好处是减小了freelist长度,因只有HWM以下的块才会放到freelist上,即oracle总使用以用过的空闲块进行insert,避免了空间浪费同时提高了free list的性能和可管理性;同时在需要扫描整个segment中数据块是,因HWM存在,也只需扫描HWM以下的块,从而提高了性能。 测试: SQL> create table t7 (a int,b char(10)); SQL> analyze table t7 compute statistics; SQL> select blocks,empty_blocks from dba_tables where table_name='T7'; BLOCKS EMPTY_BLOCKS ---------- ------------ 0 7 SQL> select substr(segment_name,1,8),header_file,header_block,blocks from dba_segments where segment_name='T7'; SUBSTR(SEGMENT_N HEADER_FILE HEADER_BLOCK BLOCKS ---------------- ----------- ------------ ---------- T7 1 61161 8 SQL> alter system dump datafile 1 block 61161; $vi /u01/app/oracle/admin/ora10/udump/ora10_ora_4366.trc .......... #blocks in seg. hdr's freelists: 0 #blocks below: 0 ............... SQL> begin 2 for I in 1..2000 3 loop 4 insert into t7 values (I,'aaaaaaaaaa'); 5 end loop; 6 commit; 7 end; 8 / SQL> analyze table t7 compute statistics; SQL> select blocks,empty_blocks from dba_tables where table_name='T7'; BLOCKS EMPTY_BLOCKS ---------- ------------ 7 0 SQL> select extent_id,block_id,blocks from dba_extents where segment_name='T7'; EXTENT_ID BLOCK_ID BLOCKS ---------- ---------- ---------- 0 61161 8 SQL> select substr(segment_name,1,8),header_file,header_block,blocks from dba_segments where segment_name='T7'; SUBSTR(SEGMENT_N HEADER_FILE HEADER_BLOCK BLOCKS ---------------- ----------- ------------ ---------- T7 1 61161 8 SQL> alter system dump datafile 1 block 61161; $vi /u01/app/oracle/admin/ora10/udump/ora10_ora_4366.trc #blocks in seg. hdr's freelists: 2 #blocks below: 7 SQL> begin 2 for I in 2001..4000 3 loop 4 insert into t7 values (I,'aaaaaaaaaa'); 5 end loop; 6 commit; 7 end; 8 / SQL> analyze table t7 compute statistics; SQL> select blocks,empty_blocks from dba_tables where table_name='T7'; BLOCKS EMPTY_BLOCKS ---------- ------------ 12 3 SQL> select extent_id,block_id,blocks from dba_extents where segment_name='T7'; EXTENT_ID BLOCK_ID BLOCKS ---------- ---------- ---------- 0 61161 8 1 61169 8 SQL> select substr(segment_name,1,8),header_file,header_block,blocks from dba_segments where segment_name='T7'; SUBSTR(SEGMENT_N HEADER_FILE HEADER_BLOCK BLOCKS ---------------- ----------- ------------ ---------- T7 1 61161 16 $vi /u01/app/oracle/admin/ora10/udump/ora10_ora_4366.trc #blocks in seg. hdr's freelists: 1 #blocks below: 12 SQL> delete from t7 where a>500; SQL> commit; SQL> analyze table t7 compute statistics; SQL> select blocks,empty_blocks from dba_tables where table_name='T7'; BLOCKS EMPTY_BLOCKS ---------- ------------ 12 3 SQL> select extent_id,block_id,blocks from dba_extents where segment_name='T7'; EXTENT_ID BLOCK_ID BLOCKS ---------- ---------- ---------- 0 61161 8 1 61169 8 SQL> select substr(segment_name,1,8),header_file,header_block,blocks from dba_segments where segment_name='T7'; SUBSTR(SEGMENT_N HEADER_FILE HEADER_BLOCK BLOCKS ---------------- ----------- ------------ ---------- T7 1 61161 16 SQL> alter system dump datafile 1 block 61161; $vi /u01/app/oracle/admin/ora10/udump/ora10_ora_4366.trc #blocks in seg. hdr's freelists: 11 #blocks below: 12 HWM太高,HWM下空闲块过多的解决办法: 1. recreate table; 2. truncate table; 3. alter table shrink space;(for oracle10g) 数据块头(包含块头,表目录区,行目录区)组成: 1. 定长部分数据:记录block bype(即segment type),block地址等。 2. 变长部分数据:行地址,ITL(interested transaction list)等 ITL实际为block header中的一段用于保存数据的数据结构,称为ITL slot,其中保存的数据包括block中关于事务信息的记录,包括list编号、回滚段地址、事务状态、事务在该block影响的记录条数等。 每个需要存取该数据块的事务都需先获得一个该数据块的ITL slot,因此一个数据块上ITL slot入口的多少决定该数据块支持并发事务数量的多少,可在create table时以inittrans(默认1)和maxtrans(默认255)参数指定初始和最大ITL slot数,当initrans<=2时,每个分配的数据块中都会有2个ITL slot,当ITL slot不够用时,oracle会动态增加ITL slot的数量。 Free list和ITL都影响并发性,区别如下: 1. ITL影响block层的并发性,free list影响segment层的并发性; 2. ITL影响并发的事务,free list影响并发的insert操作; 3. 事务进行全程均占用ITL,事务结束后释放;insert仅在事务进行前搜索占用free list,事务进行时free list已释放; Block cleanouts(块清除) :当事务commit时;block中的block中的ITL被清除, Ø Fash block cleanouts commit时若需cleanouts的块位于buffer cache,则立即清除ITL,若事务太大,需要清除的块数量大于buffer cache的10%,则暂只立即清除10%以内的部分。 Ø Delayed block cleanouts commit时若需cleanouts的块已写到disk,则延时清除ITL,若事务太大,需要清除的块数量大于buffer cache的10%,则10%以外的部分进行延时清除。延时清除将在块被再次访问进行以提高commit的性能。 转载请保留固定链接: https://linuxeye.com/database/666.html |