本文共 9611 字,大约阅读时间需要 32 分钟。
[20160726]行链接行迁移与ITL槽.txt
当表中一行的数据不能在一个数据block中放入的时候,这个时候就会发生两种情况,一种是行链接(Row Chaining),另外一种就是行迁
移(Row Migration)了。行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下。这种情况下,Oracle将使用链接一个或者多个在这个段
中保留的block存储这一行记录,行链接比较容易发生在比较大的行上,例如行上有LONG、LONG RAW、LOB等数据类型的字段,这种时候行 链接是不可避免的会产生的。当一行记录初始插入的时候事可以存储在一个block中的,由于更新操作导致行长增加了,而block的自由空间已经完全满了,这个时候就
产生了行迁移。在这种情况下,Oracle将会迁移整行数据到一个新的block中(假设一个block中可以存储下整行数据),Oracle会保留被迁 移行的原始指针指向新的存放行数据的block,这就意味着被迁移行的ROW ID是不会改变的。当发生了行迁移或者行链接,对这行数据操作的性能就会降低,因为Oracle必须要扫描更多的block来获得这行的信息.
--我自己并不想讲行链接行迁移,而是在一些测试时当发生行链接行迁移时ITL槽数量的变量,通过例子来说明:
1.建立测试环境:
SCOTT@book> @ &r/ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- -------------------------------------------------------------------------------- x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit ProductionSCOTT@book> create table t (id number ,c1 varchar2(2000),c2 varchar2(2000),c3 varchar2(2000),c4 varchar2(2000),c5 varchar2(2000));
Table created.2.测试出现行链接的情况:
--首先做1点点说明,如果1条记录插入新块中,一般缺省仅仅建立2个ITL槽,而如果你使用ctas建立并导入数据,一般缺省仅仅建立3个ITL槽.
--如果在一个块中存在多个事务,每一个事务占用1个ITL槽(24字节),如果itl槽不足,就会动态增加ITL槽的数量,如果数据块中free空间不 --足,就会出现itl不足的等待事件.如果是索引块就会出现索引分裂.--像我前面建立的表,如果插入记录,正常会建立2个ITL.但是当插入记录出现行链接会出现什么情况呢?
insert into t values
(1,lpad('c1',2000,'x'),lpad('c2',2000,'x'),lpad('c3',2000,'x'),lpad('c4',2000,'x'),lpad('c5',2000,'x')); commit;--//由于插入的信息超过一块所能放下的情况,出现行链接.
SCOTT@book> select rowid,t.id from t;
ROWID ID ------------------ ---------- AAAXT5AAEAAAALvAAA 1SCOTT@book> @ &r/rowid AAAXT5AAEAAAALvAAA
OBJECT FILE BLOCK ROW DBA TEXT ---------- ---------- ---------- ---------- -------------------- ---------------------------------------- 95481 4 751 0 4,751 alter system dump datafile 4 block 751 ;SCOTT@book> alter system checkpoint;
System altered.SCOTT@book> alter system dump datafile 4 block 751 ;
System altered.Block header dump: 0x010002ef
Object id on Block? Y seg/obj: 0x174f9 csc: 0x03.15754d18 itc: 2 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0007.000.0000188b 0x00c008e2.0620.27 --U- 1 fsc 0x0000.15754d19 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 bdba: 0x010002ef data_block_dump,data header at 0x7f5d2ef22264 =============== tsiz: 0x1f98 hsiz: 0x14 pbl: 0x7f5d2ef22264 76543210 flag=-------- ntab=1 nrow=1 frre=-1 fsbo=0x14 fseo=0xfe6 avsp=0xfd2 tosp=0xfd2 0xe:pti[0] nrow=1 offs=0 0x12:pri[0] offs=0xfe6 block_row_dump: tab 0, row 0, @0xfe6 tl: 4018 fb: --H-F--- lb: 0x1 cc: 3 nrid: 0x010002ee.0 col 0: [ 2] c1 02 col 1: [2000] --可以发现ITL的数量是2.再看看行迁移对应的数据块。SCOTT@book> @ &r/dfb16 0x010002ee
RFILE# BLOCK# TEXT ---------- ---------- ------------------------------------------------------------ 4 750 alter system dump datafile 4 block 750 ;--检查转储:
Block header dump: 0x010002ee Object id on Block? Y seg/obj: 0x174f9 csc: 0x03.15754d18 itc: 3 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0007.000.0000188b 0x00c008e2.0620.26 --U- 1 fsc 0x0000.15754d19 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 0x03 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 bdba: 0x010002ee data_block_dump,data header at 0x7f5d2ef2227c =============== tsiz: 0x1f80 hsiz: 0x14 pbl: 0x7f5d2ef2227c 76543210 flag=-------- ntab=1 nrow=1 frre=-1 fsbo=0x14 fseo=0x804 avsp=0x7f0 tosp=0x7f0 0xe:pti[0] nrow=1 offs=0 0x12:pri[0] offs=0x804 block_row_dump: tab 0, row 0, @0x804 tl: 6012 fb: -----L-- lb: 0x1 cc: 3--可以发现出现行迁移的块itl槽的数量是3.而不是2.也就是出现行链接时对应的块要增加1个ITL槽,注意那行xid全是0,而flag= C---.
3.测试出现行迁移的情况.
--// drop table t purge;
create table t (id number ,c1 varchar2(2000),c2 varchar2(2000),c3 varchar2(2000),c4 varchar2(2000),c5 varchar2(2000)); insert into t (id ,c1)values (1,lpad('c1',2000,'y')); insert into t (id ,c1)values (2,lpad('c1',2000,'z')); commit ;SCOTT@book> select rowid,t.id from t;
ROWID ID ------------------ ---------- AAAXT6AAEAAAALuAAA 1 AAAXT6AAEAAAALuAAB 2SCOTT@book> @ &r/rowid AAAXT6AAEAAAALuAAA
OBJECT FILE BLOCK ROW DBA TEXT ---------- ---------- ---------- ---------- -------------------- ---------------------------------------- 95482 4 750 0 4,750 alter system dump datafile 4 block 750 ;SCOTT@book> alter system checkpoint;
System altered.SCOTT@book> alter system dump datafile 4 block 750 ;
System altered.Block header dump: 0x010002ee
Object id on Block? Y seg/obj: 0x174fa csc: 0x03.15754f2b itc: 2 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0001.00c.00000f84 0x00c000fe.0805.05 --U- 2 fsc 0x0000.15754f2c 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 bdba: 0x010002ee data_block_dump,data header at 0x7f5d2ef22264 =============== --//看看转储itl槽的数量.可以发现占用2个ITL槽,与我前面的说明一致. --修改记录出现行迁移呢?update t set c2=lpad('c2',2000,'z'),c3=lpad('c3',2000,'z'),c4=lpad('c4',2000,'z'),c5=lpad('c5',1000,'z') where id=2;
commit;alter system checkpoint;
--一下子增加7000字节,1个数据块已经容纳不下,出现行迁移的情况,再做一次转储:
SCOTT@book> alter system dump datafile 4 block 750 ;
System altered.Block header dump: 0x010002ee
Object id on Block? Y seg/obj: 0x174fa csc: 0x03.15754f60 itc: 2 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0001.00c.00000f84 0x00c000fe.0805.05 C--- 0 scn 0x0003.15754f2c 0x02 0x000a.020.0000cfed 0x00c00330.29c9.01 --U- 1 fsc 0x0000.15754f63 bdba: 0x010002ee data_block_dump,data header at 0x7f5d2ef22264 =============== .... tab 0, row 1, @0x807 tl: 2015 fb: --H-F--- lb: 0x2 cc: 2 nrid: 0x010002ef.0 col 0: [ 2] c1 03 col 1: [2000]SCOTT@book> @ &r/dfb16 0x010002ef
RFILE# BLOCK# TEXT ---------- ---------- ------------------------------------------------------------ 4 751 alter system dump datafile 4 block 751 ;Block header dump: 0x010002ef
Object id on Block? Y seg/obj: 0x174fa csc: 0x03.15754f60 itc: 3 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.020.0000cfed 0x00c0032e.29c9.3e --U- 1 fsc 0x0000.15754f63 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 0x03 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 bdba: 0x010002ef data_block_dump,data header at 0x7f5d2ef2227c--可以发现出现行迁移块的ITL的数量会增加1个。
4.从上面的测试可以发现只要出现行链接或者行迁移,就会自动增加1个itl槽,当然自由空间要允许的情况下.
--这样做一个假设,如果1块中有多个事务出现行链接或者迁移会出现什么情况呢?做1个行内链接的情况: --// drop table t purge; spool a.sql select 'create table t (' from dual union all select 'col'||lpad(rownum-1,3,'0')||' number(1),' from dual connect by level<=1000 union all select 'constraint t1_pk primary key (col000));' from dual ;--整理与编辑a.sql 执行它。建立表t。
SCOTT@book> insert into t (col000,col999) values (1,1);
1 row created.SCOTT@book> commit ;
Commit complete.--因为一个行片对应字段255个,这样就建立了4个行片,这种情况相当于行内链接。参考http://blog.itpub.net/267265/viewspace-2122499/。
SCOTT@book> select rowid,col000 from t;
ROWID COL000
------------------ ---------- AAAXT7AAEAAAALuAAD 1SCOTT@book> @ &r/rowid AAAXT7AAEAAAALuAAD
OBJECT FILE BLOCK ROW DBA TEXT ---------- ---------- ---------- ---------- -------------------- ---------------------------------------- 95483 4 750 3 4,750 alter system dump datafile 4 block 750 ;SCOTT@book> alter system checkpoint; System altered.
SCOTT@book> alter system dump datafile 4 block 750 ;
System altered.Block header dump: 0x010002ee
Object id on Block? Y seg/obj: 0x174fb csc: 0x03.157550e7 itc: 5 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.005.0000cfe9 0x00c00367.29c9.11 --U- 4 fsc 0x0000.157550e8 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 0x03 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x04 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x05 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 bdba: 0x010002ee data_block_dump,data header at 0x7f8aec1802ac ===============--可以发现出现3行一样的。
0x03 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x04 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x05 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000--因为在这个数据块内发生了3次"行链接".通过bbed观察也可以证明这点:
BBED> set dba 4,750 DBA 0x010002ee (16777966 4,750)BBED> p kdbt
struct kdbt[0], 4 bytes @186 sb2 kdbtoffs @186 0 sb2 kdbtnrow @188 4 --//注:这里记录的是行片数量,如果表字段小于255,对应行记录是正确的。BBED> p kdbr
sb2 kdbr[0] @190 7756 sb2 kdbr[1] @192 7492 sb2 kdbr[2] @194 7228 sb2 kdbr[3] @196 6982--再插入1条呢?
SCOTT@book> insert into t (col000,col999) values (2,2); 1 row created.SCOTT@book> alter system checkpoint;
System altered.SCOTT@book> alter system dump datafile 4 block 750 ;
System altered.Block header dump: 0x010002ee Object id on Block? Y seg/obj: 0x174fb csc: 0x03.157550e7 itc: 6 flg: E typ: 1 - DATA brn: 0 bdba: 0x10002e8 ver: 0x01 opc: 0 inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.005.0000cfe9 0x00c00367.29c9.11 --U- 4 fsc 0x0000.157550e8 0x02 0x000a.008.0000cfdb 0x00c0036f.29c9.08 ---- 4 fsc 0x0000.00000000 0x03 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x04 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x05 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 0x06 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 bdba: 0x010002ee data_block_dump,data header at 0x7f8aec1802c4 --有增加1个ITL槽。总结:
如果出现行链接或者行迁移,ITL槽数量会自动增加。至于为什么我不是很清楚。 0x06 0x0000.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00000000 --仅仅能理解出现行迁移先预留ITL槽,以备以后需要吗?不理解。转载地址:http://lgcix.baihongyu.com/