關於Oracle塊的一些總結
以下關於Oracle的一些描述都是個人總結而成,由於個人知識的限制,在本地管理表空間部分及dump資料塊的部分的描述在某些方面會不準確,與實際情況不符合。
Oracle的表空間由若干的資料檔案(OS級)所組成。一個表空間最多可以有1024個資料檔案組成。
資料檔案的大小受塊大小的限制可以有不同的大小。假設一個塊大小為8k。
8i後的rowid組成結構如下:OOOOOO FFF BBBBBB RRR
共有10個位元組組成(1位元組×10=8bit×10=80bit)
OOOOOO是data_object_id(32bit)
FFF是rfile#(10bit)
BBBBBB是block_id(22bit)
RRR是row_id(16bit)
因此可以看到對應的rowid可以表示的最大檔案數為2^10=1024,每個檔案可表示的最大的block數為2^22=4194304 假設每個block size=8k,則有8*1024*2^22/1024/1024/1024 = 32G,即如果block的大小為8k,則一個資料檔案的最大大小為32G。由於一個表空間最多有1024個資料檔案,則一個塊大小為8k的表空間最大可以為32T。
計算公式:
select "block_size(K)", "block_size(K)" * block_num / 1024 / 1024 "file_size(G)"
from (select power(2, rownum) "block_size(K)", power(2, 22) block_num
from dual
connect by rownum <= 4)
以上說明的都只是smallfile tablespace, Oracle 10g開始還支援一種bigfile tablespace。這種表空間只能有一個資料檔案,該資料檔案最大可以達到4G個block大小。
理論上的 BFT 可以達到下面所列的值:
資料塊大小(單位:K) BFT 最大值(單位:T)
2k 8T
4k 16T
8k 32T
16k 64T
32k 128T
預設情況下建立的表空間都是smallfile表空間。要建立大檔案表空間,則可以透過指定bigfile引數來指定。
檢視當前表空間的預設建立型別,可以透過下面查詢來檢視:
select * from database_properties dp where dp.property_name = 'DEFAULT_TBS_TYPE'
下面介紹表空間的邏輯組成
一個表空間在邏輯上是由若干個segment組成的,每個segment都對應一個object。但是並不是每個object都對應一個segment,如果function、procedure等。每個segment由若干extent組成,extent是Oracle分配空間的最小單位,當segment需要擴充套件時,oracle就會為該segment分配新的extent。分配extent的大小由建立表空間時uniform. size引數指定。如果指定,則每次按照指定的大小進行擴充套件。如果不指定,則以pctincrease引數指定的比例逐級遞增。每個extent都由若干個塊組成,塊的多少取決於分配的extent的大小。假設一個extent為1m,則含有的block數為:1*1024/8=128個。
本地管理表空間(local management tablespace)下,每個segment的前3個塊都用於存放該段的儲存資訊。每個資料檔案的前8個塊都是存放所有段的資訊:
建立表空間:
create tablespace mytbs datafile 'E:\oracle\oradata\lyon\mytbs01.dbf'
size 10m uniform. size 1m extent management local segment space management auto;
在指定的表空間上建立測試表:
create table mytb(x varchar2(10), y varchar2(30)) tablespace mytbs nologging;
建立測試資料:
insert into mytb(x, y)
select 'This', dump('This',16) from dual union all
select 'is', dump('is',16) from dual union all
select 'a', dump('a',16) from dual union all
select 'dump', dump('dump',16) from dual union all
select 'test', dump('test',16) from dual union all
select '!', dump('!',16) from dual;
commit;
檢視該表的extent資訊:
select segment_name, tablespace_name, file_id, block_id, bytes, blocks
from dba_extents de
where de.segment_name = 'MYTB';
> select segment_name, tablespace_name, file_id, block_id, bytes, blocks
2 from dba_extents de
3 where de.segment_name = 'MYTB';
SEGMENT_NAME TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS
------------------------------ ------------------------------ ---------- ---------- ---------- ----------
MYTB MYTBS 21 9 1048576 128
已用時間: 00: 00: 00.32
可以看到block_id=9,且共有128個塊。
檢視當前實際資料所在的塊:
customer21@ORCL> select dbms_rowid.rowid_relative_fno(rowid) rfile#,
2 dbms_rowid.rowid_block_number(rowid) blknumber,
3 dbms_rowid.rowid_row_number(rowid) rownumber
4 from mytb;
RFILE# BLKNUMBER ROWNUMBER
---------- ---------- ----------
21 35 0
21 35 1
21 35 2
21 35 3
21 35 4
21 35 5
已選擇6行。
已用時間: 00: 00: 00.03
可以看到實際資料開始使用的塊為35。
有兩個問題:
1、新的表空間下建立的物件,實際object開始的塊的id為9,前面的8個塊呢?
2、該物件(表mytb),在表空間中開始分配的block_id=9,但是為何初始資料所在的塊為35?
第一個問題比較容易回答,這8個塊是本地管理表空間(LMT)情況下,用於存放物件資訊的。
第二個問題實際相差了35-9=26個塊。除去兩端的塊,還有24個塊去哪裡了?
ORACLE中空閒資料塊可以透過FREELIST或BITMAP來維護,它們位於一個段的頭部用來標識當前段中哪些資料塊可以進行INSERT。在本地管理表空間中ORACLE自動管理分配給段的區的大小,只在本地管理的表空間中才能選用段自動管理,採用自動段空間管理的本地管理表空間中的段中的空閒資料塊的資訊就存放在段中某些區的頭部,使用點陣圖來管理(最普通的情況是一個段的第一個區的第一個塊為FIRST LEVEL BITMAP BLOCK,第二個塊為SECOND LEVEL BITMAP BLOCK,第三個塊為PAGETABLE SEGMENT HEADER
也就是說,每個段的第一個區的前面三個塊都是存放空閒資料庫資訊的。那還剩下24-3=21個塊。
alter system dump datafile 21 block min 12 block max 34
alter system dump datafile 21 block 35
dump 35號塊,取出一段如下:
col 0: [ 4] 54 68 69 73
這個與
select * from mytb
Typ=96 Len=4: 54,68,69,73的結果是一樣的。
說明了這個值的長度為4,每個位元組對應的acsii碼是54,68,69,73(16進位制),轉換為字元即為:This。
drop index idx_mytb_x
create index idx_mytb_x on mytb(x) tablespace mytbs nologging;
select * from dba_extents de where de.segment_name = 'IDX_MYTB_X'
alter system dump datafile 21 block 141
索引dump資訊
row#0[8025] flag: ------, lock: 0, len=11
col 0; len 1; (1): 21
col 1; len 6; (6): 05 40 00 23 00 05
row#1[8011] flag: ------, lock: 0, len=14
col 0; len 4; (4): 54 68 69 73
col 1; len 6; (6): 05 40 00 23 00 00
row#2[8000] flag: ------, lock: 0, len=11
col 0; len 1; (1): 61
col 1; len 6; (6): 05 40 00 23 00 02
row#3[7986] flag: ------, lock: 0, len=14
col 0; len 4; (4): 64 75 6d 70
col 1; len 6; (6): 05 40 00 23 00 03
row#4[7974] flag: ------, lock: 0, len=12
col 0; len 2; (2): 69 73
col 1; len 6; (6): 05 40 00 23 00 01
row#5[7960] flag: ------, lock: 0, len=14
col 0; len 4; (4): 74 65 73 74
col 1; len 6; (6): 05 40 00 23 00 04
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12932950/viewspace-614688/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORACLE關於NULL的總結OracleNull
- 關於ORACLE鎖的總結Oracle
- 關於Mysql使用的一些總結MySql
- MySql關於鎖的一些總結MySql
- 關於繼承的一些小總結繼承
- 關於EM配置的一些總結
- 關於BUFFER POOL的一些總結
- 關於oracle裡的process總結Oracle
- 關於ORACLE的一點總結Oracle
- 關於oracle synonym 的總結整理Oracle
- 關於Code Review的一些思考總結View
- 關於 資料壞塊 的整理和總結
- 總結關於CPU的一些基本知識
- 關於sqlplus用法的一些總結SQL
- 關於查詢轉換的一些總結
- 對於Oracle鎖的一些理論總結Oracle
- 關於oracle中session跟蹤的總結OracleSession
- 關於 變址影像(indexed image) 的一些總結Index
- 關於字元函式的一些應用總結字元函式
- 關於使用者體驗的一些總結
- 關於查詢最佳化的一些總結
- 關於DDD和COLA的一些總結和思考
- 關於區塊鏈的一些澄清區塊鏈
- 關於學習 Linux 系統結構的一些總結Linux
- 關於程式和執行緒 自我的一些總結執行緒
- 關於分割槽表Local索引Rebuild的一些總結索引Rebuild
- 關於Oracle Timezone的一點總結Oracle
- 關於ORACLE的鎖表與解鎖總結Oracle
- ORACLE壞塊總結(轉)Oracle
- ORACLE壞塊總結2Oracle
- 關於oracle的一些命令Oracle
- 關於近期的總結
- 關於UIWebView的總結UIWebView
- 關於BeautifulSoup的總結
- 關於HTML的總結HTML
- 關於學習-Linux-系統結構的一些總結Linux
- 微信小程式關於分享一些簡單總結微信小程式
- 關於前端工程化(基建)的一些總結和思考前端