Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評(píng)論 :: 0 Trackbacks
          ??? 數(shù)據(jù)庫結(jié)構(gòu)(五).內(nèi)存結(jié)構(gòu)
          ?
          ?
          ??? Oracle 的內(nèi)存可以分為:系統(tǒng)全局區(qū)(SGA)、程序全局區(qū)(PGA)、用戶全局區(qū)(UGA),其主要用來儲(chǔ)存:
          ??? 1 、程序代碼
          ??? 2 、活動(dòng)和非活動(dòng)的session信息
          ??? 3 、程序執(zhí)行過程中的信息(例如Cursor)
          ??? 4 、與 Oracle 進(jìn)程共享和通信的信息(例如鎖)
          ??? 5 、被緩存到內(nèi)存的信息
          ?
          ?
          一、系統(tǒng)全局區(qū)(SGA)
          ?
          ??? SGA 是一組為系統(tǒng)分配的共享內(nèi)存結(jié)構(gòu),可以包含多個(gè)數(shù)據(jù)庫實(shí)例的數(shù)據(jù)或控制信息。當(dāng)實(shí)例啟動(dòng)時(shí), SGA 即被自動(dòng)分配,實(shí)例關(guān)閉時(shí)被自動(dòng)回收。
          ??? SGA 按其作用的不同,可以分為:數(shù)據(jù)緩沖區(qū)、日志緩沖區(qū)、共享池、大池、 Java 池、流池等。
          ?
          ??? 查看 SGA 的大小可以使用 :
          ?
          ??? SQL> select * from v$sga;
          ??? NAME????????????????????? VALUE
          ??? -------------------- ----------
          ??? Fixed Size?????????????? 453492
          ??? Variable Size???????? 109051904
          ??? Database Buffers?????? 25165824
          ??? Redo Buffers???????????? 667648
          ?
          1、數(shù)據(jù)緩沖區(qū)(Database Buffer Cache)
          ?
          ??? 用戶第一次執(zhí)行查詢或修改數(shù)據(jù)操作時(shí),服務(wù)器進(jìn)程將數(shù)據(jù)從數(shù)據(jù)文件中讀取出來,并裝入到數(shù)據(jù)緩沖區(qū)中,這樣操作即在內(nèi)存中完成,用戶下一次訪問相同數(shù)據(jù)時(shí), Oracle 可以直接將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)返回給用戶,大大提高相應(yīng)速度。
          ?
          ??? 數(shù)據(jù)緩沖區(qū)由許多相同大小的緩存塊組成,其大小與數(shù)據(jù)塊相同,從其是否被利用角度可分為三類:
          ??? (1) 臟緩存塊:保存了已經(jīng)被修改過的數(shù)據(jù),這些數(shù)據(jù)需等待 DBWR 要重新被寫入數(shù)據(jù)文件中;
          ??? (2) 空閑緩存塊:不包含任何數(shù)據(jù),等待被寫入;
          ??? (3) 命中緩存塊:用戶正在訪問的緩存塊,這些緩存塊將被保留在數(shù)據(jù)緩沖區(qū)中。
          ?
          ??? Oracle 通過最近最少使用列表(LRU)寫入列表(DIRTY)來管理數(shù)據(jù)緩沖區(qū)中的緩存塊。
          ??? (1) LRU :包含所有三類緩存塊,使用 LRU 算法將緩沖區(qū)中最近一段時(shí)間內(nèi)訪問次數(shù)最少的緩存塊移除緩沖區(qū)。
          ??? (2) DIRTY :包含了已經(jīng)被修改并需要寫入數(shù)據(jù)文件的緩存塊
          ?
          ??? 數(shù)據(jù)緩沖區(qū)的工作機(jī)制:
          ??? (1) 用戶提交訪問申請(qǐng), Oracle 在數(shù)據(jù)緩沖區(qū)中查找,若該數(shù)據(jù)塊位于數(shù)據(jù)緩沖區(qū)中,則直接返回給用戶,稱之為 “ 緩存命中 ”
          ??? (2) 若數(shù)據(jù)緩沖區(qū)中查找不到所需數(shù)據(jù)塊,則先從數(shù)據(jù)文件提取到緩存中,再從緩存讀取并返回給用戶,稱之為 “ 緩存失敗 ”
          ??? (3) 當(dāng) “ 緩存失敗 ” 時(shí),先找到空閑緩存塊,若沒有空閑塊,則將 LRU 列表中的臟緩存塊移入 DIRTY 列表
          ??? (4) 當(dāng) DIRTY 列表到達(dá)一定長度時(shí),由 DBWR 將臟數(shù)據(jù)塊的數(shù)據(jù)寫入到磁盤文件,重新刷新數(shù)據(jù)緩沖區(qū)
          ?
          ??? 8i以前的版本,數(shù)據(jù)緩存的大小由DB_BLOCK_BUFFER(數(shù)據(jù)緩存區(qū)緩存塊數(shù)量)和DB_BLOCK_SIZE(數(shù)據(jù)塊大小)兩者的乘積決定,而在9i以后,直接使用DB_CACHE_SIZE指定
          ?
          2、日志緩沖區(qū)(Redo Log Buffer)
          ?
          ??? 日志緩沖區(qū)用于存儲(chǔ)數(shù)據(jù)庫的修改信息。當(dāng)日志緩沖區(qū)的日志信息達(dá)到一定數(shù)量時(shí),由 LGWR 進(jìn)程將日志寫入到日志文件組。
          ??? 日志緩沖區(qū)是一個(gè)直接從頂端向底端寫入數(shù)據(jù)的循環(huán)緩沖區(qū),當(dāng)寫到最底端時(shí),再返回到緩沖區(qū)的起始點(diǎn)循環(huán)寫入。
          ??? 日志緩沖區(qū)大小由 LOG_BUFFER 參數(shù)指定,并可以在運(yùn)行的過程中中進(jìn)行動(dòng)態(tài)修改。日志緩沖區(qū)對(duì)數(shù)據(jù)庫性能的影響較小,當(dāng)然設(shè)置較大的日志緩沖區(qū)可以減少日志文件的 I/O 次數(shù),提高數(shù)據(jù)庫性能。
          ?
          3、共享池(Shared Pool)
          ?
          ??? 共享池分為:庫緩沖區(qū)、數(shù)據(jù)字典緩沖區(qū)、用戶全局區(qū) 三部分。共享池大小由 SHARED_POOL_SIZE 參數(shù)設(shè)定。
          ??? (1) 庫緩沖區(qū):緩存 SQL 語句的分析碼、執(zhí)行計(jì)劃
          ??? (2) 數(shù)據(jù)字典緩沖區(qū):包含從數(shù)據(jù)字典中得到的表、列定義和權(quán)限
          ??? (3) 用戶全局區(qū):包含了用戶的session信息
          ?
          ??? 當(dāng)一條SQL語句提交時(shí),Oracle首先從共享池的緩沖區(qū)內(nèi)搜索,查看是否有相同SQL被解析并執(zhí)行,若存在則不必再次解析。
          ?
          4、大池(Large Pool)
          ?
          ??? 大池是數(shù)據(jù)庫管理員能夠配置的可選內(nèi)存空間,可用于不同類型的內(nèi)存存儲(chǔ)。
          ?
          ??? Oracle 的某些操作可能需要內(nèi)存中使用大量的緩存,例如:
          ??? 1、數(shù)據(jù)庫的備份或恢復(fù)操作
          ??? 2、執(zhí)行具有大量排序操作的 SQL 語句
          ??? 3、執(zhí)行并行化的數(shù)據(jù)庫操作
          ??? 若沒有創(chuàng)建大池,這些操作需要的緩存空間都將在共享池或PGA中分配,大量的占用會(huì)影響到共享池和PGA的使用效率。大池的大小通過 LARGE_POOL_SIZE 設(shè)定。
          ??? 注:在共享服務(wù)器操作模式下,服務(wù)器進(jìn)程會(huì)將session信息存儲(chǔ)在大池中,而非共享池。session結(jié)束后大池即釋放內(nèi)存。
          ?
          5、Java池(Java Pool)
          ?
          ??? Oracle提供了對(duì)Java語言的支持,所以提供Java池。 Java池主要用于對(duì)Java語言提供語法分析區(qū)。
          ??? Java 池的大小由參數(shù) JAVA_POOL_SIZE 設(shè)定。
          ?
          6、流池(Stream Pool)
          ?
          ??? 這是Oracle Stream專用的內(nèi)存池,Oracle Stream是數(shù)據(jù)庫中的一個(gè)數(shù)據(jù)共享工具。
          ??? 該值由STREAMS_POOL_SIZE指定大小。若未配置該內(nèi)存區(qū),則當(dāng)使用到 Stream功能時(shí) ,Oracle會(huì)分配共享池中至多10%的空間作為Stream內(nèi)存。
          ?
          ?
          二、程序全局區(qū)(PGA)
          ?
          ??? PGA是包含單獨(dú)用戶或服務(wù)器數(shù)據(jù)和控制文件的內(nèi)存區(qū)域。PGA由用戶連接到數(shù)據(jù)庫時(shí)創(chuàng)建,進(jìn)行自動(dòng)分配,且是非共享的,只有服務(wù)進(jìn)程本身才能訪問它自己的PGA區(qū)。
          ??? 每一個(gè)服務(wù)進(jìn)程都有自己的PGA區(qū),PGA的內(nèi)容與結(jié)構(gòu)和數(shù)據(jù)庫的操作模式(專用/共享服務(wù)器)有關(guān)。
          ?
          ??? PGA 按照oracle官方文檔解釋,叫做程序全局區(qū)(Program Global Area),但也有些資料上說還可以理解為進(jìn)程全局區(qū)(Process Global Area)。這兩者沒有本質(zhì)的區(qū)別,它首先是一個(gè)內(nèi)存區(qū)域,其次,該區(qū)域中包含了與某個(gè)特定服務(wù)器進(jìn)程相關(guān)的數(shù)據(jù)和控制信息。每個(gè)進(jìn)程都具有自己私有的PGA區(qū),這也就意味著,這塊區(qū)域只能被其所屬的進(jìn)程進(jìn)入,而不能被其他進(jìn)程訪問,所以在PGA中不需要latch這樣的內(nèi)存結(jié)構(gòu)來保護(hù)其中的信息。籠統(tǒng)的來說,PGA里包含了當(dāng)前進(jìn)程所使用的有關(guān)操作系統(tǒng)資源的信息(比如打開的文件句柄等)以及一些與當(dāng)前進(jìn)程相關(guān)的一些私有的狀態(tài)信息。
          ?
          ??? 每個(gè)PGA區(qū)都包含兩部分:
          ??? (1) 固定PGA部分(Fixed PGA):這部分包含一些小的固定尺寸的變量,以及指向變化PGA部分的指針。
          ??? (2) 變化PGA部分(Variable PGA):這部分是按照堆(Heap)來進(jìn)行組織的,所以這部分也叫做PGA堆。可以從X$KSMPP視圖中看到有關(guān)PGA堆的分布信息。PGA堆中所包含的內(nèi)存結(jié)構(gòu)包括:
          ?
          ??? 有關(guān)一些固定表的永久性內(nèi)存。
          ??? 如果session使用的是專用連接方式(dedicated server),則還含有用戶全局區(qū)(UGA-User Global Area)子堆。如果session使用的是共享連接方式(shared server),則UGA位于SGA中。
          ??? 調(diào)用全局區(qū)(CGA-Call Global Area)子堆。
          ?
          ?
          三、用戶全局區(qū)(Sort Area)
          ?
          ??? UGA是包含與某個(gè)特定session相關(guān)信息的內(nèi)存區(qū)域,比如session的登錄信息以及session私有的SQL區(qū)域等。
          ?
          ??? 每個(gè)UGA也包含兩個(gè)部分:
          ??? (1) 固定UGA部分(Fixed UGA):這部分包含一些小的固定尺寸的變量,以及指向變化UGA部分的指針。
          ??? (2) 變化UGA部分(Variable UGA):這部分也是按照堆來進(jìn)行組織的,可以從X$KSMUP視圖中看到有關(guān)UGA堆的分布情況。
          ?
          ??? UGA堆的分布與OPEN_CURSORS、OPEN_LINKS等參數(shù)有關(guān)系。所謂的游標(biāo)(cursor)就是放在這里的。
          ??? UGA堆中所包含的內(nèi)存結(jié)構(gòu)包括:
          ??? (1) 私有SQL區(qū)域(Private SQL Area):這部分區(qū)域包含綁定變量信息以及運(yùn)行時(shí)的內(nèi)存結(jié)構(gòu)等數(shù)據(jù)。每一個(gè)發(fā)出SQL語句的session都有自己的私有SQL區(qū)域。
          ??????? 這部分區(qū)域又可分成兩部分:
          ??????? (i) 永久內(nèi)存區(qū)域:這里存放了相同SQL語句多次執(zhí)行時(shí)都需要的一些游標(biāo)信息,比如綁定變量信息、數(shù)據(jù)類型轉(zhuǎn)換信息等。這部分內(nèi)存只有在游標(biāo)被關(guān)閉時(shí)才會(huì)被釋放。
          ??????? (ii)運(yùn)行時(shí)區(qū)域:這里存放了當(dāng)SQL語句運(yùn)行時(shí)所使用的一些信息。這部分區(qū)域的大小尺寸依賴于所要執(zhí)行的SQL語句的類型(sort或hash-join等)和復(fù)雜度以及所要處理的數(shù)據(jù)行的行數(shù)以及行的大小。在處理SQL語句時(shí)的第一步就是要?jiǎng)?chuàng)建運(yùn)行時(shí)區(qū)域,對(duì)于DML(INSERT、UPDATE、DELETE)語句來說,SQL語句執(zhí)行完畢就釋放該區(qū)域;而對(duì)于查詢語句(SELECT)來說,則是在所有數(shù)據(jù)行都被獲取并傳遞給用戶以后被釋放,或者該查詢被取消以后也會(huì)被釋放。
          ??? (2) Session相關(guān)的信息。這部分信息包括:
          ??????? 1.正在使用的包(package)的狀態(tài)信息。
          ??????? 2.使用alter session這樣的命令所啟用的跟蹤信息、或者所修改的session級(jí)別的優(yōu)化器參數(shù)(optimizer_mode)、排序參(sort_area_size等)、修改的NLS參數(shù)等。
          ??????? 3.所打開的dblinks。
          ??????? 4.可使用的角色(roles)等。
          ?
          ??? 從上面可以很明顯的看出,我們最需要關(guān)注的就是私有SQL區(qū)域中的運(yùn)行時(shí)區(qū)域了。實(shí)際上,從9i以后,對(duì)這部分區(qū)域有了一個(gè)新的名稱:SQL工作區(qū)域(SQL Work Area)。SQL工作區(qū)域的大小依賴于所要處理的SQL語句的復(fù)雜程度而定。如果SQL語句包含諸如group by、Hash-join等這樣的操作,則會(huì)需要很大的SQL工作區(qū)域。實(shí)際上,我們調(diào)整PGA也就是調(diào)整這塊區(qū)域。后面還會(huì)說到這部分內(nèi)容。
          ?
          ??? 而UGA所處的位置完全由session連接的方式?jīng)Q定:
          ??? 如果session是通過共享服務(wù)器(shared server)方式連到數(shù)據(jù)庫的,則毫無疑問,UGA必須能夠被所有進(jìn)程訪問,所以這個(gè)時(shí)候UGA是從SGA中進(jìn)行分配的。進(jìn)一步說,如果SGA中設(shè)置了large pool,則UGA從large pool里進(jìn)行分配;否則,如果沒有設(shè)置large pool,則UGA只能從shared pool里進(jìn)行分配了。
          ??? 如果session是通過專用服務(wù)器(dedicated server)方式連到數(shù)據(jù)庫的,則UGA是從進(jìn)程的PGA中進(jìn)行分配的。
          ?
          ?
          ?
          附一: SGA 各部分大小解析 (轉(zhuǎn)載)
          *********************************************************************************
          ?
          SGA中的The fixed area包含了數(shù)千個(gè)原子變量,以及如latches和指向SGA中其它區(qū)域的pointers(指針)等小的數(shù)據(jù)結(jié)構(gòu).通過對(duì)fixed table內(nèi)表X$KSMFSV查詢(如下)可以獲得這些變量的名字,變量類型,大小和在內(nèi)存中的地址.
          SQL> select ksmfsnam, ksmfstyp, ksmfssiz, ksmfsadr from x$ksmfsv;
          ?
          這些SGA變量的名字是隱藏的而且?guī)缀跬耆恍枰ブ?但是我們可以通過結(jié)合fixed table內(nèi)表X$KSMMEM獲得這些變量的值或者檢查它們所指向的數(shù)據(jù)結(jié)構(gòu).
          SQL>select a.ksmmmval from x$ksmmem a where addr=(select addr from x$ksmfsv where ksmfsnam= ’ kcrfal_ ’ );
          ?
          SGA中的fixed area的每個(gè)組成部分的大小是固定的.也就是說它們是不依靠于其它的初始化參數(shù)的設(shè)置來進(jìn)行調(diào)整的.fixed area中的所以組成部分的大小相加就是fixed area的大小.
          ?
          The variable area:
          ?
          SGA 中的the variable area是由large pool和shared pool組成的.large pool的內(nèi)存大小是動(dòng)態(tài)分配的,而shared pool的內(nèi)存大小即包含了動(dòng)態(tài)管理的內(nèi)存又包含了永久性的(已經(jīng)分配的)內(nèi)存.實(shí)際上,初始化參數(shù)shared_pool_size的大小設(shè)置是指定shared pool中動(dòng)態(tài)分配的那部分內(nèi)存的一個(gè)大概的SIZES而不是整個(gè)shared pool的SIZES
          ?
          Shared pool 中永久性的內(nèi)存包含各種數(shù)據(jù)結(jié)構(gòu)如 :the buffer headers, processes, sessions, transaction arrays, the enqueue resources , locks, the online rollback segment arrays, various arrays for recording statistics. 其中大部分的SIZE是依靠初始參數(shù)的設(shè)置來確定的. 這些初始參數(shù)只能在實(shí)例被關(guān)閉的狀態(tài)下才能夠進(jìn)行修改 . 所以這里說的永久性是針對(duì)實(shí)例打開狀態(tài)下的生存期而言. 簡單的一個(gè)例子PROCESSES參數(shù). 在這個(gè) process arrays 中的 slots 用完之后 , 如果有其它的 process 想再申請(qǐng)一個(gè) process 則會(huì)失敗 , 因?yàn)樗鼈冊(cè)趦?nèi)存中的大小是在實(shí)例啟動(dòng)時(shí)預(yù)分配的. 不能動(dòng)態(tài)修改之 .
          ?
          針對(duì)很多永久性的 arrays, 有很多的 X$ 表都把這些元素做一個(gè)記錄而成員結(jié)構(gòu)則作為字段 .V$ 視圖的數(shù)據(jù)就是從這些 X$ 表獲得 . 如 V$PROCESS 是基于 X$KSUPR 內(nèi)表的 .V$PROCESS 視圖不包含 X$KSUPR 的全部字段 . X$KSUPR也沒有覆蓋SGA進(jìn)程結(jié)構(gòu)的所有成員.
          ?
          The variable area的在SGA中的SIZES就等于LARGE_POOL_SIZE,SHARED_POOL_SIZE和永久性的內(nèi)存arrays的SIZE三者相加. 永久性的內(nèi)存arrays的總的SIZE可以通過初始參數(shù)的設(shè)置來計(jì)算得到.然而,你需要知道從參數(shù)獲得這些array sizes的方程式,每個(gè)array元素大小的字節(jié)數(shù),還有array頭信息的sizes.這些跟Oracle的版本號(hào)和OS有關(guān).實(shí)際使用中,我們是不必要計(jì)算這個(gè)永久性的內(nèi)存arrays的SIZE的.如果想知道,一個(gè)方法就是在STARTUP NOMOUNT數(shù)據(jù)庫時(shí)記下the variable area.然后減去參數(shù)中LARGE_POOL_SIZE和SHARED_POOL_SIZE的大小就可以.
          ?
          The database block area:
          ?
          這個(gè)區(qū)域是數(shù)據(jù)庫塊的拷貝.在Oracle 8i中,buffer數(shù)由DB_BLOCK_BUFFERS指定.每個(gè)buffer的大小由DB_BLOCK_SIZE指定.所以這個(gè)區(qū)域的大小是兩者相乘.在Oracle 9i中,這個(gè)區(qū)域的大小是DB_CACHE_SIZE指定.這個(gè)區(qū)不包含它們自己的控制結(jié)構(gòu),只包含database block copies data.每個(gè)buffer的header信息存在于SGA的the variable area中.還有l(wèi)atches信息也放在SGA的the variable area中.在設(shè)置DB_BLOCK_BUFFERS時(shí)每4個(gè)BUFFERS會(huì)影響the variable area的1K的SIZE.關(guān)于這一點(diǎn).可以通過測試(針對(duì)8i而言).
          ?
          The log buffer:
          ?
          這個(gè)區(qū)域的SIZE是由參數(shù)LOG_BUFFER指定的.如果OS支持內(nèi)存保護(hù),log buffer將會(huì)被兩個(gè)保護(hù)頁面包圍起來以免被一些ORACLE的錯(cuò)誤進(jìn)程損壞log buffer.在SGA中,跟其它的如variable area和database block area相比,log buffer是非常小的.log buffer分成內(nèi)部的buffer blocks,而這些block各有8個(gè)字節(jié)的頭部信息存在于variable area中.
          ?
          The instance lock database:
          ?
          在OPS/RAC配置中,instance locks用來控制由所有instances共享的資源以串行的方式被進(jìn)入并使用.SGA中的這個(gè)區(qū)域所維護(hù)的是本地實(shí)例所要使用的數(shù)據(jù)庫資源,所有實(shí)例和進(jìn)程都會(huì)用到的數(shù)據(jù)庫資源,還有所有實(shí)例和進(jìn)程當(dāng)前需要的或者已經(jīng)擁有的鎖(LOCKS).這三個(gè)arrays的SIZE分別由參數(shù)LM_RESS,LM_PROCS,LM_LOCKS參數(shù)指定.(這三個(gè)參數(shù)是RAC的參數(shù),在單實(shí)例中用SHOW PARAMETER是查看不到的). The instance lock database還包含了message buffers和其它的structure.但是其SIZE是非常小的.
          ?
          這個(gè)區(qū)域的SIZE是沒辦法在實(shí)例啟動(dòng)的時(shí)候看到的.這是Oracle Internals.可以用ORADEBUG工具查看.SQL>ORADEBUG IPC.至于ORADEBUG工具就不做介紹.用這個(gè)工具做操作時(shí)需要經(jīng)過Oracle Support同意.
          ?
          可以用以下的兩種方式DUMP SGA:
          ?
          SQL>ALTER SESSION SET EVENTS 'immediate trace name global_area level 2';
          或者
          SQL>ORADEBUG DUMP GLOBAL_AREA 2;
          *********************************************************************************
          ?
          ?
          ?
          ?
          附二、PGA 管理(轉(zhuǎn)載)
          *********************************************************************************
          ?
          http://blog.oracle.com.cn/index.php/2446/viewspace-2843.html
          ?
          上文是一篇對(duì)于PGA的詳細(xì)介紹,如需仔細(xì)了解該部分內(nèi)容,則可查閱
          ?
          ?
          ?
          ?
          posted on 2008-08-22 22:13 decode360 閱讀(331) 評(píng)論(0)  編輯  收藏 所屬分類: 08.DBA
          主站蜘蛛池模板: 宣武区| 阿坝| 巴东县| 正蓝旗| 迭部县| 德钦县| 昌平区| 沅陵县| 湘潭县| 密山市| 贺兰县| 梨树县| 宝兴县| 巴里| 濉溪县| 建水县| 平安县| 道孚县| 江口县| 鄢陵县| 石屏县| 荥阳市| 大悟县| 安丘市| 河曲县| 宁城县| 霍山县| 瓦房店市| 石门县| 广丰县| 浦江县| 稷山县| 增城市| 余干县| 乐都县| 沧州市| 郑州市| 三台县| 遵义市| 兰坪| 阜阳市|