教你如何成為Oracle 10g OCP - 第六章 儲存管理

tolywang發表於2010-09-07

 

儲存概念 - 物理概念及邏輯概念 

物理概念:  資料檔案,控制檔案,聯機日誌檔案 等
邏輯概念:  表空間(tablespace), 段(segment), 區間(extent), 資料塊(block)

Tablespace : 可以細分為更小的邏輯概念segment, segment可以跨多個資料檔案。
Segment :    可以細分為更小的邏輯概念extent, 典型的segment是table, index 等。
Extent  :    一個extent 不能跨多個資料檔案,它是一個邏輯上連續的空間,Segment一次擴充套件
             或收縮的最小單位就是extent .  extent最終被細分為最小的邏輯單位block, extent
             由多個連續的block組成。

 

6.1  表空間

分為系統表空間及非系統表空間

system tablespace :   在建庫的時候就建立的表空間,包含資料字典資訊。
non-system tablesapce :   使用者資料 + 臨時資料 + undo 資料

一般我們根據業務邏輯來為DB劃分表空間,然後根據表的大小再次劃分,比如
sales_large_tbs, sales_middle_tbs, sales_small_tbs 。 

 

6.1.1 表空間的空間管理

表空間的空間管理是指對錶空間中的segment的擴充套件和收縮排行管理,segment的擴張和
收縮的最小單位是extent, 所以表空間的空間管理也就是如何管理extent的分配和釋放。

管理方式:  資料字典管理(DMT) 和 本地管理(LMT) .

資料字典管理(DMT):   用資料字典表FET$(Free Extent)和UET$(Used Extent)來管理extent的
擴張和收縮。 FET$記錄tablespace中的可用空間,UET$記錄表空間中已經分配的空間。

FET$字典表: 記錄TS#, FILE#, BLK#, LENGTH
UET$字典表: 每個EXTENT佔一條記錄,記錄EXTENT所在的TS,datafile,extent第一個blk#號,
以及extent長度。

DMT資料字典管理的方式就是透過這兩個table之間轉移資料行來實現的。


建立一個Tablespace TBS1, 那麼在FET$會增加一條記錄:
TS#    File#    Blk#   Length
20      28       1       50  
然後在其中建一個表,假設這個表定義的extent=8 block, 那麼需要更新FET$
(表示後面的block分配由blk# 9 開始,8個塊分配了,只有42個block free):
TS#    File#    Blk#   Length
20      28       9       42  

由於佔用了extent,這時還需要更新UET$表,我們使用8個block生成了一個extent, 則
blk# 號碼由1開始,長度為8 block :
EXT#   TS#    File#   Blk#   Length 
100    20      28      1       8    

 

刪除資料後FET$及UET$的變化:

假設當前FET$ 為:
TS#    File#     Blk#     Length
20      28        48        2     
當前的UET$為:
EXT#    TS#    File#     Blk#     Length
100     20       28        1        8  
101     20       28        9        12  

使用者刪除一個表T1, 導致T1第一個extent即100號extent被釋放了,那麼:
FET$更新為:
TS#    File#     Blk#     Length
20      28        48        2   
20      28        1         8    
UET#更新為:
EXT#    TS#    File#     Blk#     Length
101     20       28        9        12   
假設使用者又刪除一個表T2, 導致T1第一個extent即101號extent被釋放了,那麼:
UET$表的101號extent記錄被刪除。
FET$更新為:
TS#    File#     Blk#     Length
20      28        48        2   
20      28        1         8  
20      28        9         12    
SMON負責定期合併這種相鄰可用空間,所以FET$更新為:
TS#    File#     Blk#     Length
20      28        48        2   
20      28        1        20   

 

字典管理的問題
A. 當使用者程式對錶DML操作需要空間時,Oracle會產生很多遞迴的SQL,來完成FET$及UET$的更新。
B. 對FET$及UET$的DML產生很多事務,會引起鎖定,多個程式都要求擴充套件extent, 如果都需要
更新FET$中的相同記錄,那麼會引起鎖定等待 。
C. 對FET$及UET$的更新操作會引起undo及redo 。
D. SMON要定期合併相鄰的FET$中記錄的可用空間,會消耗一定資源 。

 

要解決以上問題,Oracle引入了LMT:  LMT不再使用FET$和UET$
LMT :  本地管理表空間,不使用FET$及UET$, 而是在表空間的資料檔案頭部選出6個block(從第
3個block到第8個block), 在其中存放bitmap來管理extent的分配及釋放。

資料檔案頭部的bitmap由多個bit組成,比如 11001010001100111001000001,每個bit位對應一個extent,
或者多個bit位對應一個extent(因為有時一個extent過大)。 當程式需要extent時,只需要掃描檔案
頭部的bitmap, 找到0位,分配bit位對應的可用空間,更新bit值為1,刪除extent則相反。

LMT的優點: 克服了DMT的缺點,沒有遞迴SQL,只需要更新檔案頭部,無事務,速度快,沒有鎖及undo,
redo, 且不存在合併空間的問題。 Oracle9i開始需要建立LMT,而不是DMT . 

10g資料檔案頭中會有64K的空間用來存放bitmap,其他空間都可用,所以我們在建立資料檔案大小
的時候,需要在uniform. size 整數倍的前提下再加入這64K的大小,以免浪費空間 。  

 

---------------------------------------------------------------------------------------


備註:

The locally-managed (bitmapped) tablespace (LMT) file has the following structure:

1、File header: 1 block
2、Bitmapped file space header: 1 block
3、Head portion of bitmap blocks: N blocks
4、Useful file blocks: U units (A unit is a number of blocks.)
5、Tail portion of bitmap blocks: M blocks

If a Unit = B blocks, then the total file size = 1 + 1 + N + U*B +M.
The operating system file allocated will in some cases be file size + 1 block for
the OS header.


---------------------------------------------------------------------------------------

 

6.1.2 建立和管理表空間

- DMT, LMT
- Permanent , Temporary(能被覆蓋,關閉DB後刪除)

臨時表空間: 使用者在對Data進行排序的時候,會先在PGA裡完成,如果排序Data太多,PGA記憶體
不足,則Oracle會將要排序的data分割成多份,只取一份放在PGA中排序,其他部分都交換到臨時
表空間中。當PGA中的部分排序完畢後,將排好序的部分資料交換到臨時表空間中,同時再從臨時
表空間中取一份沒有排序的資料放到PGA裡面進行排序,依此類推,直到將所有資料都排序完畢
為止 。

如果沒有為資料庫指定一個臨時表空間,同時在建立使用者時也沒有明確指定其預設的臨時表空間,
則會使用系統表空間作為該使用者的臨時表空間。DBCA會自動為資料庫建立一個temp臨時表空間。


- 表空間的各種狀態
可以透過 select tablespace_name,status from dba_tablespaces; 檢視錶空間的各種狀態。
可以透過 alter tablespace tbs_name offline/online/read only/read write; 修改狀態。

例子:

CREATE TABLESPACE SYSAUX DATAFILE
  '/ocfs_data/mxdell/sysaux01.dbf' SIZE 2028M AUTOEXTEND ON NEXT 1024M MAXSIZE 4096M,
  '/ocfs_data/mxdell/sysaux02.dbf' SIZE 2025M AUTOEXTEND OFF
LOGGING
ONLINE
PERMANENT
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 16K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;


CREATE TABLESPACE LOG_DATA DATAFILE
  '/ocfs_data/mxdell/log_data01.dbf' SIZE 4001M AUTOEXTEND ON NEXT 2048M MAXSIZE 10240M,
  '/ocfs_data/mxdell/log_data02.dbf' SIZE 4001M AUTOEXTEND OFF
LOGGING
ONLINE
PERMANENT
EXTENT MANAGEMENT LOCAL UNIFORM. SIZE 20M
BLOCKSIZE 16K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;

 

Read Write - 可以進行讀寫操作的表空間 。
Read Only - 只讀表空間中的資料不能被修改,但是表可以被drop,因為刪除一個表只是更新
系統tablespace中的資料字典,在資料字典中將該表的定義資訊刪除而已,並不實際地刪除
該表包含的資料。
Offline -  離線狀態,不能讀寫,系統表空間,預設temp空間及undo都不能置為offline .

Bigfile tablespace:  Oracle10g時被引入,大檔案表空間,只能包含一個資料檔案,設定它的
最大好處就是減少了資料檔案數量,簡化了datafile的管理,根據block大小的不同,它的大小
可以達到8TB .

Smallfile tablespace:  建立表空間的時候預設就是smallfile,可以建立多個檔案。

Storage(tablespace) :  extent有自動擴充套件(AUTOALLOCATE),有uniform. size(同樣大小)。
自動擴充套件的規律如下:
Oracle9i 下:
0-15    extents 每個大小是64K 合計大小 1M
16-79  extents 每個大小是1M 合計大小 63M --以上兩項大小合計 64M
80-199 extents 每個大小是8M 合計大小 960M --以上三項大小合計 1024M=1G
200-?  extents 每個大小是64M

Oracle10g下有變化 : 
extent0 ~127= 8M   總大小  128×8M=1G
extent 128=64M   當segment的大小大於1G時,oracle開始分配64M的extents。


如何規劃表空間:  一般是根據業務邏輯劃分,然後再根據資料量大小來分。

 


Segment Space Manangement - 該選項從Oracle9i 開始引入,管理如何選擇可用block.

a. Manual : Oracle9i之前,只能以手工設定引數方式來確定哪個block可以用來插入資料。
freelist(可用連結串列)指定了所有可用於insert操作的資料塊的列表,管理HWM(高水位)線以下
的空閒空間。主要Storage引數有pctused, pctfree 等。

segment上的可用空間分為兩種,一種是已經分配給segment的,在HWM上未被使用的空閒空間;
第二種是在HWM下連線在freelist上的空閒空間。

Freelist儲存在每個segment的header block中,freelist中掛的都是可用來插入資料的block,
freelist的起點記錄在segment header的第一個block中,當操作插入資料需要可用block時,
先鎖定segment的header(多少資料塊?), 然後在freelist中查詢有足夠空間的可用block,找到
後將data插入,最後釋放segment header的鎖定。

 

pctused/pctfree - 用於控制資料塊可用與否。預設情況下pctfree=10, pctused=40, 當freelist
中某可用block不斷插入資料,如果block剩餘空間只有10%的時候,該block被從freelist中摘除,
不能再用於insert 資料,剩餘的10%空間用於update操作中的欄位長度擴充套件。  當刪除某個非
freelist中的資料block中的data,使該block中已經使用的空間小於pctused的值(比如40%),那麼
該block會被再次掛到freelist中(使用者資料插入)。

當某個segment併發插入比較嚴重時,由於搜尋freelist只能由一個程式鎖定segment header,
其他程式必須等待,從而出現爭用現象。

 

Automatic - ASSM (Auto Segment Space Manangement), 自動段空間管理
ASSM在9i中被引入,Oracle引入bitmap blocks來管理block, 他們與data block一起分佈在
整個segment中,結構類似樹狀index 。

注意: ASSM必須在本地管理表空間(LMT)中才能使用。


ASSM結構 - bitmap block組織,一共三個層級,第一級類似index裡的葉子節點,其中含有
block地址和每個塊的使用狀態;第二級類似index的分支節點,其中包含第一級bitmap塊
的地址;第三級則類似根節點,包含第二級BMB(bitmap block)塊地址。

Oracle ASSM三級點陣圖塊結構詳見:


資料庫塊的使用狀態分為六個等級:unformated(未格式化block), <25%(block可用空間小於
25%),25%~50%, 50%~75%,75%~100%, full(無可用空間)。

當伺服器程式需找可用資料塊來插入資料時,只需根據各個層級bitmap block的關聯關係,找
到第一級(葉子節點)BMB即可。因此,伺服器程式根據插入data大小來判斷用哪個block,假設
當前的插入需要1KB (block大小為8K), 則表示需要12.5%的block大小空間(1/8), 於是在葉子
BMB塊中找一個可用空間百分比大於12.5%的block即可,插入完成後,把被插入的資料塊剩餘
的可用空間狀態資訊更新到BMB塊中對應的條目。

- 引入ASSM後,用BMB而不是freelist ,因此多個程式可同時使用多個BMB並行插入,防止了
freelist中對segment header的爭用等待,Oracle建議用ASSM 。

- 在ASSM表空間裡建立segment時,只能指定pctfree, 而pctused及freelist被忽略,pctused
被6個等級的block代替。

 

四種設定表空間offline的方式:

A. Normal - offline之前,被操作表空間對應的資料檔案必須出於online狀態,Oracle對
該表空間所有檔案做checkpoint, 將對應的dirty data全寫入datafile, 這樣方式的offline,
表空間資料沒有損失,下次online時不需恢復。

B. Immediate - 立即offline, 不為表空間的任何檔案做checkpoint, 通常在tablespace對
應的datafile 全丟失或損壞的情況下采用這種模式,Oracle不會發出檔案級別的ckpt, 所有
dirty data都不寫入,這種方式offline的tbs 資料會被損壞,下次online的時需要恢復。

C. Temporary - 為所有線上檔案做checkpoint, 通常在tablespace 對應的datafile沒有完全
丟失或損壞的情況下采用,Oracle發出ckpt, dirty data能寫入的即寫入,不能寫入就不寫入 。 
下次online的時候需要恢復。


系統及非系統表空間datafile轉移方式:

系統表空間 -
A. shutdown immediate ;
B. startup mount;
C. cp  /u01/system01.dbf   /u02/system01.dbf 
D. alter database rename datafile  '....'  to  '....' ; 
E. alter database open ; 

非系統表空間 -
A. alter tablespace exam offline ; 
B. cp  /u01/exam01.dbf   /u02/exam01.dbf 
C. alter tablespace exam rename datafile '/u01/exam.dbf'  to '/u02/exam.dbf' ;
D. alter tablespace exam online ;


6.1.3  臨時表空間和臨時表空間組
- Create temporary tablespace temp tempfile '/u01/temp01.dbf' ..... ;


6.1.4 非預設資料塊大小的表空間
- db_2k_cache_size , db_16k_cache_size ...

 

 

 


6.2  聯機日誌檔案

將資料庫裡所有資料塊的變化記錄下來,記錄下來的變化叫做重做記錄(redo record).注意這裡
強調的是資料塊的變化,而不是資料的變化,修改資料塊的頭部的標記資訊時,也會產生重做記
錄。

例如: 下面的一行代表log buffer中的一個重做記錄
(update redo_test set name='CDF' where id=1)

行號   事務ID   File#    Block#   row   column   value
 1       T1       2         18     -       -      ABC     --- 回滾段資料塊
 1       T1       4         111    1       2      CDF     --- 表的資料塊

以上重做條目先在log buffer中產生,當出現某種觸發時間(比如達到1m或使用者commit),喚醒
LGWR程式,將重做條目重新整理到聯機日誌檔案中,它的寫入都是向前的順序寫,不像datafile
隨機的寫。由於順序寫入,不需要尋找空閒塊等,所以LGWR寫入redo file的速度會相對快。

聯機日誌檔案存在的主要目的就是為了將資料庫恢復到歷史上的任何一個時間點。


聯機日誌檔案切換的過程 
A. 從controlfile中得到下一個可用的聯機日誌檔案;
B. 在控制檔案中記錄寫入當前redo log最後一個日誌塊的SCN(hing SCN), 關閉當前redo logfile;
C. 增加SCN, 修改controlfile,將下一個redo logfile標記為current, 判斷前一個redo file裡
包含的redo record 對應的dirty data是否已經寫入datafile, 如果沒有則標記為active, 如果有
寫入datafile則標記為inactive , 若資料庫為歸檔模式,那麼lgwr後臺程式將前一個redo file加
入到歸檔列表中,並喚醒ARCn程式進行歸檔 。
D. 開啟新的redo logfile(如果是多組,則開啟多組中的所有成員),記錄當前log sequence和第一個
日誌塊的SCN(Low SCN),開始新一輪的重做記錄。


聯機日誌檔案online redo logfile的幾種狀態:
current/active/inactive/unused/clearing/clearing_current

active 狀態:  該日誌檔案中包含有redo record 對應的dirty block還沒有被寫入datafile中,為
什麼會出現這種狀態呢?   由於redo logfile是active,說明日誌已經切換到其他日誌組上(狀態為
current),日誌切換的時候會觸發增量檢查點(incremental checkpoint), CKPT會觸發DBWR寫dirty
block, 不過注意,增量檢查點只是在控制檔案中記錄當前檢查點佇列中dirty block在第一次修改時
對應的日誌塊在日誌檔案中的地址(檢查點位置),DBWR啟動並不表示立即寫dirty block,除非檢查
點佇列中dirty block的數量達到一定程度或超過一定時間,active狀態和歸檔無直接關係,可能已經
歸檔或還沒有歸檔。

備註: 檢查點佇列上串起來的都是髒塊對應的buffer cache, 啟動dbwr後。程式會根據一些列
引數及規則, 計算出應該寫的dirty block的數量(不是所有的dirty block)。

 

DBWR啟動並不表示立即寫dirty block的原因 -------- 
alter system checkpoint ; 手工觸發完全檢查點。
完全檢查點優先順序高,透過它觸發的DBWR會立即寫dirty block; 而增量檢查點觸發的DBWR啟動的
條件的優先順序低,DBWR不會立即寫dirty block, 而是要等一段時間才實際寫 。 


- 我們可以設定log_checkpoint_to_alert為true,將檢查點啟動和結束的時間記錄到trace檔案中。
- lgwr寫redo record 重做記錄時,以組為單位,並行寫入組裡所有日誌成員 。
- 強制切換日誌 :  alter system switch logfile; 

 

 

6.2.2  管理日誌檔案

clear logfile - 清除指定的日誌檔案,在日誌檔案組有丟失或損壞部分成員時,可以清除該
日誌檔案組,Oracle會自動建立丟失或損壞的成員,被清除的檔案組狀態必須是inactive .
比如:  alter database clear logfile group 3 ;

sizing advicor - 10g引入的顧問,幫組我們確定最佳redo logfile的大小,我們需要先設定
初始化引數; fast_start_mttr_target ,才能使用顧問,也可以查詢v$instance_recovery中
的optimal_logfile_size 列 .

 

6.3 OMF : Oracle管理檔案

OMF與非OMF可以同時存在。相關引數: db_create_online_dest_n , db_recovery_file_des 定義
快速閃回區 ,備份時如果沒有指定檔案所在地,備份檔案會被放在快速閃回區中。

 


6.4  資料塊的結構

資料塊頭部記錄了當前資料塊所屬的segment型別(index或table), block地址,最重要的資訊時ITL
(interested transaction list), 定義table時,inittrans,maxtrans指定ITL槽的初始及最大數。
當一個事務要更新block中的資料時,必須先在block的頭部獲取一個可用的ITL槽 ,然後將當前事務
ID, 事務使用到的undo塊的地址,scn號及當前事務是否提交等資訊註冊到ITL槽,ITL槽可以重複
使用,但是隻有當事務提交或回滾後,該ITL才能被複用; 如果ITL槽都在被使用,且事務需要使用,
則會動態建立一個新的ITL槽。

 

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

相關文章