[20160726]行链接行迁移与ITL槽.txt

[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 Production

SCOTT@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          1

SCOTT@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: 0

Itl           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: 0

Itl           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          2

SCOTT@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: 0

Itl           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: 0

Itl           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: 0

Itl           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          1

SCOTT@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: 0

Itl           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槽,以备以后需要吗?不理解。

时间: 2024-10-03 03:31:48

[20160726]行链接行迁移与ITL槽.txt的相关文章

[20160728]]行链接行迁移与ITL槽3.txt

[20160728]]行链接行迁移与ITL槽3.txt --上午测试了行链接行迁移与ITL槽的关系,链接如下: [20160727]行链接行迁移与ITL槽2.txt => http://blog.itpub.net/267265/viewspace-2122663/ --如果仔细看前面的测试可以发现当出现行链接或者行迁移时,除了增加1个空itl槽像如下: 0x05   0x0000.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.0

[20160729]行链接行迁移与ITL槽4.txt

[20160729]行链接行迁移与ITL槽4.txt --做了几个测试,有点乱. http://blog.itpub.net/267265/viewspace-2122700/ http://blog.itpub.net/267265/viewspace-2122663/ http://blog.itpub.net/267265/viewspace-2122599/ --还是通过1个例子来模拟看看.做一个非常极端的测试: 1.环境: SCOTT@book> @ &r/ver1 PORT_ST

行链接 行迁移的消除

模拟行链接: 如何模仿行链接? 首先要了解三个语句: 第1句:运行$ORACLE_HOME/rdbms/admin/utlchain.sql 脚本,SQL> @D:\oracle\product\10.1.0\Db_1\RDBMS\ADMIN\utlchain.sql创建chained_rows表,用于存放发生行迁移         的行的rowid. 第2句:运行analyze table table_name list chained rows into chained_rows; 把产生行

关于Oracle数据库中行迁移/行链接的问题

oracle|链接|数据|数据库|问题 一.行迁移/行链接的介绍 在实际的工作中我们经常会碰到一些Oracle数据库性能较低的问题,当然,引起Oracle数据库性能较低的原因是多方面的,我们能够通过一些正确的设计和诊断来尽量的避免一些Oracle数据库性能不好,Row Migration (行迁移) & Row Chaining (行链接)就是其中我们可以尽量避免的引起Oracle数据库性能低下的潜在问题.通过合理的诊断行迁移/行链接,我们可以较大幅度上提高Oracle数据库的性能. 那究竟什么

Oracle数据库中行迁移/行链接学习(一)什么是行迁移/行链

在实际的工作中我们经常会碰到一些Oracle数据库性能较低的问题,当然,引起Oracle数据库性能较低的原因是多方面的,我们能够通过一些正确的设计和诊断来尽量的避免一些Oracle数据库性能不好,Row Migration (行迁移) & Row Chaining (行链接)就是其中我们可以尽量避免的引起Oracle数据库性能低下的潜在问题.通过合理的诊断行迁移/行链接,我们可以较大幅度上提高Oracle数据库的性能. 那究竟什么是行迁移/行链接呢,先让我们从Oracle的block开始谈起.

行链接和行迁移的秘密

一.概述:  如果你的Oracle数据库性能低下,行链接和行迁移可能是其中的原因之一.我们能够通过合理的设计或调整数据库来阻止这个现象.    行链接和行迁移是能够被避免的两个潜在性问题.我们可以通过合理的调整来提高数据库性能.本文主要描述的是:    什么是行迁移与行链接    如何判断行迁移与行链接    如何避免行迁移与行链接   当使用索引读取单行时,行迁移影响OLTP系统.最糟糕的情形是,对所有读取操作而言,增加了额外的I/O.行链接则影响索引读和全表扫描.    注:在翻译行(row

行链接(Row Chaining)和行迁移(Row Migration)

行链接(Row Chaining)和行迁移(Row Migration) 一.概述:   如果你的Oracle数据库性能低下,行链接和行迁移可能是其中的原因之一.我们能够通过合理的设计或调整数据库来阻止这个现象.      行链接和行迁移是能够被避免的两个潜在性问题.我们可以通过合理的调整来提高数据库性能.本文主要描述的是:     什么是行迁移与行链接     如何判断行迁移与行链接     如何避免行迁移与行链接   当使用索引读取单行时,行迁移影响OLTP系统.最糟糕的情形是,对所有读取操

Oracle数据库中行迁移/行链接学习(三)行迁移/行链接的清除方法

由于对于行链接来说只能增大db_block_size来清除,而db_block_size在创建了数据库后又是不能改变了的,所以这里对行链接的清除不做过多的叙述了,主要是针对行迁移来谈谈在实际的生产系统中如何去清除. 对于行迁移的清除,一般来说分为两个步骤:第一步,控制住行迁移的增长,使其不在增多:第二步,清除掉以前存在的行迁移. 众所周知,行迁移产生的主要原因是因为表上的pctfree参数设置过小导致的,而要实现第一步控制住行迁移的增长,就必须设置好一个正确合适的pctfree参数,否则即使清除

Oracle数据库中行迁移/行链接学习(二)行迁移/行链接的检测方法

通过前面的介绍我们知道,行链接主要是由于数据库的db_block_size不够大,对于一些大的字段没法在一个block中存储下,从而产生了行链接.对于行链接我们除了增大db_block_size之外没有别的任何办法去避免,但是因为数据库建立后db_block_size是不可改变的(在9i之前),对于Oracle9i的数据库我们可以对不同的表空间指定不同的db_block_size,因此行链接的产生几乎是不可避免的,也没有太多可以调整的地方.行迁移则主要是由于更新表的时候,由于表的pctfree参