行链接(Row chaining)和行迁移(Row Migration)的读书笔记

上一篇 / 下一篇  2008-05-03 10:29:02

   今天上午,阴云密布,天气很黑,屋外雷雨交加,是个看书的好日子.偶尔在电脑上看到以前下载的CSDN Emag(Oracle)第一期,浏览了一下,发现Coolyl写得<关于Oracle数据库中行迁移/行链接的问题>不错,以前也看过不少有关Row chaining和Row Migration的文章,但对其中的概念还比较容易混淆,特在看完这篇文章之后做以小结.

1.一个Oracle block由三个部分组成,分别是数据块头、自由空间、实际数据三部份组成。

数据块头:主要包含有数据块地址的一些基本信息和段的类型,以及表和包含有数据的实际行的地址。
自由空间:是指可以为以后的更新和插入操作分配的空间,大小由PCTFREE和PCTUSED两个参数影响。
实际数据:是指在行内存储的实际数据。

当创建或者更改任何表和索引的时候,Oracle在空间控制方面使用两个存储参数:
PCTFREE:为将来更新已经存在的数据预留空间的百分比。
PCTUSED:用于为插入一新行数据的最小空间的百分比。这个值决定了块的可用状态。可用的块时可以执行插入的块,不可用状态的块只能执行删除和修改,可用状态的块被放在freelist中。


当表中一行的数据不能在一个数据block中放入的时候,这个时候就会发生两种情况,一种是行链接,另外一种就是行迁移了。

   行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下。这种情况下,Oracle将使用链接一个或者多个在这个段中保留的block存储这一行记录,行链接比较容易发生在比较大的行上,例如行上有LONG、LONG RAW、LOB等数据类型的字段,这种时候行链接是不可避免的会产生的。
   当一行记录初始插入的时候事可以存储在一个block中的,由于更新操作导致行长增加了,而block的自由空间已经完全满了,这个时候就产生了行迁移。在这种情况下,Oracle将会迁移整行数据到一个新的block中(假设一个block中可以存储下整行数据),Oracle会保留被迁移行的原始指针指向新的存放行数据的block,这就意味着被迁移行的ROW ID是不会改变的。

  也就是说Row chaining 往往发生在INSERT时候,Row Migration往往发生在UPDATE的时候.

2.test:

create table test ( x int primary key, a char(2000), b char(2000), c char(2000), d char(2000), e char(2000) ) tablespace TS_TEST;

查看TS_TEST这个表空间的数据文件号

select file_id from dba_data_files where tablespace_name='TS_TEST';

数据库的db_block_size是8K,创建的表有五个字段,每个占2000个字节,这样一行记录大约10K,就能超过一个block的大小了。

insert into test(x) values (1);COMMIT;

查找这行记录所在的block,并dump出来

select dbms_rowid.rowid_block_number(rowid) from test;

alter system dump datafile 23 block 34;

在udump目录下查看trace文件的内容

update test set a='test',COMMIT;

alter system dump datafile 23 block 34;

trace文件的内容:nrid出现了值,指向了下一个row id,证明刚刚的update操作使这行记录产生了行链接或者行迁移了

3.行迁移/行链接的检测

1>利用Oracle数据库自身提供的脚本utlchain.sql(在$ORACLE_HOME/rdbms/admin目录下)生成chained_rows表,然后利用ANALYZE TABLE table_name LIST CHAINED ROWS INTO chained_rows命令逐个分析表,将分析的结果存入chained_rows表中。从utlchain.sql脚本中我们看到chained_rows的建表脚本,对于分区表,cluster表都是适用的。然后可以使用拼凑语句的办法生成分析所需要的表的脚本,并执行脚本将具体的分析数据放入Chained_rows表中

2>查询v$sysstat视图中的’table fetch continued row’列得到当前的行链接和行迁移数量

SELECT name, value FROM v$sysstat WHERE name = 'table fetch continued row';


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-07-25  
  12345
6789101112
13141516171819
20212223242526
2728293031  

数据统计

  • 访问量: 457
  • 日志数: 20
  • 书签数: 15
  • 建立时间: 2007-12-31
  • 更新时间: 2008-07-13

RSS订阅

Open Toolbar