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負責寫的,它是系統的一個進程


使用
[oracle@redhat4 ~]$ 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可以重啓數據庫
但實際環境這樣重啓很危險的
因爲這樣重啓
整個過程中的關閉數據庫過程會被強制執行
而不管有沒有正在運行的進程和正在連接的用戶
非常可能造成數據的丟失,和引起數據庫故障。


再去查一下
[oracle@redhat4 ~]$ 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日
     文字:韻箏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章