oracle體系結構三部曲之記憶體結構

2021-08-27 02:09:40 字數 3460 閱讀 8546

還是想嘮叨一下,要想把oracle體系結構學深學透,必須結合備份與恢復的實驗及原理去學,這個我在後續也會寫相應的blog。在這裡我在介紹記憶體結構時,只是做些基礎性的了解。

我們先看兩個容易混淆的概念。sid和oracle_sid,其實吧,這兩個沒啥本質的區別。若真個想分一分的話。那麼,sid是站點識別符號,也即會話識別符號,他和$oracle_home一起唯一標識了乙個sga;而oracle_sid則可以認為是例項名,通過v$instance的字段instance_name查出。

當dba安裝oracle軟體時,針對os首先會辨別是32位還是64位,而這32位和64位又是代表什麼意思呢?簡單來說,就是cpu對於記憶體最大的支援範圍。32位的cpu最大支援4g記憶體。如果oracle執行在32位linux上時,其預設sga無法超過1.7g.

例項是由引數檔案建立出來的,存在於作業系統的記憶體中。linux上有兩條命令可以檢查例項是否開啟:

ps -ef|grep ora_ --檢查後台程序是否開啟;

ipcs -m|grep ora --檢查sga是否分配

在我的磁碟上,有3個資料庫.任何時刻我都只有乙個例項,但有多個資料庫,在任何時間點上只能訪問其中的乙個資料庫。當一台伺服器上有多個例項執行時,每個例項都有乙個自己專用的sga。

每個oracle例項都有乙個被oracle程序所共享的記憶體結構,稱之為sga。當例項開啟後,各個記憶體區會依照最少的需求分配所需的大小。在ora10g使用自動sga記憶體管理(asmm:automatic shared memory management)時,只需把sga_target引數設定為所需的大小便可,其後會根據工作負載自動擴充套件每個記憶體塊的大小。在sga中,空間的最小分配單位是顆粒。它由sga_max_size決定,當sga的總和小於128m時,顆粒為4m,當sga大於128m時,顆粒為16m。

下面我們來看看主要的sga元件。

database_buffer_cache

緩衝區快取中的塊實質上在乙個位置上管理,但有兩個不同的列表指向這些塊:

髒塊列表:其中的塊需要dbwn寫入磁碟

非髒塊列表:8.0以前的版本是lru演算法,之後採用接觸計數演算法,如果命中快取中的乙個塊,則會增加與之相關聯的計數器。塊緩衝區不再像以前那樣移到塊列表的最前面,而是原地留在塊列表中,只是遞增它的接觸計數。不過,一段時間,塊會在列表中「移動」。例如,髒塊由髒列表指向,過一段時間要重用塊時,如果緩衝區已滿,就要將接觸計數較小的某個塊釋放,換由非髒塊列表來指向。

緩衝區快取允許有不同的塊大小。可以通過設定db_nk_cache_size引數,並重啟資料庫。但前提要注意sga的大小。如果採用擴大的方法,比如,你的sga大小是128m,你想再為緩衝區增加另外的64m,就必須把sga_max_size設定為192m或者更大。另外,你也可以採用收縮的辦法,即縮小db_cache_size,因為9i之後,database_buffer_cache的大小可以直接修改引數db_cache_size,那麼:

show parameter db_cache_size; --看一下目前有多大

alter system set db_cache_size=xxm; --將其縮小

alter system set db_16k_cache_size=xxm; --設定16k的資料塊大小的緩衝區快取

這樣我在database_buffer_cache中就有兩種資料塊大小了。這兩個快取是互斥的。只是為了可傳輸表空間。比如,oltp和olap就可以共存於乙個資料庫中。

cache hit(快取命中):使用者請求查詢時,oracle在緩衝區快取找到使用者所需的資料時,就直接從緩衝區返回給使用者。如果在緩衝區找不到,則稱之為cache miss(快取失誤)。

database_buffer_cache命中率公式是

cache hit ratio=1-(physical reads/(db block gets+consistent gets))

db block gets:是指dml語句所得到的資料塊個數

consistent gets:是指select語句所得到的資料塊個數

logical reads:將db_block gets與consistent gets相加得到的資料塊個數。

physical reads:從硬碟上讀出的資料

hit ratio最好大於90%

database_buffer_cache中包含三種不同性質的快取:

dirty buffer:已修改,但尚未寫入資料庫的資料

free buffer:這裡的內容和資料檔案的內容一模一樣,也就是這些buffer已經寫入資料庫內了,隨時可以拿來覆蓋使用。

pinned buffer:正在被使用的buffer

可以把database_buffer_cache卻分為三種不同性質的分割槽:

**池:放在**池的資料,只在事務還存在時才會被用到,一旦事務結束,就會被釋放掉。

保留池:頻繁重複用到的資料

預設池:沒有指定時,資料就會被放在預設池。

shared pool

設計共享池是為了重用查詢計畫.破壞共享池,最容易的辦法是不使用繫結變數。oracle提供乙個引數cursor_sharing可對sql語句做強制繫結變數,其中有個引數值叫similar。在10g中,shared_pool_size引數控制了共享池的大小。裡面的主要主件是庫快取和字典快取。對於這兩個的關係,參見的我的部落格:

在共享池內分析sql語句可分為hard parse和soft parse,。當sql語句一進入oracle資料庫時,oracle首先會檢查一下共享池有沒有完全相同的sql語句,如果沒有,就會進行parse作業;如果有,就會跳過parse,只檢查使用者許可權等。

可以使用dbms_shared_pool.keep(兩個引數),把sql強制留在shared pool裡面。

1)先找出sql語句的相對位置:

select address,hash_value from v$sqlarea where sql_text='......';

2)將位置保留在共享池內:

exec dbms_shared_pool.keep('address','型別『);

redo log buffer

重做日誌緩衝區的預設大小由log_buffer引數控制,這個區的最小大小取決於os。將log_buffer設定為1,再重啟資料庫就可以知道最小值。重做日誌緩衝區的空間劃分為多個塊,這些塊基本上都是512k。

和這個區相關的概念,最重要的是檢查點機制。即:dbwn會去檢查某些redo entry是否已經寫入redo log file。檢查點機制是避免在資料庫恢復時,讀取的redo資訊太多,導致恢復的時間過長。大體的檢查點機制有以下幾個步驟:

1)取當前的scn號為檢查點scn。

2)檢查相關的redo entry是否寫入online redo log file

3)如果寫入,則dbwn會把redo保護的dirty buffer flush到磁碟

4)如果沒有,則dbwn會去通知lgwr來寫,然後,自己再寫

5)ckpt更新控制檔案和資料檔案的檔案頭

而觸發檢查點的事件有很多,比如:日誌卻,;fast_start_mttr_target等

oracle體系結構三部曲之記憶體結構

還是想嘮叨一下,要想把oracle體系結構學深學透,必須結合備份與恢復的實驗及原理去學,這個我在後續也會寫相應的blog。在這裡我在介紹記憶體結構時,只是做些基礎性的了解。我們先看兩個容易混淆的概念。sid和oracle sid,其實吧,這兩個沒啥本質的區別。若真個想分一分的話。那麼,sid是站點識...

oracle體系結構三部曲之記憶體結構

還是想嘮叨一下,要想把oracle體系結構學深學透,必須結合備份與恢復的實驗及原理去學,這個我在後續也會寫相應的blog。在這裡我在介紹記憶體結構時,只是做些基礎性的了解。我們先看兩個容易混淆的概念。sid和oracle sid,其實吧,這兩個沒啥本質的區別。若真個想分一分的話。那麼,sid是站點識...

人生三部曲

人生三部曲 童年沙丁魚罐頭似的公共汽車在曬的發燙的柏油路上緩慢地爬著。我 瘦瘦小小的個子在擁擠的人群中喘不過氣來。還要多久呀?人們煩躁而沉悶的氣氛充斥著整個車廂。忽然,我看見一位打扮入時的西裝人士,正悄悄地把手伸入一位老人的口袋。我第一反應就是有小偷!於是大聲脫口而出,一車人都回頭驚悸地看著我,西裝...