Oracle關於快取記憶體區應用原理
為什麼oracle能夠對於大量資料進行訪問時候能彰顯出更加出色表現,就是通過所謂的快取記憶體來實現資料的高速運算與操作。在之前的博文中我已經說過sql的執行原理,當我們訪問資料庫的資料時候,首先不是從資料檔案中去查詢這個資料,而是從資料快取記憶體中去查詢,而沒有這個必要再去查詢磁碟中的資料檔案了。只有在資料快取中沒有這個資料的時候,資料庫才會從資料檔案中去查詢(這樣做的目的就是提高讀取的速度,因為讀取記憶體的速度遠比讀取磁碟的速度快好多倍)。有了這種機制就能提高資料庫的整體效率。
這種機制固然提高了資料庫的訪問效率,但是我們不禁會問資料庫是如何實現資料檔案和快取記憶體的一致性的那?在弄清這個問題之前我們先來看一下
在oracle中,oracle的體系結構是有記憶體結構和程序結構共同組成:
由此可見我們所要研究的資料快取記憶體是SGA一部分,那麼我們就來說一下SGA的資料結構:
第一部分:資料快取區
資料快取區就是我們將資料庫檔案的資料存放的快取,它用來儲存從資料檔案中讀取最近的資料塊資訊,其中的資料被所有使用者享用,資料快取區有許多大小相同的快取塊組成,這些快取塊大致可以分為3類:
一、 空閒快取塊
當我們重新啟動資料庫後,系統就會為資料庫分配一些空閒的快取塊。空閒快取塊中是沒有任何資料的,他們在等待後臺程序或伺服器程序向其中寫入資料。當Oracle
一般來說,資料庫在啟動的時候,就會在記憶體中預先分配這些快取塊。所以,Oracle資料庫在啟動的時候,會佔用比較多的記憶體(這個記憶體空間是可以設定的)。但是,這可以免去在實際需要時向記憶體申請的時間。所以,有時候Oracle資料庫雖然已啟動,記憶體的佔用率就很高,但是,其後續仍然可以正常執行的原因。而其他資料庫雖然剛啟動的時候記憶體佔用率不是很高,但是,但系統記憶體到達80%以上時,在進行資料處理就會受到明顯的影響。
所以,當我們利用SELECT語句從資料庫檔案中讀取檔案的時候,資料庫首先會尋找是否有空閒的快取。
二、命中快取塊
命中快取塊儲存那些正在使用的資料。當select語句先從資料庫檔案中讀取資料後,會把取得的資料放入到這個命中快取塊中。直到快取記憶體消耗完畢等原因,這個空間才會被釋放。如此下次如果再次訪問相同的資料的時候就可以從這裡進行查詢,節省時間(因為只是被select,因此這裡的資料是不會換出記憶體)。
三、髒快取塊
髒快取塊儲存已經被修改但是還沒有被寫入資料庫檔案的資料。當訪問完資料之後,由空閒快取塊標誌轉化為命中快取塊標誌。當我們執行update這類帶侵略性的操作的時候,我們要先去命中快取區去尋找資料,如果存在就可以直接操作,並且此時命中快取區標誌被轉為髒快取塊標誌。這樣就能夠實現資料的一致性。當滿足一定的條件時,這些髒快取塊中的資料內容會被寫入到資料庫檔案中去,以便永久性的保留資料庫修改記錄。當寫入資料庫之後髒快取塊標誌就會轉化為空閒快取塊。
那Oracle資料庫關於實現三大快取塊標誌轉化的原理:
實現以上機制主要靠兩個列表:1.最近最少使用列表(LRU列表); 2.寫入列表(DIRTY表).其中LRU列表儲存著所有空閒快取塊、命中快取塊和全部還沒有被移入到DIRTY列表中的髒快取塊。
當Oracle資料庫使用者在查詢資料的時候,可能會遇到如下情況:
1、查詢資料時,資料庫首先在LRU列表中查詢是否有空閒快取塊。其查詢的資料是從尾部開始查詢。當查詢有空閒的快取塊時,資料庫就會把查到的資料寫入到這個空閒快取中。
2、若資料庫在查詢的時候,首先查到的是髒快取的話,則會把這個髒快取移動到DIRTY列表中,然後再繼續查詢,直到查詢到合適的空閒快取塊為止(查詢的時候資料發生變動)。
3、若資料庫在LRU列表中,從尾到頭查了一遍(忽略oracle的查詢演算法),沒有找到空閒快取塊,或者雖然有空閒快取塊,但是其容量不符合要求時,資料庫就會暫時結束這一次查詢。然後,系統就會觸發資料庫寫程序,把DIRTY列表中的髒快取塊寫入到資料庫中去。已經被寫入到資料庫檔案中去的髒快取塊將又被資料庫標記為空閒快取塊,並插入到LRU列表中。當資料庫執行完畢這個動作之後,資料庫又會對LRU列表進行搜尋,找到合適的資料高速空閒快取之後,就會把讀取的資料寫入到這個空閒快取中。
第二部分:重做日誌快取記憶體
用於記錄資料庫發生改變的資訊,這些變化可能是DML或者DDL,關於DML和DDL我已經描述過。
第三部分:共享池
主要包括庫快取、資料字典快取以及用於儲存並行操作資訊和控制結構的快取
庫快取:解析使用者程序提交的SQL語句或者pl/sql程式和儲存最近解析過的程式;
資料字典緩衝區:儲存資料庫物件的資訊,包括使用者賬號資訊、資料檔名、段名、表說明、許可權等。
第四部分:JAVA池
主要為JAVA命令提供語法解析(用不到JAVA命令無需配置)。
第五部分:大池
資料庫管理員配置的可選記憶體區域,用於分配大量的記憶體,處理比共享池更大的記憶體。需要處理的操作有:資料庫備份與恢復;執行並行化的資料庫操作;具有大量排序的sql等。