[20160803]另類行遷移.txt
[20160803]另類行遷移.txt
--前幾天做測試時,連結:
http://blog.itpub.net/267265/viewspace-2122712/=>[20160729]行連結行遷移與ITL槽4.txt
--發現一個塊中的記錄在欄位長度變長後全部發生行遷移,感覺很奇怪,當時也沒有仔細思考(開始以為至少有一些記錄不會發生行遷移的
--情況),事後才想起來以前我做過類似的測試,參考連結:
http://blog.itpub.net/267265/viewspace-1742243/=> [20150720]為什麼8K資料塊Hakan Factor=736
--為了加強記憶,重複測試:
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
create table t (id number,pad varchar2(200));
alter table t pctfree 0;
create unique index pk_t on t(id);
alter table t add constraint pk_t primary key (id) enable validate;
insert into t(id) select rownum from dual connect by level<=734;
commit ;
SCOTT@book> select rowid,id from t where id =1 or id=734 or id=733;
ROWID ID
------------------ ----------
AAAXWyAAEAAAALrAAA 1
AAAXWyAAEAAAALrALc 733
AAAXWyAAEAAAALsAAA 734
SCOTT@book> @ &r/rowid AAAXWyAAEAAAALrAAA
OBJECT FILE BLOCK ROW DBA TEXT
---------- ---------- ---------- ---------- -------------------- ----------------------------------------
95666 4 747 0 4,747 alter system dump datafile 4 block 747 ;
--//dba=4,747,一塊共733條記錄。
SCOTT@book> alter system checkpoint ;
System altered.
--按照前面的理論,一條記錄至少保留9個位元組.
BBED> set dba 4,747
DBA 0x0240008e (37748878 9,142)
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 747 Dba:0x010002eb
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 72 bytes @20
struct kdbh, 14 bytes @100
struct kdbt[1], 4 bytes @114
sb2 kdbr[733] @118
ub1 freespace[1579] @1584
ub1 rowdata[5025] @3163
ub4 tailchk @8188
-- 計算如下:
8192-1584-4=6604 (扣除尾部tailchk4個位元組)
6604/733=9.00954979536152796725 (平均9個位元組,如果全部記錄發生行遷移,至少要儲存9個位元組)
6604-733*9=7 (餘數)
BBED> x /rnc *kdbr[0]
rowdata[3341] @6504
-------------
flag@6504: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@6505: 0x01
cols@6506: 1
col 0[2] @6507: 1
BBED> x /rnc *kdbr[1]
rowdata[3347] @6510
-------------
flag@6510: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@6511: 0x01
cols@6512: 1
col 0[2] @6513: 2
--//這裡1條記錄佔6個位元組,數字1佔2個位元組.還剩下9-6=3個位元組,其中一個作為長度指示器,這樣修改欄位pad字元長度增
--//加3,應該就會出現行遷移的情況.測試看看.
2.測試:
$ cat a.sql
update t set pad=lpad('x',3,'x') where id=&&1;
commit ;
quit;
spool b.sh
select 'sqlplus -s scott/book @a.sql '|| rownum from dual connect by level<=734;
spool off
--//編輯整理,執行b.sh.這樣將產生大量的行遷移.
SCOTT@book> alter system checkpoint ;
System altered.
SCOTT@book> alter system dump datafile 4 block 747 ;
System altered.
$ grep nrid /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_39869.trc | cut -d":" -f2 | cut -d"." -f1 | sort | uniq -c
167 0x010002ec
167 0x010002ed
167 0x010002ee
167 0x010002ef
61 0x010002f9
167+167+167+167+61=729,僅僅4條沒有發生行遷移.
--轉儲其中1塊0x010002ec
SCOTT@book> @ &r/dfb16 0x010002ec
RFILE# BLOCK# TEXT
---------- ---------- ------------------------------------------------------------
4 748 alter system dump datafile 4 block 748 ;
SCOTT@book> alter system checkpoint ;
System altered.
SCOTT@book> alter system dump datafile 4 block 748 ;
System altered.
$ sed -n "/Itl/,/bdba:/p" /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_41566.trc
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0009.008.000036c8 0x00c00103.091d.0b C--- 0 scn 0x0003.157b2d98
0x02 0x000a.00c.0000d54b 0x00c002dd.2b3c.17 C--- 0 scn 0x0003.157b37e2
0x03 0x000a.005.0000d554 0x00c002dd.2b3c.1a C--- 0 scn 0x0003.157b37e7
0x04 0x000a.007.0000d54e 0x00c002dd.2b3c.1d C--- 0 scn 0x0003.157b37ec
0x05 0x000a.01f.0000d554 0x00c002dd.2b3c.20 C--- 0 scn 0x0003.157b37f1
0x06 0x000a.017.0000d549 0x00c002dd.2b3c.23 C--- 0 scn 0x0003.157b37f6
0x07 0x000a.00a.0000d565 0x00c002dd.2b3c.26 C--- 0 scn 0x0003.157b37fb
0x08 0x000a.01c.0000d51e 0x00c002dd.2b3c.29 C--- 0 scn 0x0003.157b3800
0x09 0x000a.018.0000d55b 0x00c002dd.2b3c.2c C--- 0 scn 0x0003.157b3805
0x0a 0x000a.01a.0000d553 0x00c002dd.2b3c.2f C--- 0 scn 0x0003.157b380a
0x0b 0x000a.010.0000d549 0x00c002dd.2b3c.32 C--- 0 scn 0x0003.157b380f
...
0xa5 0x000a.016.0000d559 0x00c002e3.2b3c.1a C--- 0 scn 0x0003.157b3b19
0xa6 0x0009.004.000036c8 0x00c00106.091d.10 C--- 0 scn 0x0003.157b3b1f
0xa7 0x0007.010.000018cb 0x00c000e3.0661.21 C--- 0 scn 0x0003.157b3b24
0xa8 0x000a.019.0000d555 0x00c002e3.2b3c.1d C--- 0 scn 0x0003.157b3b29
0xa9 0x0003.017.000010ed 0x00c0015d.0cda.0f --U- 1 fsc 0x0000.157b3c6a
bdba: 0x010002ec
-- 0xa9 = 169. 總共佔用169個ITL槽.這也進一步證明8k的資料庫最多佔用169個ITL槽.
BBED> set dba 4,748
DBA 0x010002ec (16777964 4,748)
BBED> map /v
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 748 Dba:0x010002ec
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
ub1 type_kcbh @0
ub1 frmt_kcbh @1
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4
ub4 bas_kcbh @8
ub2 wrp_kcbh @12
ub1 seq_kcbh @14
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18
struct ktbbh, 4080 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
sb2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[169], 4056 bytes @44
struct kdbh, 14 bytes @4108
ub1 kdbhflag @4108
sb1 kdbhntab @4109
sb2 kdbhnrow @4110
sb2 kdbhfrre @4112
sb2 kdbhfsbo @4114
sb2 kdbhfseo @4116
sb2 kdbhavsp @4118
sb2 kdbhtosp @4120
struct kdbt[1], 4 bytes @4122
sb2 kdbtoffs @4122
sb2 kdbtnrow @4124
sb2 kdbr[168] @4126
ub1 freespace[870] @4462
ub1 rowdata[2856] @5332
ub4 tailchk @8188
--可以發現freespace還有870,但是ITL槽的數量不在增加.
SCOTT@book> analyze table t list chained rows;
Table analyzed.
SCOTT@book> analyze table t compute statistics;
Table analyzed.
SCOTT@book> select table_name, num_rows, chain_cnt, avg_row_len from user_tables where table_name='T';
TABLE_NAME NUM_ROWS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- -----------
T 734 729 17
3.繼續演示ITL不足的情況,如果有多個事務出現在該塊,由於要增加ITL槽,這樣必須搶佔freespace,這樣就不能保證記錄的擴充套件,實際上
oracle這個時候不允許增加itl槽,這樣就出現itl不足的情況.這也是我前次測試的結果:
--重來。
--drop table t purge ;
create table t (id number,pad varchar2(200));
alter table t pctfree 0;
create unique index pk_t on t(id);
alter table t add constraint pk_t primary key (id) enable validate;
insert into t(id) select rownum from dual connect by level<=734;
commit ;
SCOTT@book> select rowid,id from t where id =1 or id=734 or id=733;
ROWID ID
------------------ ----------
AAAXW0AAEAAAALrAAA 1
AAAXW0AAEAAAALrALc 733
AAAXW0AAEAAAALsAAA 734
SCOTT@book> @ &r/rowid AAAXW0AAEAAAALrAAA
OBJECT FILE BLOCK ROW DBA TEXT
---------- ---------- ---------- ---------- -------------------- ----------------------------------------
95668 4 747 0 4,747 alter system dump datafile 4 block 747 ;
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 747 Dba:0x010002eb
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 72 bytes @20
struct kdbh, 14 bytes @100
struct kdbt[1], 4 bytes @114
sb2 kdbr[733] @118
ub1 freespace[1579] @1584
ub1 rowdata[5025] @3163
ub4 tailchk @8188
--//可以發現freespace=1579 ,還有許多。
--session 1,注意不提交:
SCOTT@book(68,1377)> update t set pad=lpad('a',10,'a') where id=1;
1 row updated.
--session 2,注意不提交:
SCOTT@book(101,3247)> update t set pad=lpad('a',10,'a') where id=2;
1 row updated.
--session 3,注意不提交:
SCOTT@book(112,565)> update t set pad=lpad('a',10,'a') where id=3;
--//看看等待事件:
cat wait.sql
select p1raw,p2raw,p3raw,p1,p2,p3,sid,serial#,seq#,event,state,wait_time_micro,seconds_in_wait from v$session where wait_class<>'Idle' order by event ;
SCOTT@book> @ &r/wait
P1RAW P2RAW P3RAW P1 P2 P3 SID SERIAL# SEQ# EVENT STATE WAIT_TIME_MICRO SECONDS_IN_WAIT
---------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------------------------------- ------------------- --------------- ---------------
0000000062657100 0000000000000001 00 1650815232 1 0 123 265 25 SQL*Net message to client WAITED SHORT TIME 2 0
0000000054580004 0000000000090005 00000000000036C9 1415053316 589829 14025 112 565 38 enq: TX - allocate ITL entry WAITING 8500417 9
--出現了enq: TX - allocate ITL entry等待事件,而這個時候透過bbed觀察,freespace=1579的情況.
總結:
1.這種情況在實際系統很少見,僅僅出現在行記錄很短的情況。
2.一旦發生行遷移,在被行遷移的塊中會增加至少1個ITL槽,當然我的測試非常極端,出現增加10-20個ITL槽應該是正常的。
3.這種情況另外一個副產品就是itl不足,當然也出現在塊寫很慢,行記錄很短的情況較常見。
4.從另外一個側面說明為什麼8K資料塊Hakan Factor=736 ,要保留行遷移的記錄nrid 6個位元組+前面3個
5.其實這些測試並不重要,主要在於更好的理解oracle的一些內部結構。
--補充測試:
)> update t set pad=lpad('a',10,'a') where id=4;
1 row updated.
SCOTT@book(112,565)> commit ;
Commit complete.
SCOTT@book(112,565)> alter system checkpoint ;
System altered.
BBED> set dba 4,747
DBA 0x010002eb (16777963 4,747)
BBED> x /rnc *kdbr[2]
rowdata[9] @3136
----------
flag@3136: 0x20 (KDRHFH)
lock@3137: 0x00
cols@3138: 0
nrid@3139:0x010002ee.1
BBED> x /rnc *kdbr[3]
rowdata[0] @3127
----------
flag@3127: 0x20 (KDRHFH)
lock@3128: 0x01
cols@3129: 0
nrid@3130:0x010002ee.2
--//最少預留9個位元組。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2122887/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20140213]再論行遷移.txt
- [20160726]行連結行遷移與ITL槽.txt
- 查詢行遷移及消除行遷移(chained rows)AI
- [20180327]行遷移與ITL浪費.txt
- [20160803]解析正規表示式.txt
- [20160729]行連結行遷移與ITL槽4.txt
- [20160727]行連結行遷移與ITL槽2.txt
- [20160728]]行連結行遷移與ITL槽3.txt
- [20230425]CBO cost與行遷移關係.txt
- [20160803]exp/imp語法問題.txt
- [20180402]行連結行遷移與ITL槽6.txt
- 行遷移測試
- [20140209]行遷移和expdp匯出.txt
- 行遷移和行連結
- [20121116]通過bbed觀察行連結與行遷移.txt
- Oracle行遷移實驗Oracle
- 清除行遷移的例子
- [20190120]行連結遷移與dml.txt
- 清除行遷移和行連結
- 行遷移(鏈化行)問題
- CRM系統如何進行另類資料管理?
- 另類SQL拼接方法SQL
- 另類SQL優化SQL優化
- 遷移學習時間序列分類遷移學習
- 遷移執行緒migration執行緒
- 行遷移_行連結的介紹
- 如何消除行連結和行遷移
- 另類 RobotFramework 使用法Framework
- ThinkPHP之另類RBAC效果PHP
- 模擬Oracle行遷移和行連結Oracle
- pctused, pctfree, pctincrease , 行遷移 & 行連結
- 行遷移和行連結的檢測
- 查詢表存在大量行遷移
- 使用RMAN進行資料遷移
- 今天晚上進行資料遷移
- [20130607]行遷移與ALTER TABLE MINIMIZE RECORDS_PER_BLOCK.txtBloC
- KVM線上遷移(動態遷移)
- 另類網路層設計