gdufo

           

          Sizing the Buffer Cache

           

          1、overview
          buffer cache中緩沖了數(shù)據(jù)文件中的data blocks,是SGA的一部分,可以被所有的進(jìn)程共享。為了提高性能,Server 進(jìn)程一次讀入多data blocks,DBWn一次寫入多個(gè)data blocks到data file。
          相關(guān)的初始化參數(shù)有:
          DB_CACHE_SIZE:指定默認(rèn)的buffer pool的size,以bytes為單位。
          DB_KEEP_CACHE_SIZE:以bytes為單位,指明keep buffer pool的大小。
          DB_RECYCLE_CACHE_SIZE:以bytes為單位,指明recycle buffer pool的大小。
          在Oracle8i中,有以下特點(diǎn):
          **  buffer cache的大小事由DB_BLOCK_BUFFERS * DB_BLOCK_SIZE決定的;
          **  在某個(gè)時(shí)間點(diǎn),buffer cache中可能存在同一個(gè)data block的多個(gè)copies。只有一個(gè)是當(dāng)前實(shí)際的block。但是Server為了時(shí)間讀一致性,結(jié)合使用rollback信息,滿足不同的查詢。
          **  buffer cache中的blocks通過(guò)兩個(gè)lists進(jìn)行管理:①LRU list;②dirty list
          **  buffer cache中的blocks可能有三種狀態(tài):①free buffers:其在disk和memory中是一致的,可以被重用;②dirty blocks:disk和memory中的數(shù)據(jù)不同,只有這些blocks被寫入disk,才可被重用;③pinned blocks:當(dāng)前正在被訪問(wèn)的blocks

          2、buffer cache Sizing的參數(shù)(9i中)
          **  支持多種大小的block,system的block大小仍用db_block_size設(shè)置(后面稱其為primary block size),但其他tablespace可以有自己不同的block size。
          **  默認(rèn)的與primary block size相關(guān)的buffer pool通過(guò)db_cache_size設(shè)置。DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE與DB_CACHE_SIZE是獨(dú)立的。
          **  從9i開(kāi)始對(duì)SGA的infrastructure修改變?yōu)閯?dòng)態(tài)的,可以不必shutdown在startup。
          注:由于動(dòng)態(tài)SGA的分配,也引入的新的分配單元granule。可以通過(guò)v$buffer_pool監(jiān)控到buffer cache中g(shù)ranule的分配與回收
          1)granule:在9i中,SGA組件分配回收的單位是granule。是一段連續(xù)的虛擬內(nèi)存分配單位。其大小要依賴于對(duì)總SGA的估計(jì):如果估計(jì) SGA不足128MB,則設(shè)置為4MB,否則設(shè)置為16MB。當(dāng)instance startup時(shí),Server分配granule實(shí)體,組成SGA_MAX_SIZE的大小,并分配個(gè)SGA的不同組件。最小的SGA中要有3個(gè) granules,分別擁有redo buffer、data buffer cache和shared pool。dba可以通過(guò)alter system動(dòng)態(tài)的增加SGA的某個(gè)組件的memory大小,但是必須確保有足夠的free granules方可成功;memory granules不會(huì)被自動(dòng)釋放從而滿足其他組件memory增加的需求,可以減小某些組件的memory granules,但是縮減granules必須確保是未使用的,方可成功。在動(dòng)態(tài)添加組件memory時(shí),必須注意:新的cache sizes必須是granule size的整數(shù)倍;總的SGA size不可超過(guò)MAX_SGA_SIZE;DB_CACHE_SIZE不能設(shè)置為0(注意這是9i中,而我現(xiàn)在安裝的是11g,情況有所不同?。?br /> 2)動(dòng)態(tài)buffer cache的advisory parameter:通過(guò)設(shè)置db_cache_advice參數(shù)為on,可以提供buffer cache size的合并和預(yù)測(cè)統(tǒng)計(jì)數(shù)據(jù),從而輔助DBA調(diào)節(jié)buffer cache。db_cache_advice的可以設(shè)置為:off關(guān)閉advisory,并收回相應(yīng)的memory;ready,關(guān)閉advisory, 但保留其memory;on,打開(kāi)advisory,從而引起一定的cpu和memory開(kāi)銷。為了避免從off過(guò)渡到on時(shí)引起的ORA-4031 err,需要現(xiàn)將其設(shè)置為ready。
          3)buffer cache advisory收集的數(shù)據(jù)信息主要可以通過(guò)v$db_cache_advice視圖顯示
          select size_for_estimate, buffers_for_estimate, estd_physical_read_factor,estd_physical_reads
              from v$db_cache_advice where name=’DEFAULT’
                  and block_size = (select value from v$parameter where name = ‘db_block_size’)
                  and advice_status = ‘ON’;
          4)管理database buffer cache
          ①服務(wù)器進(jìn)程和database buffer cache:當(dāng)server需要申請(qǐng)一個(gè)block時(shí),需要一些步驟:
          i)server通過(guò)hash函數(shù)檢查被請(qǐng)求的block是否已經(jīng)在buffer cache中了。如果被找到了,則將其從LRU list中移動(dòng)到尾部。這將是邏輯讀。如果沒(méi)被找到,server 進(jìn)程需要將block從data file中讀入。
          ii)在從data file中讀入時(shí),server 進(jìn)程將先查找LRU list,找到一個(gè)free block。
          iii)當(dāng)查找LRU list時(shí),server 進(jìn)程同時(shí)會(huì)將相應(yīng)的dirty block移動(dòng)到dirty list中。
          iv)如果dirty list超過(guò)了其threshold size,server將給DBWn發(fā)信號(hào),讓其flush在dirty list中的 dirty blocks到data file中。如果server在查找的threshold范圍內(nèi)找不到空閑的block時(shí),DBWn也會(huì)受到類似信號(hào),直接將LRU list中的block寫入data file。
          v)當(dāng)空閑塊被找到之后,server將相應(yīng)的block讀入空閑塊。并將其放入LRU list的尾部。
          vi)如果block不一致,server將通過(guò)當(dāng)前block和rollback segments重建一個(gè)早期版本。
          vii)此外,對(duì)于DWRn進(jìn)程,每過(guò)3秒,會(huì)先將LRU list中的dirty blocks移動(dòng)到dirty list中,隨后將dirty list中的blocks寫入data file。
          viii)當(dāng)LGWR進(jìn)程發(fā)起checkpoint signals時(shí),DWRn也會(huì)先將LRU list中的dirty blocks移動(dòng)到dirty list中,隨后將dirty list中的blocks寫入data file。
          ix)當(dāng)發(fā)出命令alter tablespace offline或是進(jìn)行在線備份時(shí),DBWn也會(huì)先將LRU list中的dirty blocks移動(dòng)到dirty list中,隨后將dirty list中的blocks寫入data file。
          x)在刪除object時(shí),DBWn會(huì)先將與該object有關(guān)的dirty blocks寫入磁盤。
          xi)在正常的normal、immediate、transactional shutdown時(shí),也會(huì)flush data buffer。

          2、data buffer size的調(diào)節(jié)
          1)調(diào)節(jié)的目標(biāo)是提高data cache中的命中率,從而減少實(shí)際的物理I/O。
          2)診斷的工具主要是觀察cache的命中率(使用v$sysstat和utlbstat.sql與utlestat.sql等)和v$db_cache_advice
          select name,value from v$sysstat
              where name in (’session logical reads’, ‘physical reads’,
                  ‘physical reads direct’,'physical reads direct (lob)’); 
          • physical reads: Number of blocks read from disk
          • physical reads direct: Number of direct reads, does not require the cache
          • physical reads direct (lob): Number of direct reads of large binary objects
          • session logical reads: Number of logical read requests
          命中率 = 1- (physical reads – physical reads direct – physical reads direct (lob)) / session logical reads
          由于v$sysstat中的數(shù)據(jù)是自instance startup后的累計(jì)數(shù)據(jù),所以在startup不久就進(jìn)行此查詢獲得的結(jié)果是沒(méi)有太大意義的。
          v$buffer_pool描述了multiple buffer pools的情況,v$buffer_pool_statistics顯示了各個(gè)pool的統(tǒng)計(jì)情況
          select name, physical_reads, db_block_gets,consistent_gets from v$buffer_pool_statistics;
          v$bh:描述了保存在cache中的數(shù)據(jù)blocks
          3)tuning:
          改變cache的命中率,DBA可以:
          ①當(dāng)出現(xiàn)下面的情況時(shí),可以考慮增加buffer cache size:
          * cache的命中率不足90%
          * 有足夠的memory,不會(huì)引起額外的缺頁(yè)現(xiàn)象
          * 之前對(duì)cache的增加有較好的收效
          ②如果是由于data的訪問(wèn)特點(diǎn)造成了較低的命中率,可以考慮為不同的blocks使用多buffer pools,并適當(dāng)?shù)膶able配置緩沖到cache中
          ③此外,對(duì)于sorting和parallel reads,如果可以的話,避免其讀入cache。
          需要注意的是:還需考慮OS的caching的影響。
          4)對(duì)于命中率主要受到數(shù)據(jù)訪問(wèn)方式的影響
          * 全表掃描
          * data和application的設(shè)計(jì)
          * large table的隨機(jī)訪問(wèn)
          * cache的不均勻分布
          5)對(duì)于cache命中率的評(píng)估:
          * 如果上一次對(duì)data buffer cache的增加沒(méi)有活動(dòng)較好的收效,就不要繼續(xù)對(duì)其增加。
          * 當(dāng)查看命中率時(shí),要明確:在全表掃描時(shí)遇到的blocks并沒(méi)有放入到LRU的head部分,所以重復(fù)掃描不會(huì)造成blocks的緩沖
          * 由于設(shè)計(jì)和應(yīng)用層造成的重復(fù)掃描某個(gè)大表時(shí),將會(huì)造成性能問(wèn)題。所以建議盡量在一次讀取數(shù)據(jù),并適當(dāng)建立索引。
          6)使用multiple buffer pools:當(dāng)使用multiple buffer pools方法時(shí),objects被分配到那個(gè)pool要依靠其訪問(wèn)的方式。有三類buffer pools(我記得在11g中更靈活,不止三類了):
          * keep:此類pool用于存放可能被reused的對(duì)象。
          * recycle:該pool被用于存放reused可能性較小的blocks。
          * default:同single buffer cache中的cache是一致的。
          主要是通過(guò)DB_CACHE_SIZE, DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE參數(shù)設(shè)置的。它們都是動(dòng)態(tài)的。在9i中其latches是自動(dòng)分配 的。在8i中需要用db_block_lru_latches分配,一般是至少每50個(gè)blocks分配一個(gè)latch。
          在使用multiple buffer pools時(shí),可以使用如下sql語(yǔ)句:
          CREATE INDEX cust_idx .. STORAGE (BUFFER_POOL KEEP);
          ALTER TABLE customer STORAGE (BUFFER_POOL RECYCLE);
          ALTER INDEX cust_name_idx STORAGE (BUFFER_POOL KEEP);
          當(dāng)發(fā)出alter命令來(lái)修改buffer pool時(shí),之前的blocks仍保存在原有的buffer中,新load的才會(huì)被cache到新buffer pool中。
          因?yàn)閎uffer pool是以segment為單位分配的,有多個(gè)segments組成對(duì)象就可能被緩沖到不同的buffer pools中。
          7)keep buffer pool的使用:在確定keep pool大小時(shí),可以在設(shè)計(jì)時(shí)考慮要把那些object放入該buffer,然后求和即可。具體可以如下:
          analyze table hr.countries estimate statistics;
          select table_name, blocks from dba_table where owner = ‘HR’ and table_name = ‘COUNTRIES’;
          具體可以編寫腳本先后對(duì)DBA_TABLES, DBA_TAB_PARTITIONS, DBA_INDEXES和DBA_CLUSTERS進(jìn)行analyze。并根據(jù)訪問(wèn)的特性,將部分對(duì)象分對(duì)象所需要的blocks加總計(jì)算。
          8)對(duì)recycle pool的設(shè)置,不要設(shè)置過(guò)小,以免在事務(wù)或SQL還沒(méi)有被執(zhí)行完,就已經(jīng)被換出了。
          對(duì)其進(jìn)行監(jiān)控、并確定其size的工具可以使用v$sysstat中的物理讀(physical reads)的統(tǒng)計(jì)信息,此外可以使用v$cache視圖,它需要在sys下運(yùn)行catparr.sql腳本進(jìn)行創(chuàng)建。
          v$cache視圖從object的角度對(duì)buffer pool的blocks的占用進(jìn)行了統(tǒng)計(jì)。其實(shí)v$cache是為了Oracle parallel server(OPS)而發(fā)布的,在執(zhí)行catparr.sql時(shí),還創(chuàng)建了其他只在OPS中才有用的視圖。它還映射了DB object在datafile中的 extents。當(dāng)創(chuàng)建了新的object后,需要重新運(yùn)行該腳本。
          在決定recycle pool大小時(shí),可先令recycle pool disable;運(yùn)行catparr.sql;在DB使用高峰期,運(yùn)行下述語(yǔ)句計(jì)算每個(gè)object占用了多少blocks:
          select owner#, name, count(*) blocks from v$cache group by owner#, name;
          根據(jù)不同對(duì)象的訪問(wèn)特點(diǎn),確定哪些應(yīng)該被放入recycle pool并加總這些對(duì)象所占用的blocks,這里我用rcb來(lái)表示這個(gè)數(shù)。分配rcb/4大小的recycle pool。
          9)跟蹤物理讀的方法有很多:用調(diào)節(jié)工具如Oracle trace manager、sqlplus autotrace或是tkprof運(yùn)行sql都可以跟蹤其執(zhí)行時(shí)的物理讀。此外可以查看視圖v$sess_io。例如:
          select s.username, io.block_gets, io.consistent_gets, io.physical_reads
              from v$sess_io io, v$session s where io.sid = s.sid;
          10)計(jì)算multiple pools下的命中率,可以使用視圖v$buffer_pool_statistics
          select name, 1-(physical_reads/(db_block_gets+consistent_gets)) “hit_ratio”
              from v$buffer_pool_statistics where db_block_gets + consistent_gets > 0;
          11)在考慮不同的object使用何種pool時(shí),可從下面的觀點(diǎn)出發(fā):
          **  對(duì)于keep pool:blocks將被頻繁使用;segments的大小應(yīng)該小于default buffer pool大小的10%
          **  recycle pool:在所屬的transaction之外將很少被reused;segment的大小是default buffer pool兩倍之多
          12)將table caching:如果server通過(guò)全表掃描獲得數(shù)據(jù),blocks將被放到LRUlist的尾部,并可能會(huì)很快因缺少free blocks被換出。對(duì)此可以選擇將整個(gè)表cache到list的最近經(jīng)常使用的部分。具體可以在create table時(shí)使用cache關(guān)鍵字,或alter table使用cache,或使用cache的暗示。但是如果將太多的table放入LRU list的most recently used端,可能會(huì)使buffer cache非常擁擠。
          13)其他cache performance indicators
          ①select name, value from v$sysstat where name = ‘free buffer inspected’;
          如果此獲得的等待統(tǒng)計(jì)很大,并不斷增加需要考慮增加buffer pool。其表示了在查找free buffer是skipped的buffer。之所以skipped,是由于dirty或pinned。
          ②select event, total_waits from v$system_event where event in (‘free buffer waits’, ‘buffer busy waits’);
          除了v$system_event,也可從v$session_wait視圖。buffer busy wait表示有多個(gè)進(jìn)程嘗試同時(shí)訪問(wèn)buffer cache中的部分buffers。通過(guò)v$waitstat視圖可以查看所有不同buffer被等待統(tǒng)計(jì)數(shù)據(jù)。buffer busy wait中包含的類型有data block、segment header、undo header和undo block。如果在v$waitstat視圖中:
          * data block(tables或indexes的contention)較大:查看sql是否正確使用了索引;查看是否存在right-hand- indexes的情況(例如索引上的數(shù)據(jù)是由sequence產(chǎn)生);考慮是否使用segment-space管理或是增加free lists避免多個(gè)進(jìn)程同時(shí)向一個(gè)block中insert。
          * undo header:顯示了在回滾段header上沖突:對(duì)此如果不使用自動(dòng)的undo管理,則嘗試增加更多的rollback segments。
          * undo block:顯示了在rollback segment block的沖突:如果不使用自動(dòng)undo的管理,考慮增大rollback segment的sizes。
          * free buffer waits:表示server進(jìn)程不能找到free buffer了,signal DWRn寫入dirty blocks,這個(gè)過(guò)程引起的等待。對(duì)此,可以嘗試提升DBWR的效率,另一方面可以考慮是不是buffer cache設(shè)置過(guò)小了。
                 引起DBWR高效工作的原因可能是:i/o系統(tǒng)慢;i/o可能在等待某些資源,如latches;buffer cache太小了,造成DBWR需要不斷寫入臟數(shù)據(jù);buffer cache太大了,一個(gè)DBWR進(jìn)程迅速的無(wú)法釋放足夠的buffer。對(duì)此,可以進(jìn)一步查看等待DBWR的session,獲知具體的問(wèn)題。
          14)free list:它為每個(gè)對(duì)象維護(hù)一個(gè)blocks list用于數(shù)據(jù)的insert,free lists的數(shù)量是可以動(dòng)態(tài)設(shè)置的。但是對(duì)于單核cpu的系統(tǒng),使用多free lists的好處不大。調(diào)節(jié)free list的目的是可以減少insert時(shí)對(duì)free lists的爭(zhēng)用沖突。當(dāng)使用automatic free space management時(shí),Oracle使用bitmap存儲(chǔ)free-list的信息,在數(shù)據(jù)庫(kù)上降低了沖突,free lists就可以不用使用了。
          **  診斷free list的沖突的存在:


          如上,通過(guò)v$session_wait獲得等待時(shí)間具體在等待哪一個(gè)block,通過(guò)v$waitstat中class為segment header顯示了等待freelist的數(shù)據(jù),v$system_event視圖中event字段為’buffer busy waits’的記錄顯示freelist的等待的整體信息。我們可以通過(guò)dba_segments表查看是那些segments需要增加 freelist。具體的查詢語(yǔ)句如下:
          select s.segment_name, s.segment_type, s.freelists,
              w.wait_time, w.seconds_in_wait, w.state
              from dba_segments s, v$session_wait w
              where w.event=’buffer busy waits’
              and w.p1 = s.header_files and w.p2 = s.header_block;
          對(duì)freel ist的修改可以使用alter table語(yǔ)句進(jìn)行動(dòng)態(tài)修改,但是對(duì)于自動(dòng)segment空間管理的模式下是不能對(duì)freelist的數(shù)量進(jìn)行修改的。
          對(duì)于降低buffer busy waits可采取的措施有:
          **  對(duì)于data blocks:適當(dāng)改變pctfree或pctused;查看是否有right-hand index;增大initrans的值,降低每個(gè)block中存放的記錄的數(shù)量。
          **  對(duì)于segment header:使用free lists或增加free lists的數(shù)量,使用free list groups。
          **  對(duì)free list blocks:增加更多的free lists。(在Oracle Parallel Server中,應(yīng)該確保每個(gè)instance有自己的free list group)
          15)自動(dòng)管理空閑空間。從9i開(kāi)始,可以使用位圖對(duì)空閑和使用的blocks使用自動(dòng)空間管理,與free list相比,性能更好。它只能在創(chuàng)建tablespace時(shí)指明,此后,建立在該表空間上的所有segment都將以自動(dòng)空間管理方式管理。
          create tablespace tsp datafile ‘/path/datafile.dbf’ size nM
              extent management local segment space management auto;

          posted on 2010-01-12 12:27 gdufo 閱讀(708) 評(píng)論(0)  編輯  收藏 所屬分類: Database (oracle, sqlser,MYSQL)

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Hibernate

          友情鏈接

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 兴国县| 安吉县| 缙云县| 明水县| 建昌县| 洛阳市| 塔城市| 霍城县| 余干县| 恩施市| 牟定县| 象州县| 兴义市| 新泰市| 铅山县| 皮山县| 道孚县| 古田县| 深水埗区| 紫阳县| 织金县| 济南市| 乌什县| 沧源| 沙洋县| 娄烦县| 淮滨县| 花莲市| 吉安市| 宣威市| 文安县| 阳江市| 拉萨市| 晴隆县| 惠水县| 内江市| 通州区| 太仆寺旗| 洪泽县| 农安县| 莒南县|