行連結(Row chaining)和行遷移(Row Migration)的讀書筆記

hunterjoy發表於2008-05-03

   今天上午,陰雲密佈,天氣很黑,屋外雷雨交加,是個看書的好日子.偶爾在電腦上看到以前下載的CSDN Emag(Oracle)第一期,瀏覽了一下,發現Coolyl寫得不錯,以前也看過不少有關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';

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/543979/viewspace-257599/,如需轉載,請註明出處,否則將追究法律責任。

相關文章