[20190102]塊內重整2.txt
[20190102]塊內重整2.txt
--//我不知道用什麼術語表達這樣的情況,我僅僅一次開會對方這麼講,我現在也照用這個術語.
--//當dml插入資料到資料塊時,預留一定的空間(pctfree的百分比)不再插入.保留一些空間主要目的為了ITL的增加,以及update時空間增長.
--//避免大量的行遷移情況出現.
--//當到達頂部時,會出現一次塊內重整(也有叫塊內重組).透過演示瞭解這個過程,同時瞭解資料塊內一些資訊的變化.
--//昨天的測試忘記跟蹤對應資料塊不同情況下的kdbh.kdbhfrre變化,重新測試看看.
--//而且當時在不同會話插入,應該在同一會話插入也應該能演示出來.
1.環境:
SCOTT@book> @ 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 as select rownum id,to_char(rownum)||lpad('x',800,'x') name from dual connect by level<=8;
Table created.
SCOTT@book> @desc t
Name Null? Type
----- -------- -------------
1 ID NUMBER
2 NAME VARCHAR2(840)
--//name 定義VARCHAR2(840).
SCOTT@book> select rowid ,id from t;
ROWID ID
------------------ ----------
AAAWFjAAEAAAAIjAAA 1
AAAWFjAAEAAAAIjAAB 2
AAAWFjAAEAAAAIjAAC 3
AAAWFjAAEAAAAIjAAD 4
AAAWFjAAEAAAAIjAAE 5
AAAWFjAAEAAAAIjAAF 6
AAAWFjAAEAAAAIjAAG 7
AAAWFjAAEAAAAIjAAH 8
8 rows selected.
--//8k的資料塊.有8條記錄在一個塊中.
SCOTT@book> @rowid AAAWFjAAEAAAAIjAAA
OBJECT FILE BLOCK ROW ROWID_DBA DBA TEXT
---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
90467 4 547 0 0x1000223 4,547 alter system dump datafile 4 block 547 ;
SCOTT@book> alter system checkpoint ;
System altered.
2.透過bbed觀察:
BBED> set dba 4,547
DBA 0x01000223 (16777763 4,547)
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[1550] @158
ub1 rowdata[6480] @1708
ub4 tailchk @8188
--//還有freespace=1550.
BBED> p kdbr
sb2 kdbr[0] @142 7254
sb2 kdbr[1] @144 6444
sb2 kdbr[2] @146 5634
sb2 kdbr[3] @148 4824
sb2 kdbr[4] @150 4014
sb2 kdbr[5] @152 3204
sb2 kdbr[6] @154 2394
sb2 kdbr[7] @156 1584
BBED> x /rnc *kdbr[0]
rowdata[5670] @7378
-------------
flag@7378: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@7379: 0x00
cols@7380: 2
col 0[2] @7381: 1
col 1[801] @7384: 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ..trunc.
--//注這裡的偏移是相對偏移 7254+124(kdbh地址) = 7378.
--//共佔用3+1+2+3+801 = 810,注前面有1個位元組保持長度指示器.另外注意字串長度大於250,需要使用3個位元組儲存長度指示器.
--//可以從資料的偏移量可以看出資料是從塊底開始插入的.當前剩餘空間是1550.
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 -1
--//kdbh.kdbhfrre=-1,也就是這個時候沒有刪除記錄的情況,或者沒有可重用的行目錄.
3.繼續測試,刪除部分資料:
--//先刪除一部分資料,僅僅打上標識標識刪除.
SCOTT@book> delete from t where id in (1,3,6,7);
4 rows deleted.
SCOTT@book> commit ;
Commit complete.
SCOTT@book> alter system checkpoint ;
System altered.
--//透過bbed觀察,執行前打入set dba 4,547,這樣才會從磁碟重新讀取資料塊.不然看到是當前快取資料塊的資訊,以下測試注意這個問
--//題.
BBED> set dba 4,547
DBA 0x01000223 (16777763 4,547)
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[1550] @158
ub1 rowdata[6480] @1708
ub4 tailchk @8188
--//刪除部分記錄,freespace空間保持不變.
BBED> p kdbr
sb2 kdbr[0] @142 7254
sb2 kdbr[1] @144 6444
sb2 kdbr[2] @146 5634
sb2 kdbr[3] @148 4824
sb2 kdbr[4] @150 4014
sb2 kdbr[5] @152 3204
sb2 kdbr[6] @154 2394
sb2 kdbr[7] @156 1584
BBED> x /rnc *kdbr[0]
rowdata[5670] @7378
-------------
flag@7378: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@7379: 0x02
cols@7380: 0
--//oracle僅僅修改flag從2c變成3c,加入了KDRHFD標識,表示刪除,這個時候可以透過bbed修復.
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 -1
--//kdbh.kdbhfrre=-1,沒有變化.
4.然後修改一部分資料看看:
SCOTT@book> update t set name=lpad('a',811,'a') where id=2;
1 row updated.
SCOTT@book> commit ;
Commit complete.
SCOTT@book> alter system checkpoint ;
System altered.
--//我修改的長度與原來不等,這樣增加長度增加10個位元組.這樣還剩下1550-820 = 730位元組.
--//驗證看看:
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[730] @158
ub1 rowdata[7300] @888
ub4 tailchk @8188
--//freespace=730,ok正確!!
BBED> p kdbr
sb2 kdbr[0] @142 7254
sb2 kdbr[1] @144 764
sb2 kdbr[2] @146 5634
sb2 kdbr[3] @148 4824
sb2 kdbr[4] @150 4014
sb2 kdbr[5] @152 3204
sb2 kdbr[6] @154 2394
sb2 kdbr[7] @156 1584
--//kdbr[1] 指向新的位置.對應id=2的記錄.其它沒有變化.
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 -1
--//kdbh.kdbhfrre=-1,沒有變化.
BBED> x /rnc *kdbr[1]
rowdata[0] @888
----------
flag@888: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@889: 0x03
cols@890: 2
col 0[2] @891: 2
col 1[811] @894: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..trunc..
--//如果繼續修改記錄,長度消耗大於730並且長度與原來不一樣,這樣就會出現塊內重整的情況:
SCOTT@book> update t set name=lpad('b',811,'b') where id=4;
1 row updated.
SCOTT@book> commit ;
Commit complete.
SCOTT@book> alter system checkpoint ;
System altered.
BBED> set dba 4,547
DBA 0x01000223 (16777763 4,547)
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[4762] @158
ub1 rowdata[3268] @4920
ub4 tailchk @8188
-//freespace變成了4762,出現一次塊內重整,而且收回刪除記錄的空間.
BBED> p kdbr
sb2 kdbr[0] @142 8062
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 7240
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6428
sb2 kdbr[6] @154 6426
sb2 kdbr[7] @156 5616
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 -1
--//kdbh.kdbhfrre=-1,沒有變化.
--//可以發現行目錄發生變化對比前面的情況,做了整理,整體下移.我前面刪除的記錄是id in (1,3,6,7);
--//id=6,7的記錄應該對應kdbr[5],kdbr[6],可以發現記錄的偏移地址6428,6426,挨的很近.
--//可以大致猜測它的演算法,移動除kdbr[3](對應id=4)的記錄下移騰出空間,你可以發現kdbr[3]指向的偏移是當前最小的.
BBED> x /rnc *kdbr[5]
rowdata[1632] @6552
-------------
flag@6552: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@6553: 0x02
cols@6554: 0
BBED> x /rnc *kdbr[6]
rowdata[1630] @6550
-------------
flag@6550: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@6551: 0x02
cols@6552: 0
BBED> dump /v offset 6550 count 20
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Offsets: 6550 to 6569 Dba:0x01000223
-----------------------------------------------------------------------------------------------------------
3c023c02 2c000202 c106fe21 03357878 78787878 l <.<.,......!.5xxxxxx
<32 bytes per line>
--//僅僅保留2個位元組.這也很容易理解打上刪除標識後,為什麼bbed不顯示後面的資料資訊(如果能顯示的話)
BBED> x /rnc *kdbr[0]
rowdata[3266] @8186
-------------
flag@8186: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@8187: 0x02
cols@8188: 0
BBED> dump /v count 20
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Offsets: 8186 to 8191 Dba:0x01000223
-----------------------------------------------------------------------------------------------------------
3c020206 c4dc l <.....
~~~~~~~~~
<32 bytes per line>
--//後面4個位元組是taichk的資訊.這個時候按照以前使用bbed修復刪除記錄的方法是無用的.因為對應的記錄資訊已經被覆蓋了.
5.繼續插入記錄看看.
SCOTT@book> insert into t values(9,to_char(9)||lpad('y',800,'y'));
1 row created.
SCOTT@book> commit ;
Commit complete.
SCOTT@book> alter system checkpoint ;
System altered.
--//當前塊已經空出許多空間,可以繼續插入資料,看看這時的情況:
BBED> set dba 4,547
DBA 0x01000223 (16777763 4,547)
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[9] @142
ub1 freespace[3950] @160
ub1 rowdata[4078] @4110
ub4 tailchk @8188
--//freespace在減少,前面4762,現在freespace=3950.
--//減少4762-3950 = 812,比前面多消耗2個位元組是因為行目錄增加1行.從7->8,這樣多消耗2個位元組.
BBED> p kdbr
sb2 kdbr[0] @142 2
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 5
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6
sb2 kdbr[6] @154 -1
sb2 kdbr[7] @156 5616
sb2 kdbr[8] @158 3986
--//可以發現當前塊又插入1條.
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 0
--//kdbh.kdbhfrre=0.已經從-1變成0.
BBED> x /rnc *kdbr[8]
rowdata[0] @4110
----------
flag@4110: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@4111: 0x02
cols@4112: 2
col 0[2] @4113: 9
col 1[801] @4116: 9yyyyyyyyyyyyyyyyyyyyyy...trunc..
--//注意看前面的kdbr[0],kdbr[2],kdbr[5],kdbr[6]對應的偏移量已經發生變化,變成2,5,6,-1,透過偏移量連結起來.
--//也就是這個這時的偏移量指向的地址根本不是rowdate區域.
--//我不知道是否可以得出這樣結論:如果kdbr指向的值如果小於當前的行目錄數量(9),這些行對應的記錄應該是刪除的.
--//理論講這時對應記錄很難恢復,已經覆蓋了.
--//另外注意這時kdbh.kdbhfrre=0,也就是指向kdbr[0].
6.測試重用的情況:
--//是否會重用呢?繼續插入看看.
SCOTT@book> insert into t values(10,to_char(10)||lpad('x',800,'x'));
1 row created.
SCOTT@book> commit ;
Commit complete.
SCOTT@book> alter system checkpoint ;
System altered.
BBED> set dba 4,547
DBA 0x01000223 (16777763 4,547)
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[9] @142
ub1 freespace[3139] @160
ub1 rowdata[4889] @3299
ub4 tailchk @8188
--//freespace=3139.3950-3139 = 811,比前面多1個自己,是因為插入的name=to_char(10)||lpad('x',800,'x'),多了1個位元組.
BBED> p kdbr
sb2 kdbr[0] @142 3175
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 5
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6
sb2 kdbr[6] @154 -1
sb2 kdbr[7] @156 5616
sb2 kdbr[8] @158 3986
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 2
--//oracle在插入時能快速定位到kdbr[0],因為當時的kdbh.kdbhfrre=0,能很快定位到行目錄kdbr[0]的位置,並且插入後修改
--//kdbh.kdbhfrre=2,指向下一個能插入的位置.
--//實際上到這裡可以刪除連結串列的頭記錄在kdbh.kdbhfrre中,當前是2.如果繼續插入,變成5就可以驗證我的判斷。
SCOTT@book> insert into t values(11,to_char(11)||lpad('w',800,'w'));
1 row created.
SCOTT@book> commit ;
Commit complete.
SCOTT@book> alter system checkpoint ;
System altered.
BBED> map
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[9] @142
ub1 freespace[2328] @160
ub1 rowdata[5700] @2488
ub4 tailchk @8188
--//freespace繼續減少。3139-2328 = 811.
BBED> p kdbr
sb2 kdbr[0] @142 3175
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 2364
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6
sb2 kdbr[6] @154 -1
sb2 kdbr[7] @156 5616
sb2 kdbr[8] @158 3986
--//插入記錄佔用了kdbr[2]。
BBED> p kdbh.kdbhfrre
sb2 kdbhfrre @128 5
--//變成kdbh.kdbhfrre=5,驗證自己的判斷。
--//這樣透過kdbr[5],裡面記錄的是6,繼續插入可以很容易定位行目錄,最後記錄-1,表示已經沒有了,回到初始的狀態.
SCOTT@book> select rowid,id,substr(name,1,10) c10 from t;
ROWID ID C10
------------------ ---------- ----------
AAAWFjAAEAAAAIjAAA 10 10xxxxxxxx
AAAWFjAAEAAAAIjAAB 2 aaaaaaaaaa
AAAWFjAAEAAAAIjAAC 11 11wwwwwwww
AAAWFjAAEAAAAIjAAD 4 bbbbbbbbbb
AAAWFjAAEAAAAIjAAE 5 5xxxxxxxxx
AAAWFjAAEAAAAIjAAH 8 8xxxxxxxxx
AAAWFjAAEAAAAIjAAI 9 9yyyyyyyyy
7 rows selected.
總結:
--//僅僅透過一些簡單的例子基本演示整個過程,也許許多情況下更加複雜.
--//不過已經足以說明這整個過程.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2287110/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20190101]塊內重整.txt
- [20190129]塊內重整3.txt
- [20210317]如何知道索引塊地址2.txt索引
- [20210318]bbed讀取資料塊2.txt
- [20180306]資料塊檢查和2.txt
- 塊級、內聯、內聯塊級
- [20220223]bbed讀取資料塊mssm與assm 2.txtSSM
- [20211108]索引分裂塊清除日誌增加(唯一索引)2.txt索引
- [20190102]ORA-01775 looping chain of synonyms.txtOOPAI
- [20190102]DBMS_SHARED_POOL.MARKHOT與表.txt
- 塊狀元素、內聯元素和內聯塊狀元素
- [20190124]bbed恢復資料遇到延遲塊清除的問題2.txt
- [20190102]關於字串的分配問題(10g).txt字串
- OctoberCMS-7-內容塊
- CSS塊級/內聯元素CSS
- CSS 塊級元素和行內元素和行內塊元素 及其相互轉換CSS
- 塊級元素和行內元素
- HTML 塊級元素和內聯元素HTML
- [20191011]拆分rowid 2.txt
- [20180625]oradebug peek 2.txt
- H5-13 塊元素與行內元素(內聯元素)H5
- 重整旗鼓,2019自結前端面試小冊【JavaScript】前端面試JavaScript
- 前端開發,塊元素與行內元素前端
- 02 CSS塊級元素和行內元素CSS
- 【前端】HTML__內聯元素與塊元素前端HTML
- CSS的塊級元素和行內元素CSS
- 內部區塊鏈的優缺點區塊鏈
- [20231027]Index ITL Limit 2.txtIndexMIT
- [20210828]如何實現2.txt
- [20220322]探究oracle sequence 2.txtOracle
- [20210223]bbed itl ktbitflg 2.txt
- [20181113]Logical Standby建立2.txt
- 重整旗鼓,2019自結前端面試小冊【ECMAScript 6】前端面試
- 重整旗鼓,2019自結前端面試小冊【CSS + HTML】前端面試CSSHTML
- [20190102]連線串不配置服務名能連線資料庫嗎.txt資料庫
- JavaFX 如何使用內建的對話方塊Java
- NFT區塊鏈技術的基本內容區塊鏈
- 塊級元素與內聯元素相互轉換