Oracle 段 區 塊
2024-08-29 13:53:52
供稿:網友
閱讀Oracle文檔的b10743,《conceps》。這本被oracle公司的大師級的人物Michele Cyran等牛人所寫,真是一本不錯的書籍??蓢@英文不太好,但努力,總會有收獲的。還是從他的數據架構來說吧!
(一)Data blocks ,Extents,Segment
這就是他們之間的邏輯結構。
先看Data blocks(也叫邏輯塊,oracle塊,頁)吧,oracle存儲數據都是在這些數據塊中,一個數據塊是磁盤上數據庫物理空間一系列物理字節的組成。
比Data blocks更高一層的邏輯數據塊空間是extent,一個extent是由一系列臨近的存儲信息的數據塊組成。
最高一層的邏輯結構是segment,一個segment是同一表空間extents的一個集合。每一個segment有不同的數據結構。如每一個表的數據就存儲在自己的data segment,每一個索引存儲在自己的索引段,如果表或者索引是
是分區存儲的,那么每一個分區都存儲在他們各自的segment中。一個segment和他所有的extent都是在一個表空間中,并且一個segment可以跨越幾個數據文件。。
對于數據庫來說,data block是oracle數據庫中分配和私用的最小存儲單元。但這僅僅對數據庫來說,在物理層次,操作系統層次,所有的數據仍舊是按字節存儲的。每一個操作系統都有自己的塊尺寸(block size),在oracle數據庫中,數據塊的大小都有參數db_block_size在創建數據庫的時候來確定,他的數值應該是操作系統塊尺寸的整數倍。
數據塊都有這么幾部分組成,塊頭部分,表目錄,行目錄,空閑空間,數據這幾部分組成。塊頭主要包含兩部分信息:塊頭地址和segment的類型,是數據表還是索引;表目錄主要包含塊中有多少行數據。行目錄主要包含每一行的物理地址。數據就很明顯了,就是這個塊包含的數據。這里邊最奇妙的就是這個空閑空間,它主要目的就是為varchar這個數據類型準備的,有兩個閾值參數pctfree,pctused來控制此數據快移向那一個鏈表,這兩個參數的設定主要目的是為了避免行連接與行遷移,具體的又夠一篇文章了,以后再寫,^_^。
在來說extent這個由一系列連續的data blocks組成。每當在數據庫中創建一個表,那么分配給表的data segment分配一個包含若干數據庫的初始的extent,雖然還沒有插進去數據,但初始的extent已經做好了插入數據的準備。如果初始的extent中的數據塊已經滿了,或者沒有空間插入數據,那么他將會增量擴展。當然這只是對于串行執行的情況,對于并發就不合適了。一些存儲參數控制著oracle如何為每個段分配可用空間。當你使用create table創建一個表的時候,存儲參數會將決定分配多少的可用空間或者限制此表最多可包含多少個extents,如果在創建表的時候沒有定義這些參數,那么將采用表空間定義的默認的存儲參數。對于插入和刪除都很頻繁的表,DBA可以通過這個語句來收回無用的extent ,aler table table_name deallocate unused;
下面來說segment,每一個segment都是一個表空間下有一系列extent組成的邏輯存儲結構。如:當數據庫用戶創建一個表,那么oracle將分配一個或多個extent來組成表的數據段,創建一個索引,oracle也會紛紛extent給索引數據。一般可以分為data segment,index segment,temporary segment。
當你創建一個非分區并且非聚焦表的時候,或者一個分區表的一個分區,多個表合用的一個聚簇,都將是一個oracle將處理數據的單個data segment。
而一個index segment ,對于非分區索引,就是create index創建的索引就會分配一個segment來處理數據;分區索引則對每一個分區分配一個segment來處理數據。
當一個進程查詢的時候,oracle常常需要一個臨時的工作區存放sql的解析和執行的中間狀態,oracle自動分配的磁盤空間temporary segment。特別當內存的排序區不足時,oracle將會分配一個temporary segment。有時候,下面一些語句有時候需要用到temporary segment:
create index ....
select .... order by ;
select distinct ....
select ...... group by
select ...... union
select ...... intersect
select ...... minus
還有就是對一個子查詢來說也會用到temporary segment。如果一個查詢包含distinct 子句,一個order by ,一個group by,那么就需要兩個temporary segment。當創建一個臨時表或索引,oracle也會分配一些temporary segment。
對于temporary segment,oracle只是在一個用戶的會話(session)中分配,但sql語句執行結束或者會話斷開,將釋放所有的temporary segment。分配這些temporary segment的磁盤空間都是在臨時表空間,如果沒有定義臨時表空間,那么默認的臨時表空間將是system表空間。對于DBA來說,由于分配和釋放這些temporary segment將非常頻繁,所以至少要定義一個temporary segment,這樣可以避免system表空間的碎片。對于臨時表來說,如果多個會話公用一個臨時表,那么知道所有的會話全部結束,那才會釋放這個臨時表分配的temporary segment。