天天看點

oracle學習筆記 buffer_cache大小的設定及依據oracle學習筆記  buffer_cache大小的設定及依據



oracle學習筆記  buffer_cache大小的設定及依據

一)先回顧一下

前面講的buffercache的工作過程和大體的結構原理

磁盤有一堆dbf檔案

記憶體有buffercache

第一步:一個sql語句進來以後

如:select * from t2 where id=1;

首先是serverprocess會拿着這個sql語句去解析

解析的時候會用到cpu資源還會通路rowcache

解析完成以後生成執行計劃再存儲到librarycache裡面去

這時sql語句的第一步解析執行完了

第二步:要執行語句

執行時要通路資料

buffercache結構中一部分為鍊區,剩下的為buffer 

這裡面的鍊單元有位址指向裡面的一些buffer

這時oracle首先通過一系列的判斷以後

發現要通路的表t2裡面id等于1的行

先判斷應該在哪個鍊上

它計算完了以後它發現這個行所在的塊應該在某個鍊上但不見得在這個鍊上

然後對這個鍊進行周遊

第一種結果

在這個鍊上找到了這個block對應的buffer

既然找到了

這時候這個serverprocess直接讀這個buffer

不需要到磁盤再去讀了

第二種情況

在這個鍊上沒有找到這個block對應的buffer

這時serverprocess就會在buffer裡面找到一個可用的塊

假設一個塊可用

serverprocess把這個block讀到可用的buffer塊裡面去

同時把可用buffer塊的相關位址寫到對應鍊單元内

然後把資料接着讀出來

整個的,從鍊上找buffer,找不到時把block讀到記憶體去寫到buffer裡面去,然後再讀buffer

整個過程都是serverprocess做的

再看另外一個語句

update t2 set name=某個值 where id=1;

要修改某個block的某一行

這時同樣serverprocess經過解析以後要執行

執行時同樣判斷

這行所在的塊所在的block應該挂在某個鍊上

這裡在鍊上周遊發現周遊以後确實找到對應的buffer

直接在記憶體裡面修改buffer不須到磁盤上修改

修改完成以後buffer和block就不一緻了

這個buffer就成了一個髒的buffer

這個buffer會被挂在LRUW上和CHECKPOINT隊列上

而前面select語句結果通路的塊是幹淨的是可用的

它挂在LRU上

剛才最基本的知識都需要掌握

這是我們回顧的内容

二)DBWn程序和buffercache

接下來我們關心很多内容

某個髒塊髒了serverprocess并沒有把它寫回到磁盤上

是一個程序DBWn負責寫的,它是系統的一個程序

使用

[[email protected] ~]$ ps -ef|grep ora

查詢目前系統程序中與ora相關的程序

結果中有

oracle    3161     1  0 03:48 ?        00:00:00 ora_dbw0_jiagulun

的一個程序

此程序會把我們的髒塊寫到磁盤上

dbwn是一個背景程序

serverprocess是一個前台程序

我們的使用者送出一個sql語句

serverprocess接到sql語句

整個的從解析到執行到擷取這個過程都是serverprocess工作

serverprocess工作時使用者一直在等着,工作完了把結果返給使用者

使用者所執行的sql語句所等待的時間就是serverprocess工作的時間

是以serverprocess是直接面向使用者的叫前台程序

我們希望它越快越好

我們就希望serverprocess所做的事情越少越好

将髒塊寫回磁盤我們沒有讓serverprocess去做

而是交給一個背景程序DBWn這個程序

它的運作和使用者沒有關系,它并不影響使用者

它執行時使用者沒有在等待

它在背景周期性執行

1)髒塊和DBWn的觸發

有很多條件會觸發DBWn

1、每隔一段時間DBWn會觸發

一般觸發不會将整個的所有的髒塊全寫回磁盤

它會找LRUW鍊

将冷端的幾個髒塊寫回磁盤

因為冷端意味着不怎麼經常被使用

這是第一個每隔一個時間段

每次寫的時候寫一批不是寫所有的

2、沒有了幹淨塊

對于幹淨的和free的塊我們可以覆寫可以來使用

現在有一個block要調到記憶體裡面去

找了半天沒有找到幹淨塊沒有找到可用塊

這時也會觸發DBWn

DBWn會批量的寫一批buffer到磁盤上

寫過來的buffer和磁盤的block就一緻了

一緻以後就可用,這也是一種條件

3、資料庫關閉以後

DBWn會把所有的buffer全部寫回磁盤

1和2兩種情況最多

資料庫正常運作期間

1周期性DBWn觸發

2當我們的髒緩沖區到一定程度的時候會觸發DBWn

還有一種情況

我要在buffer裡面找一個可用塊的時候

半天都沒找着

就是找可用塊找的時間太長

雖然鍊還有剩餘,很多剩餘塊還沒有搜尋也會中途退出尋找

這裡有一個時間的門檻值我們叫閥值也可以叫門檻值

它也會觸發DBWn

總之DBWn是保證我們的髒塊能夠相對及時的合理的寫回到磁盤上

DBWn是背景

它的工作不影響前台不影響serverprocess

它在背景默默的工作

我們用資料庫的時候并不怎麼關心DBWn

2)DBWn的個數

系統程序查詢時

結果有程序名為ora_dbw0_jiagulun

其中dbw0有個數字0

既然有0,就可以有1

也就是DBWn程序可以是多個

但是我們不要去設定過多的DBWn

我們可以看一個參數

SQL> show parameter writer

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_writer_processes                  integer     1

db_writer_processes參數目前的值是1

也就是隻有一個程序

一般的它的預設值DBWn的個數是cpu數量除上8

如果你16顆cpu的話就應該是兩個DBWn程序

一般DBWn程序是夠的

老師有一次去使用者那裡

看到有一個很奇怪的現象

那麼多的DBWn而且DBWn占用cpu很高

最後發現它改過這個參數

老師問:你為什麼要改它?

他說:我覺得多一些資料庫更快!

老師的忠告是:其實不見得!

改這個參數也很容易

SQL> alter system set db_writer_processes=2;

alter system set db_writer_processes=2

                 *

ERROR at line 1:

ORA-02095: specified initialization parameter cannot be modified

結果提示這個參數不能被修改意味着它是靜态參數要使用scope=spfile選項靜态改

SQL> alter system set db_writer_processes=2 scope=spfile;

System altered.

然後重新開機資料庫

SQL> startup force;

ORACLE instance started.

Total System Global Area  285212672 bytes

Fixed Size                  1218968 bytes

Variable Size             104859240 bytes

Database Buffers          171966464 bytes

Redo Buffers                7168000 bytes

Database mounted.

Database opened.

測試環境下startup force可以重新開機資料庫

但實際環境這樣重新開機很危險的

因為這樣重新開機

整個過程中的關閉資料庫過程會被強制執行

而不管有沒有正在運作的程序和正在連接配接的使用者

非常可能造成資料的丢失,和引起資料庫故障。

再去查一下

[[email protected] ~]$ ps -ef|grep ora

結果中

oracle   21914     1  0 09:09 ?        00:00:00 ora_dbw0_jiagulun

oracle   21916     1  0 09:09 ?        00:00:00 ora_dbw1_jiagulun

有這麼兩行

說明目前DBWn有兩個程序

ora_dbw0_jiagulun和ora_dbw1_jiagulun

因為我們把db_writer_processes參數值設成2了

這次教給大家DBWn程序的數量到底設幾個不要亂設

三)buffercache大小

buffercache很重要,目前為止到底該設多大呢

1)buffercache大小的查詢和修改

buffercache的設定和sharedpool的設定很相似

一種情況我們單獨的去設定

如buffercache設定1個g或2個g

另外可以把buffercache的設定放在SGA target裡面去

oracle自動去設定buffercache大小

在實際的生産中我們還是經常的去手工設buffercache大小

這句

SELECT component,current_size,min_size FROM v$sga_dynamic_components;

是查一下目前我們sga裡面的各個元件到底是多大

buffer設定大小

alter system set db_cache_size=20M scope=memory;

也可以scope=both

設定buffercache大小這裡設的是20M

一般的有一個原則

DB_CACHE_SIZE = SGA_MAX_SIZE/2~ SGA_MAX_SIZE*2/3

dbcache設的大小一般是

SGA_MAX_SIZE的二分之一到三分之二

也就是整個的SGA的一半到三分之二的空間

我們建議大家直接設成三分之二

當然這個值不是很準确

我們到時候去通過相關的指令去設定去查

先查一下sga的狀态

SQL> SELECT component,current_size,min_size FROM v$sga_dynamic_components;                                               

COMPONENT                                                        CURRENT_SIZE   MIN_SIZE

---------------------------------------------------------------- ------------ ----------

shared pool                                                         100663296   96468992

large pool                                                            4194304    4194304

java pool                                                             4194304    4194304

streams pool                                                                0          0

DEFAULT buffer cache                                                167772160  167772160

KEEP buffer cache                                                           0          0

RECYCLE buffer cache                                                        0          0

DEFAULT 2K buffer cache                                                     0          0

DEFAULT 4K buffer cache                                                     0          0

DEFAULT 8K buffer cache                                                     0          0

DEFAULT 16K buffer cache                                                    0          0

DEFAULT 32K buffer cache                                                    0          0

ASM Buffer Cache                                                            0          0

13 rows selected.

這一行

DEFAULT buffer cache                                                167772160  167772160

是buffercache的大小

目前是100多M

sga總體大小為200多M

buffercache占了二分之一要多

仔細查一下設定的值

SQL> show parameter sga

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

lock_sga                             boolean     FALSE

pre_page_sga                         boolean     FALSE

sga_max_size                         big integer 272M

sga_target                           big integer 272M

sga設定的總大小sga_target為272M

SQL> show parameter db_cache_size

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_cache_size                        big integer 0

db_cache_size的設定的值為預設值0,說明沒有設定大小,用的全是由SGA自動調整

我們可以自己設定大小

我們設大小隻能往大了設,往小了設沒有意義

設的值比oracle系統配置設定給它的值小了

oracle不會理會這個自己設的值仍會采用自動配置設定的值

現在改一下

alter system set db_cache_size=200M scope=both;

SQL> alter system set db_cache_size=200M scope=both;

alter system set db_cache_size=200M scope=both

*

ERROR at line 1:

ORA-32017: failure in updating SPFILE

ORA-00384: Insufficient memory to grow cache

結果顯示沒有足夠的記憶體去增加

就是sga_target已經就這麼大了,都分完了

都分給各個池子了

這時要把DEFAULT buffer cache的值增加

要增加這個buffercache池子的大小的話

首先增加sga的大小

這地方首先說一下思路

首先增加sga_max_size大小

然後再增加sga_target

最後再增加db_cache_size

語句分别為

alter system set sga_max_size=500M scope=spfile;

alter system set sga_target=400M;

alter system set db_cache_size=200M;

其中的scope選項有三個可取值

scope=spfile

表示将參數值存入spfile檔案,即改變oracle的初始化參數檔案内容,在重新開機資料庫後才能生效

scope=memory

表示改變正在記憶體中運作的執行個體的參數值,隻在記憶體上修改,立即生效,

關閉執行個體此值就會丢失而被還原為原已儲存的值,因為這個修改并沒有寫入到初始化參數檔案

scope=both

表示将參數值同時存入spfile和memory,立即生效,因為存入了spfile重新開機資料庫後仍然有效。

both是預設值,修改靜态參數必須使用spfile,動态參數三種方式都可以用。

spfile檔案的位置

SQL> show parameter spfile

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

spfile                               string      /u01/app/oracle/product/10.2.0

                                                 /db_1/dbs/spfilejiagulun.ora

為了保護資料庫的安全有的參數進行了保護把它指定為靜态狀态

修改值時要加額外參數并且要資料庫重新開機才能生效

但大部分參數是動态的可以随時修改随時生效

sga_max_size是靜态參數,sga_target和db_cache_size是動态參數

這三個參數目前值

sga_max_size                         big integer 272M

sga_target                           big integer 272M

db_cache_size                        big integer 0

因為sga_max_size和sga_target目前值相同

是以這裡必須先修改sga_max_size并重新開機資料庫後

才能繼續修改sga_target的值使其增加

在sga有足夠空間時才能增加db_cache_size的值

我的修改過程

在sga_target把值增加後就會立即自動把剩餘的空間全部配置設定給db_cache_size

以為是因為db_cache_size使用預設值0,

但手工對db_cache_size配置設定值後效果仍然一樣。

在修改db_cache_size的值時

增加時是有限制的

sga要根據目前所有的狀态值分析有沒有足夠的空間滿足這個增大的值

減少時一般沒限制

因為這個值即使設定小了但sga仍使用自動配置設定空間配置設定給db_cache_size

一般真實值不會減少,仍保持在合理狀态

2)buffercache的合理值

有一個指令

SELECT size_for_estimate "Cache Size (MB)",size_factor,buffers_for_estimate "Buffers",

estd_physical_read_factor est_read_factor,

estd_physical_reads estd_phy_red,estd_physical_read_time est_phy_red_t

FROM  v$db_cache_advice

WHERE NAME='DEFAULT' AND block_size=(SELECT VALUE FROM v$parameter WHERE NAME='db_block_size');

可以通過這個指令查一下目前資料庫buffercache該設多大

執行一下:

SQL> SELECT size_for_estimate "Cache Size (MB)",size_factor,buffers_for_estimate "Buffers",

estd_physical_read_factor est_read_factor,

  2  estd_physical_reads estd_phy_red,estd_physical_read_time est_phy_red_t

  3    4  FROM  v$db_cache_advice

WHERE NAME='DEFAULT' AND block_size=(SELECT VALUE FROM v$parameter WHERE NAME='db_block_size');  5

Cache Size (MB) SIZE_FACTOR    Buffers EST_READ_FACTOR ESTD_PHY_RED EST_PHY_RED_T

--------------- ----------- ---------- --------------- ------------ -------------

             16          .1       1996          1.7523        14677            77

             32          .2       3992          1.1516         9646            48

             48          .3       5988               1         8376            40

             64          .4       7984               1         8376            40

             80          .5       9980               1         8376            40

             96          .6      11976               1         8376            40

            112          .7      13972               1         8376            40

            128          .8      15968               1         8376            40

            144          .9      17964               1         8376            40

            160           1      19960               1         8376            40

            176         1.1      21956               1         8376            40

            192         1.2      23952               1         8376            40

            208         1.3      25948               1         8376            40

            224         1.4      27944               1         8376            40

            240         1.5      29940               1         8376            40

            256         1.6      31936               1         8376            40

            272         1.7      33932               1         8376            40

            288         1.8      35928               1         8376            40

            304         1.9      37924               1         8376            40

            320           2      39920               1         8376            40

20 rows selected.

我們看一下這些列

Cache Size (MB)是假設的大小

如第一行結果

             16          .1       1996          1.7523        14677            77

設16MB的話會有1996個buffer

目前資料庫設定的塊的大小

SQL> show parameter db_block_size

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_block_size                        integer     8192

是以一個buffer是8K

16MB除以8K就是第一行Buffers列的值

EST_READ_FACTOR 為預估的實體讀因子

ESTD_PHY_RED 預估的實體讀的次數

EST_PHY_RED_T 預估的實體讀時間

我們可以以實體讀時間作為标準

因為buffercache最最突出的作用是緩存block

目的是減少實體io

這樣就減少了實體io讀的時間

如果設16M的話

預測的實體讀次數14677,系統的實體讀時間是77

如果設32M的話

預測的實體讀次數9646,實體讀時間是48

ESTD_PHY_RED和EST_PHY_RED_T基本上是同步的

次數多時間就長

對我們目前資料庫來講實際上

因為我的資料庫沒有任何負載48M就可以了

因為你設的再怎麼大

它對實體讀的次數和實體讀的時間的減少沒有任何意義

在實際生産中我們就是找這個數值

它對應的這行最後邊三列的值,在此行以後的行這三列的數值變化不大的時候

找此行Cache Size (MB)值設定就可以了

視訊課程中我們可以看到

老師個人比較喜歡

把平時要做的很多操作的一些sql語句提前給它找出來

找好了以後給它寫到txt檔案裡面去

以後幹活的時候在txt檔案中找直接複制出來用就行了

這樣它就成為了老師的一個工具

老師希望學生回去以後也要在這方面要去好好的去積累

積累以後你幹活的時候有工具

你幹活的時候就會非常的好

是以這些收集的語句都很重要

這個地方我們講了buffercache該設多大怎麼設

還教大家怎麼看目前大小

這是buffercache

知道這個以後基本的操作基本上都會了

這節課主要内容講了buffercache的設定

後面的課是block的狀态

block狀态其實應該是buffer的狀态

裡面好多東西可能大家不太了解需要詳細的講一下

内容還有一堆sql語句

2016年9月25日

     文字:韻筝