[20121116]通过bbed观察行链接与行迁移.txt

[20121116]通过bbed观察行链接与行迁移.txt

    如果应用中出现大量的行链接与行迁移,对应用的性能多少存在影响。一般情况下,行迁移主要是update后,行记录变大,导致原来
的数据块无法容纳,在原来的块保留指针,其他信息放在其他块中。而行链接主要是行记录太大,1个数据块无法容纳,导致使用多块保存。
我想通过bbed简单观察这种情况:

1.建立测试环境:

SQL> select * from v$version where rownum
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
SQL> create table t  ( a number,b varchar2(3000),c varchar2(3000) , d varchar2(3000), e varchar2(3000) ) tablespace test;
Table created.
SQL> create unique index p_t on t(a);
Index created.
SQL> insert into t (a) values (1);
1 row created.
SQL> commit ;
Commit complete.
SQL> select rowid ,t.a from t;
ROWID                       A
------------------ ----------
AAAdD/AAIAAAACOAAA          1
SQL> @ lookup_rowid AAAdD/AAIAAAACOAAA
    OBJECT       FILE      BLOCK        ROW
---------- ---------- ---------- ----------
    119039          8        142          0
SQL> alter system checkpoint;
System altered.

2.使用bbed观察:

BBED> set dba 8,142
        DBA             0x0200008e (33554574 8,142)
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @8182     0x2c
BBED> x /rn
rowdata[0]                                  @8182
----------
flag@8182: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8183: 0x01
cols@8184:    1
col    0[2] @8185: 1

--可以发现仅仅记录一个值a,其他因为都是NULL,不记录。利用这个特性,在建表时,把经常为NULL的字段放在后面,可以一定程度节约空间。

3.现在修改字段c,看看情况:

SQL> update t set c=lpad('c',3000,'c') where a=1;
1 row updated.
SQL> commit ;
Commit complete.
SQL> alter system checkpoint;
System altered.

--注意要退出bbed再进入,才能看到信息:

BBED> set dba 8,142
        DBA             0x0200008e (33554574 8,142)
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @5172     0x2c
BBED> x /rncc
rowdata[0]                                  @5172
----------
flag@5172: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5173: 0x02
cols@5174:    3
col    0[2] @5175: 1
col    1[0] @5178: *NULL*
col 2[3000] @5179: ccccccccccccccccc (太长截断)

-- 可以发现修改c字段后,一个数据块依旧能容纳记录,并没有出现行链接或者迁移的情况。
--另外对比前面看,前面的行记录在偏移8182处,修改后行记录在偏移5175处。
--如果查看8182处信息,可以发现修改前的信息依旧存在。

BBED>  set offset 8182
        OFFSET          8182
BBED> x /rncc
rowdata[3010]                               @8182
-------------
flag@8182: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8183: 0x00
cols@8184:    1
col    0[2] @8185: 1

4.现在修改字段b,d,看看情况:

SQL> update t set b=lpad('b',3000,'b') , d=lpad('d',3000,'d') where a=1;
1 row updated.
SQL> commit ;
Commit complete.
SQL> alter system checkpoint;
System altered.

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @2157     0x28
BBED> x /rnc
rowdata[0]                                  @2157
----------
flag@2157: 0x28 (KDRHFF, KDRHFH)
lock@2158: 0x01
cols@2159:    2
nrid@2160:0x0200008f.0
col    0[2] @2166: 1
col 1[3000] @2169: bbbbbbbbbbbbbbbbbbbbbbbbbbbbb (太长截断)

--可以发现cols=2记录两个字段,nrid在偏移2160处记录了0x0200008f.0,这个就是字段的其他信息在dba=0x0200008f,小数点后面的0,表示行号。
--另外可以发现前面修改的信息依旧存在。

BBED> set offset 8182
        OFFSET          8182
BBED> x /rnc
rowdata[6025]                               @8182
-------------
flag@8182: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8183: 0x00
cols@8184:    1
col    0[2] @8185: 1
BBED> set offset 5172
        OFFSET          5172
BBED> x /rncc
rowdata[3015]                               @5172
-------------
flag@5172: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5173: 0x01
cols@5174:    3
col    0[2] @5175: 1
col    1[0] @5178: *NULL*
col 2[3000] @5179: ccccccccccccccccccccc (太长截断)

现在再看看DBA=0x0200008f情况。

BBED> set dba 0x0200008f
        DBA             0x0200008f (33554575 8,143)
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @2179     0x04
BBED> x /rcc
rowdata[0]                                  @2179
----------
flag@2179: 0x04 (KDRHFL)
lock@2180: 0x01
cols@2181:    2
col 0[3000] @2182: ccccccccc (太长截断)
col 1[3000] @5185: ddddddddd (太长截断)

5.最后在修改e看看情况:

SQL> update t set e=lpad('e',3000,'e')  where a=1;
1 row updated.
SQL> commit ;
Commit complete.
SQL> alter system checkpoint;
System altered.

BBED> set dba 8,142
        DBA             0x0200008e (33554574 8,142)
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @2157     0x28
BBED> x /rnc
rowdata[0]                                  @2157
----------
flag@2157: 0x28 (KDRHFF, KDRHFH)
lock@2158: 0x02
cols@2159:    2
nrid@2160:0x0200008f.0
col    0[2] @2166: 1
col 1[3000] @2169: bbbbbbbbbbbb (太长截断)
BBED> set dba 0x0200008f
        DBA             0x0200008f (33554575 8,143)
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @2179     0x00
BBED> x /rccc
rowdata[0]                                  @2179
----------
flag@2179: 0x00 (NONE)
lock@2180: 0x02
cols@2181:    1
nrid@2182:0x0200008b.0
col 0[3000] @2188: ccccccccccccc (太长截断)
--可以dba=8,143存在nrid=0x0200008b.0,字段d,e在另外的块中。

BBED> set dba 0x0200008b
        DBA             0x0200008b (33554571 8,139)
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @2179     0x04
BBED> x /rcc
rowdata[0]                                  @2179
----------
flag@2179: 0x04 (KDRHFL)
lock@2180: 0x01
cols@2181:    2
col 0[3000] @2182: dddddddddddd (太长截断)
col 1[3000] @5185: eeeeeeeeeeee (太长截断)

--另外大家注意flag标志的变化,这个超出我的能力。

6.看看一些sql语句的执行情况:

SQL> alter system flush BUFFER_CACHE;
System altered.
SQL> alter session set events '10046 trace name context forever, level 12';
Session altered.
SQL> select substr(e,1,10) from t where a=1;
SUBSTR(E,1,10)
--------------------
eeeeeeeeee
SQL> alter session set events '10046 trace name context off';
Session altered.

--查看跟踪文件发现:

PARSING IN CURSOR #8 len=38 dep=0 uid=84 ct=3 lid=84 tim=1353072283364176 hv=1310139427 ad='daec3c10' sqlid='69c8h6j71f913'
select substr(e,1,10) from t where a=1
END OF STMT
PARSE #8:c=2000,e=1548,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=2144302522,tim=1353072283364170
EXEC #8:c=0,e=50,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=2144302522,tim=1353072283364336
WAIT #8: nam='SQL*Net message to client' ela= 4 driver id=1650815232 #bytes=1 p3=0 obj#=0 tim=1353072283364411
WAIT #8: nam='db file sequential read' ela= 33 file#=4 block#=57171 blocks=1 obj#=119040 tim=1353072283364582
WAIT #8: nam='db file sequential read' ela= 24 file#=8 block#=142 blocks=1 obj#=119039 tim=1353072283364721
WAIT #8: nam='db file sequential read' ela= 16 file#=8 block#=143 blocks=1 obj#=119039 tim=1353072283364814
WAIT #8: nam='db file scattered read' ela= 75 file#=8 block#=136 blocks=6 obj#=119039 tim=1353072283365020
FETCH #8:c=1000,e=646,p=9,cr=4,cu=0,mis=0,r=1,dep=0,og=1,plh=2144302522,tim=1353072283365093
STAT #8 id=1 cnt=1 pid=0 pos=1 bj=119039 p='TABLE ACCESS BY INDEX ROWID T (cr=4 pr=9 pw=0 time=0 us cost=0 size=1515 card=1)'
STAT #8 id=2 cnt=1 pid=1 pos=1 bj=119040 p='INDEX UNIQUE SCAN P_T (cr=1 pr=1 pw=0 time=0 us cost=0 size=0 card=1)'
WAIT #8: nam='SQL*Net message from client' ela= 224 driver id=1650815232 #bytes=1 p3=0 obj#=119039 tim=1353072283374046
FETCH #8:c=0,e=3,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=2144302522,tim=1353072283374090
WAIT #8: nam='SQL*Net message to client' ela= 2 driver id=1650815232 #bytes=1 p3=0 obj#=119039 tim=1353072283374123

--可以发现出现db file sequential read,db file scattered read等待事件。
--file#=4 block#=57171(这个是索引)-》file#=8 block#=142 blocks=1=> file#=8 block#=143 blocks=1=>file#=8 block#=136 blocks=6 .
--不知道为什么最后是db file scattered read,要读6个块。

SQL> select * from dba_extents where wner=user and segment_name='T';
OWNER  SEGMENT_NAME PARTITION_NAME       SEGMENT_TYPE       TABLESPACE_NAME       EXTENT_ID    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
------ ------------ -------------------- ------------------ -------------------- ---------- ---------- ---------- ---------- ---------- ------------
SCOTT  T                                 TABLE              TEST                          0          8        136      65536          8            8
时间: 2024-09-20 13:41:26

[20121116]通过bbed观察行链接与行迁移.txt的相关文章

行链接和行迁移的秘密

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

【BBED】使用bbed恢复已经删除的行数据

 在oracle中,当数据行被删除时,实际上并未真正的删除.这一行仅仅是被标记为删除,并且可利用空间计数器和指针会相应的调整. 行的状态信息存储在占用每一行的前几个字节的Row Header.  Row Header 包含: 1 Row Flag 判断这行是不是行首,第一列,最后一列在不在其中,是否有行迁移和行链接.是一个标志位. 2 Lock Byte(ITL entry)和列数. 3 column count Row Flag 是一个单byte的标志掩码:标识了row的状态.标志掩码的译码如

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

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

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

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

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

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

行链接 行迁移的消除

模拟行链接: 如何模仿行链接? 首先要了解三个语句: 第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; 把产生行

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

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

[20160528]bbed观察行目录变化.txt

[20160528]bbed观察行目录变化.txt 如果使用bbed观察kdbr,可以发现记录的是相对偏移量,这个偏移我一直认为从kdbh算起.而对于数据块前面有ITL槽信息,对于有2个ITL的块, 使用assm的表空间,一般我看到都是100.如果一个块上有多个事务,ITL槽会增加,kdbh的地址就会发生变化,这样记录在kdbr的行目录信息 就存在变化,通过例子来说明: 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VE

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

[20160726]行链接行迁移与ITL槽.txt 当表中一行的数据不能在一个数据block中放入的时候,这个时候就会发生两种情况,一种是行链接(Row Chaining),另外一种就是行迁 移(Row Migration)了. 行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下.这种情况下,Oracle将使用链接一个或者多个在这个段 中保留的block存储这一行记录,行链接比较容易发生在比较大的行上,例如行上有LONG.LONG RAW.LOB等数据类型的字段,这种时候