轉抄:Oracle資料塊深入分析總結
轉抄:Oracle資料塊深入分析總結
最近在研究塊的內部結構,把文件簡單整理了一下,和大家分享一下。該篇文章藉助dump和BBED對資料
庫內部結構進行了分析,最後附加了一個用BBED解決ORA-1200錯誤的小例子。在總結的過程中參考了
《Disassembling the Oracle Data Block》以及網上的翻譯版本。
dump說明
建立表空間和測試表:
create tablespace testblock datafile '/opt/oracle/oradata/oradb/testblock01.dbf' size 100M;
create table testblock(
id number,
name varchar(4)
) tablespace testblock;
插入3條資料然後提交:
SQL> insert into testblock values(1,'a');
SQL> insert into testblock values(2,'b');
SQL> insert into testblock values(3,'c');
SQL> commit;
SQL> select * from testblock;
ID NAME
---------- --------
1 a
2 b
3 c
SQL> select rowid,dbms_rowid.rowid_relative_fno(rowid) rel_fno,dbms_rowid.rowid_block_number(rowid)
blockno from testblock;
ROWID REL_FNO BLOCKNO
------------------ ---------- ----------
AAANK4AAFAAAAAQAAA 5 16
AAANK4AAFAAAAAQAAB 5 16
AAANK4AAFAAAAAQAAC 5 16
我們看到這3行資料都在5號資料檔案的第16個塊
執行資料塊dump:
SQL> alter system dump datafile 5 block 16;
以下是該資料塊的完整dump結果:
Start dump data blocks tsn: 7 file#: 5 minblk 16 maxblk 16
buffer tsn: 7 rdba: 0x01400010 (5/16)
scn: 0x0000.001732d3 seq: 0x01 flg: 0x04 tail: 0x32d30601
frmt: 0x02 chkval: 0x84cb type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0CEB6400 to 0x0CEB8400
CEB6400 0000A206 01400010 001732D3 04010000 [......@..2......]
CEB6410 000084CB 00000001 0000D2B8 001732D3 [.............2..]
CEB6420 00000000 00320002 01400009 00200006 [......2...@... .]
CEB6430 00000271 00800205 00130257 00008000 [q.......W.......]
CEB6440 001732C4 00060008 00000279 00800351 [.2......y...Q...]
CEB6450 00150278 00000001 00000000 00000000 [x...............]
CEB6460 00000000 00030100 0018FFFF 1F651F5E [............^.e.]
CEB6470 00001F65 1F5E0003 1F801F66 00000000 [e.....^.f.......]
CEB6480 00000000 00000000 00000000 00000000 [................]
Repeat 499 times
CEB83C0 022C0000 02C10202 002C6101 03C10202 [..,......a,.....]
CEB83D0 012C6201 03C10202 2C626202 C1020200 [.b,......bb,....]
CEB83E0 61610202 0202002C 630104C1 0202002C [..aa,......c,...]
CEB83F0 620103C1 0202002C 610102C1 32D30601 [...b,......a...2]
Block header dump: 0x01400010
Object id on Block? Y
seg/obj: 0xd2b8 csc: 0x00.1732d3 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1400009 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.020.00000271 0x00800205.0257.13 C--- 0 scn 0x0000.001732c4
0x02 0x0008.006.00000279 0x00800351.0278.15 ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0xceb6464
===============
tsiz: 0x1f98
hsiz: 0x18
pbl: 0x0ceb6464
bdba: 0x01400010
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f5e
avsp=0x1f65
tosp=0x1f65
0xe:pti[0] nrow=3 ffs=0
0x12:pri[0] ffs=0x1f5e
0x14:pri[1] ffs=0x1f66
0x16:pri[2] ffs=0x1f80
block_row_dump:
tab 0, row 0, @0x1f5e
tl: 8 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [ 1] 61
tab 0, row 1, @0x1f66
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [ 1] 62
tab 0, row 2, @0x1f80
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 1] 63
end_of_block_dump
End dump data blocks tsn: 7 file#: 5 minblk 16 maxblk 16
頭資訊區
這個區包括資料塊的地址,資料塊型別,檢查點資訊,scn資訊等資訊。
---------
Start dump data blocks tsn: 7 file#: 5 minblk 16 maxblk 16
buffer tsn: 7 rdba: 0x01400010 (5/16)
scn: 0x0000.001732d3 seq: 0x01 flg: 0x04 tail: 0x32d30601
frmt: 0x02 chkval: 0x84cb type: 0x06=trans data
---------
buffer tsn:7 --該塊對應的表空間號,這裡是7號表空間。
rdba: 0x01400010 (5/16) --相對資料塊地址,表示該塊為5號資料檔案第16個塊,用4個位元組32位來表示,前10位為相對資料檔案號,後22位為塊號。01400010=0000 0001 0100 0000 0000 0000 0001 0000(二進位制)
我們看到前10位轉換成十進位制就是5,後22位轉換成十進位制就是16。rdba在資料塊中的offset是4,即rdba存在於資料塊中的第5-9位元組中(offset從0開始算),資料塊中的每個部分在資料塊中的偏移量後邊會透過BBED展
示,這裡可以先不關心。
scn: 0x0000.001732d3 --資料塊頭部SCN,總共佔用6個位元組,前2個位元組表示SCN Wrap,後4個位元組表示SCN
Base。如果SCN Base達到了4個位元組表示的最大值,SCN Wrap+1,SCN Base清0。在資料塊中的offset是8
seq: 0x01 --Sequence number, incremented for every change made to the block at the same SCN。這裡可以理解為資料塊的版本。在資料塊中的offset是14.
flg: 0x04 --Flag: 0x01 New block/0x02 Delayed Logging Change advanced SCN/seq 0x04 Check value/saved - block XOR‘s to zero/0x08 Temporary block 。在資料塊中的offset是15
tail: 0x32d30601 --即tail check,存放於資料塊的最後4個位元組,用於資料塊一致性檢查。tail check的組成:
SCN Base的低2個位元組+type+seq。即tail: 0x32d30601=32d3+06+01
frmt: 0x02 -- 塊格式。01表示Oracle 7, 02表示Oracle 8+
chkval: 0x84cb --塊檢查值。我們知道如果引數DB_BLOCK_CHECKSUM=TRUE,那麼資料塊在讀入buffer和寫回資料檔案之前都要做檢查計算,如果計算值和資料塊中記錄的計算值不匹配就會標記該塊是壞塊。
type: 0x06=trans data --塊型別,參考一下表格:
Header Block Types
ID Type
01 Undo segment header
02 Undo data block
03 Save undo header
04 Save undo data block
05 Data segment header (temp, index, data and so on)
06 KTB managed data block (with ITL)
07 Temp table data block (no ITL)
08 Sort Key
09 Sort Run
10 Segment free list block
11 Data file header
資料區、空閒區
資料區是真正儲存資料的地方 ; 空閒區是目前塊內部空閒空間
Dump of memory from 0x0CEB6400 to 0x0CEB8400
CEB6400 0000A206 01400010 001732D3 04010000 [......@..2......]
CEB6410 000084CB 00000001 0000D2B8 001732D3 [.............2..]
CEB6420 00000000 00320002 01400009 00200006 [......2...@... .]
CEB6430 00000271 00800205 00130257 00008000 [q.......W.......]
CEB6440 001732C4 00060008 00000279 00800351 [.2......y...Q...]
CEB6450 00150278 00000001 00000000 00000000 [x...............]
CEB6460 00000000 00030100 0018FFFF 1F651F5E [............^.e.]
CEB6470 00001F65 1F5E0003 1F801F66 00000000 [e.....^.f.......]
CEB6480 00000000 00000000 00000000 00000000 [................]
Repeat 499 times
CEB83C0 022C0000 02C10202 002C6101 03C10202 [..,......a,.....]
CEB83D0 012C6201 03C10202 2C626202 C1020200 [.b,......bb,....]
CEB83E0 61610202 0202002C 630104C1 0202002C [..aa,......c,...]
CEB83F0 620103C1 0202002C 610102C1 32D30601 [...b,......a...2]
事物列表區
事務列表區包括了在這個資料塊內的事務,也就是我們知道的ITL(interested transaction list),從中我們可以知道XID(transaction id),UBA(undo block address)等資訊。
事物列表區分析:
--------------
Block header dump: 0x01400010 --rdba
Object id on Block? Y --該塊是否屬於某個物件
seg/obj: 0xd2b8 csc: 0x00.1732d3 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1400009 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.020.00000271 0x00800205.0257.13 C--- 0 scn 0x0000.001732c4
0x02 0x0008.006.00000279 0x00800351.0278.15 ---- 1 fsc 0x0000.00000000
---------------
seg/obj: 0xd2b8 --該資料塊中物件的object_id。前面我們dump的是表testblock,下邊來驗證一下:
SQL> select to_number('d2b8','xxxxxx') from dual;
TO_NUMBER('D2B8','XXXXXX')
------------------------------
53944
SQL> select object_name,object_type from dba_objects where object_id=53944;
OBJECT_NAME OBJECT_TYPE
------------------------------ --------------------
TESTBLOCK TABLE
csc: 0x00.1732d3 --SCN at last Block CleanOut,表示最後一次塊清除(Block CleanOut)時候的SCN。
itc: 2 --塊中ITL slot的數量,我們看下邊的ITL,的確只有2個slot。
flg: E --flg: 0 表示此塊被放置在自由列表(freelist)中。
typ: 1 - DATA --型別1表示資料,型別2表示索引
bdba --Block relative data block address(RDBA)
下邊我們重點看一下ITL事物槽。Oracle的每個資料塊中都有一個或者多個事務槽,每一個對資料塊的併發訪問
事務都會佔用一個事務槽。
每個事物都會ITL事物槽由槽位號、XID、Uba、Flag、Lck、Scn/Fsc幾部分組成。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.020.00000271 0x00800205.0257.13 C--- 0 scn 0x0000.001732c4
0x02 0x0008.006.00000279 0x00800351.0278.15 ---- 1 fsc 0x0000.00000000
Xid:事務id,在回滾段事務表中有一條記錄和這個事務對應。Xid組成:Undo Segment Number +Transaction
Table Slot Number+ Wrap
Uba:回滾段地址,該事務對應的回滾段地址。Uba組成:回滾塊地址(undo檔案號和資料塊號)+回滾序列號+
回滾記錄號
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
8 6 633 2 849 632 21
Flag:事務標誌位。這個標誌位就記錄了這個事務的操作狀態,各個標誌的含義分別是:
C = transaction has been committed and locks cleaned out --事物已經提交,鎖已經被清除
B = this undo record contains the undo for this ITL entry
U = transaction committed (maybe long ago); SCN is an upper bound --事物已經提交,但是鎖還沒有清除
T = transaction was still active at block cleanout SCN --塊清除的SCN被記錄時,該事務仍然是活動的,塊
上如果有已經提交的事務,那麼在clean ount的時候,塊會被進行清除,但是這個塊裡面的事務不會被清除。
Lck:表示這個事務所影響的行數。我們看到01號事物槽Lck為0,因為該事物槽中的事物Flag為C,證明該事物
已經提交,鎖也被清楚掉了,該事物槽可以被重用了。02號事物槽Lck為1,是因為我對第一行做了一個更新,
並且沒有提交,Flag為----說明該事物是活動的。
Scn/Fsc:Commit SCN或者快速提交(Fast Commit Fsc)的SCN。
每條記錄中的行級鎖對應Itl條目lb,對應於Itl列表中的序號,即那個事務在該記錄上產生的鎖。
對於Oracle來說,對於一個事務,可以是快速提交、也可以是延遲提交,目的都是為了提高提交的速度。提交以後,oracle需要對ITL事務槽、每一行的鎖定標記進行清除。如果是快速提交,那麼在提交的時候,會將事務表和每一個資料塊的ITL槽進行清除。但是鎖定標記可能沒有清除,等下次用到的時候再進行清除。如果是延遲提交,那麼在提交的時候,只是將事務表進行清除,並沒有對ITL事務槽進行清除,每一行的鎖定標記也沒有清除。因此C和U的情況特別多。塊清除的過程並不包括每個行的鎖定標記的清除,主要指的是ITL的清除。
注意:
1、事務槽中首先記錄的是Xid和Uba,只有在提交以後,當對這個資料塊進行cleanout的時候,才會更新Flag和Scn。因此Oracle總是以事務表中對這個資料塊的Scn以及Flag為準。
2、一個事務開始以後,在一個資料塊上得到一個事務槽,那麼在這個事務提交以前,這個事務槽會一直佔用,直到這個事務提交釋放這個事務槽。
3、只有在已經提交以後,這個itl事務槽中的scn才會有數值。
4、事務是否已經提交、事務對應的SCN,這些資訊都是以回滾段事務表中的為主,事務槽中的不準確
5、事務槽中的事務id和uba地址是準確的
6、事務槽1中的事務id和回滾段中的事務id肯定不是一樣的,不同回滾段中的事務id也一定不一樣。
尾區
尾區儲存著資料塊的描述資訊
data_block_dump,data header at 0xceb6464
===============
tsiz: 0x1f98 --Total Data Area Size(資料區的大小 )
hsiz: 0x18 --Data Header Size(資料塊頭大小)
pbl: 0x0ceb6464 --ptr to buffer holding the block(指向這個資料塊在記憶體中映象的指標)
bdba: 0x01400010 --block dba / rdba(資料塊地址)
76543210
flag=--------
ntab=1 --number of tables (>1 is a cluster)
nrow=3 --number of rows
frre=-1 --first free row index entry, -1=you have to add one(沒有建立索引)
fsbo=0x18 --free space begin offset(空閒空間起始位置)
fseo=0x1f5e --free space end offset(空閒空間結束位置)
avsp=0x1f65 --available space in the block(可用空間)
tosp=0x1f65 --total available space when all txs commit
0xe:pti[0] nrow=3 ffs=0 --該塊有3條記錄
0x12:pri[0] ffs=0x1f5e --第1條記錄在偏移量為0x1f5e的地方,下邊兩行以此類推。
0x14:pri[1] ffs=0x1f66
0x16:pri[2] ffs=0x1f80
tab 0, row 0, @0x1f5e
tl: 8 fb: --H-FL-- lb: 0x2 cc: 2 --lb: 0x2說明事物在該資料行上的鎖還沒清除,並且該鎖指向02號事物槽。(此前對改行進行了更新,並且未提交)
col 0: [ 2] c1 02
col 1: [ 1] 61
tab 0, row 1, @0x1f66
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2 --lb: 0x0說明事物在該資料行上的鎖已經被清除。(此前對該行進行了更新,並且已經提交)
col 1: [ 1] 62
tab 0, row 2, @0x1f80
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 1] 63
―――――――――――――
tl --表示Row Size(number of bytes plus data)
fb --Flag Byte
K- Cluster key
H- head of row piece
D- Deleted row
F- first data piece
L- last data piece
P- First column cintinues from previous row
N- Last column cintinues in next piece
當我們delete一行資料的時候,資料並不是物理的被刪除,而是把該行標記為刪除,這個時候fb應該是--HDFL-- 而不是原來的--H-FL-- 。把第3行資料刪除後提交,重新dump一下:
tab 0, row 2, @0x1f80
tl: 8 fb: --HDFL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 1] 63
Lb --表示lock byte,表示鎖定該行的這個事務在itl的入口
Cc --表示number of columns in this Row piece。 關於行中的資料,我們以第一行來說明一下 ,我們知道表的第一行為(1,'a'),我們驗證一下:
col 0: [ 2] c1 02
col 1: [ 1] 61
SQL> select dump(1,16) from dual;
DUMP(1,16)
-----------------
Typ=2 Len=2: c1,2
SQL> select dump('a',16) from dual;
DUMP('A',16)
----------------
Typ=96 Len=1: 61
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9606200/viewspace-745696/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 轉載:Oracle資料塊損壞恢復總結Oracle
- ORACLE壞塊總結(轉)Oracle
- 區塊鏈資料總結區塊鏈
- oracle資料塊格式小結Oracle
- ORACLE壞塊總結2Oracle
- oracle資料塊轉儲說明Oracle
- Oracle資料庫索引使用及索引失效總結 轉Oracle資料庫索引
- MySQL與oracle的資料型別轉換總結MySqlOracle資料型別
- Oracle壞塊問題總結Oracle
- oracle block資料塊結構之itcOracleBloC
- oracle block資料塊結構續(一)OracleBloC
- 【轉】Qt資料庫總結QT資料庫
- Oracle 資料庫12c 16大新特性總結(轉)Oracle資料庫
- 關於 資料壞塊 的整理和總結
- 使用BBED幫助理解Oracle資料塊結構Oracle
- 使用Oracle資料泵問題總結Oracle
- oracle資料字典的一點總結!Oracle
- Oracle資料庫效能優化總結Oracle資料庫優化
- oracle 資料庫安裝思路總結Oracle資料庫
- Oracle資料塊格式Oracle
- oracle資料塊概述Oracle
- oracle資料塊理解Oracle
- Oracle資料塊blockOracleBloC
- Oracle 行列轉換總結Oracle
- oracle 轉義字元 總結Oracle字元
- Oracle 9.2.0.4 DataGuard 總結(轉)Oracle
- Oracle行列轉換總結Oracle
- JavaScript資料型別轉換總結JavaScript資料型別
- Oracle的邏輯結構(表空間、段、區間、塊)——Oracle資料塊(二)Oracle
- SQL Server Page資料庫結構深入分析SQLServer資料庫
- 原創 oracle 資料完整性總結Oracle
- oracle10g 常用資料字典總結Oracle
- Oracle行資料擴充套件方法總結Oracle套件
- ORACLE資料庫開發經驗總結Oracle資料庫
- 關於Oracle塊的一些總結Oracle
- 資料結構學習(C++)——圖(總結) (轉)資料結構C++
- 資料結構學習(C++)——樹(總結) (轉)資料結構C++
- 資料庫基礎知識總結(轉)資料庫