Oracle內存結構(02)--緩衝區

1、Data_buffer_cache
用來保存頻繁訪問的數據的內存緩衝區域,以便於oracle用戶進程需訪問的某塊數據可以首先到data_buffer_cache中來尋找能命中(cache hit),從而大大減少從磁盤讀取數據所需要的IO時間。
兩個不同的列表:
  • 待寫列表(write list):包含已被修改的,但尚未寫入磁盤的髒緩存塊的指示列表。
  • 最近最少使用(Least recently used/LRU list):包含空閒緩存塊、命中緩存塊,及還未移入待寫列表的髒緩存塊的指示列表。
四個不同緩衝池:
  • Default pool
  • Keep pool
  • Recycle pool
  • DB_nk_cache_size
查看data_buffer_cache:
SQL> select current_size from v$buffer_pool;           #查看當前分配大小。
SQL> show parameter db%cache_size;                    #查看最低分配限制(ASMM下)
(1)Default pool
數據庫對象未特別指定時所使用的默認緩衝池。分別以不同算法處理緩衝區數據,使緩衝數據能盡長或盡短時間地佔用default pool緩衝區。
工作方式:
當oracle進程訪問一塊緩衝區後,會將該緩衝區移動到LRU列表的MRU端(下圖中的hot area),隨着更多被訪問的緩衝區移動到LRU列表的MRU端,較早前被訪問過的緩衝區就會逐漸向LRU列表的LRU端(下圖中的Cold area)移動。
 
當用戶進程執行全表掃描時,數據首次將會從磁盤被讀入內存緩衝區,之後將該緩衝區移動到LRU列表的LRU端,以使這些通常只是暫時需要的全表掃描數據所佔用的緩衝區能被儘快地移出數據緩衝區,爲其他使用頻率更高的數據塊騰出空間。
查看當前分配的大小:
 SQL> select component,current_size from v$sga_dynamic_components where component='DEFAULT buffer cache';
或SQL> select name,current_size from v$buffer_pool;
如何指定對象使用default pool緩衝區:默認使用default pool。
測試default pool使用效果:
SQL> shutdown immediate
SQL> startup                       #重啓數據庫,清空緩存。
SQL> show parameter db%cache_size     #查看data_buffer_cache大小。
SQL> conn system/oracle                 #以非sysdba用戶登錄。
SQL> create table t1 as select * from dba_objects;     #創建測試表。
SQL> select object_name,a.status,count(*) from v$bh a,user_objects b
  2  where a.objd=b.object_id and object_name in ('T1') group by object_name,a.status;
OBJECT_NAME                    STATUS    COUNT(*)
------------------------------ ------- ----------
T1                             xcur             1                      #查看指定對象在default pool中所佔用的緩衝區塊數目。
SQL> set autotrace on statistics                #開啓顯示統計信息功能。
SQL> select count(*) from t1;                  #全表掃描。
  COUNT(*)
----------
     49807
Statistics
----------------------------------------------------------
         28  recursive calls
          0  db block gets
        761  consistent gets
        684  physical reads                                            #有物理讀。
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
SQL> select count(*) from t1;                        #再次全表掃描。
  COUNT(*)
----------
     49807
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        689  consistent gets
          0  physical reads                                #無物理讀。
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
SQL> select object_name,a.status,count(*) from v$bh a,user_objects b
  2  where a.objd=b.object_id and object_name in ('T1') group by object_name,a.status;
OBJECT_NAME                    STATUS    COUNT(*)
------------------------------ ------- ----------
T1                             xcur           685                      #查看指定對象在default pool中所佔用的緩衝區塊數目。
(2)Keep pool
將存儲在該緩存的數據一直保存在緩存中。該緩存不參與ASMM的動態管理,不能自動調整大小。默認未啓用,大小爲0.手工修改指定值後,default pool的空間將被相應的消減。
經常訪問的熱點表應該專門放入keep pool,以防止在默認情況下所有對象都使用default pool時,一個大對象臨時調入default pool將其中的真正熱點數據擠出default pool帶來的性能損失。
工作方式:
與default pool不同,新讀入的數據不斷以先進先出的方式從LRU表的MRU端移動到LRU端,直到無空閒緩衝時,LRU端最久未使用的數據被調出緩衝區。
查看當前分配的大小:
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='KEEP buffer cache';                      
SQL> select name,current_size from v$buffer_pool;
修改當前分配大小:
SQL> alter system set db_keep_cache_size=10M scope=both;
SQL> show parameter db_keep_cache
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='KEEP buffer cache';                      
SQL> select name,current_size from v$buffer_pool;            #可見default pool相應地減少了。
指定對象使用keep pool:
SQL> create table t_keep(n int) storage(buffer_pool keep);
SQL> alter table t1 storage(buffer_pool keep);
(3)Recycle pool
隨時清除存儲在其中不再被用戶需要的數據,該緩存不參與ASMM的動態管理,不能自動調整大小。默認未啓用,大小爲0.手工修改指定值後,default pool的空間將被相應的消減。
不常訪問的大對象應該專門放入recycle pool,以防止一個大對象臨時調入default pool,而將其中真正的熱點表擠出default pool帶來的性能損失。
工作方式:
與default pool和keep pool都不同,對於recycle pool,先進入緩存的表被保留在recycle pool中。recycle pool滿了以後,讀取的數據將不被緩存。
查看當前分配的大小:
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='RECYCLE buffer cache';
SQL> select name,current_size from v$buffer_pool;
修改當前分配大小:
SQL> alter system set db_recycle_cache_size=10M scope=both;
SQL> show parameter db_recycle_cache
SQL> select component,current_size from v$sga_dynamic_components
  2  where component='RECYCLE buffer cache';
SQL> select name,current_size from v$buffer_pool;
指定對象使用keep pool:
SQL> create table t_rec(n int) storage(buffer_pool recycle);
SQL> alter table t1 storage(buffer_pool keep);
2、shared pool
共享池是SGA中最關鍵的內存片段,特別是在性能和可伸縮性上。一個太小的共享池會降低性能,使系統停止;太大的共享池也會有同樣的效果,將會消耗大量的CPU來管理這個共享池。
shared pool分爲library_cache和data dictionary cache兩個主要的部分及近600項其餘部分。
查看shared_pool參數默認設置值,爲0則表示ASMM已開啓:
SQL> show parameter shared_pool_size;
查看shared_pool當前運行期間所分配大小:
SQL> select pool,sum(bytes) from v$sgastat group by pool;
查看shared_pool中所有組成部分:
SQL> select * from v$sgastat;
SQL> select pool,sum(bytes) from v$sgastat group by pool;
(1)Library Cache
用戶提交一個新SQL語句時,Oracle會分析(parse)該句SQL(硬解析),這個過程將耗費相對較多的時間。分析完畢後,oracle會將該SQL的分析結果給保存在Library Cache中,當數據庫再次執行該SQL時,oracle將直接取第一次分析結果而不再重新解析,從而減少運行時間。
  • Library Cache四個組成部分:
  • 共享SQL區:保存語句文本,編譯後的語法分析樹及執行計劃。
  • 私有SQL區:保存語句中的變量值。
  • 共享PL/SQL區:保存PL/SQL語句。
  • 控制結構區:保存鎖等控制信息。
查看library cache的大小:
SQL> select sum(sharable_mem) from v$db_object_cache;
測試library cache的作用:
SQL> set timing on
SQL> select count(*) from dba_objects;
  COUNT(*)
----------
     49809
Elapsed: 00:00:00.20
SQL> select count(*) from dba_objects;
  COUNT(*)
----------
     49809
Elapsed: 00:00:00.10
查看保存在library cache中保存的已分析的SQL語句:
SQL> select * from v$sqltext where sql_text like '%dba_object%';
SQL> select sql_text from v$sqlarea where sql_text like '%dba_object%';
綁定變量:
綁定變量的使用:
SQL> select object_id,object_name from dba_objects where object_id=5100;
SQL> select object_id,object_name from dba_objects where object_id=5101;
SQL> variable i number;            #定義變量。
SQL> exec :i:=5100;                 #給變量賦值。
SQL> print :i                            #打印變量值。
SQL> select object_id,object_name from dba_objects where object_id=:i;
SQL> exec :i:=5101;
SQL> select object_id,object_name from dba_objects where object_id=:i;
SQL> select sql_text,parse_calls from v$sqlarea where sql_text like '%object_id%';
SQL_TEXT
--------------------------------------------------------------------------------
PARSE_CALLS
-----------
select object_id,object_name from dba_objects where object_id=:i              #緩存的sql語句。
          2                                                                                                #被調用次數。
select sql_text,parse_calls from v$sqlarea where sql_text like '%object_id%'
          1
select object_id,object_name from dba_objects where object_id=5100
          1
select object_id,object_name from dba_objects where object_id=5101
          1
#可見使用綁定變量可以增加sql語句緩存的命中率,減少硬解析所帶來的性能損失。

Data Dictionary Cache

專供數據字典使用的緩衝區,SQL語句分析過程中需要大量訪問系統數據字典(從磁盤數據文件中訪問數據字典成爲recursive calls),即可使用該緩存區專門存放數據字典,從而避免過多的recursive calls所帶來的性能損失。

數據字典是關於數據庫的參考信息、數據庫的結構信息、數據庫的用戶信息等各類信息描述的一組表和視圖的集合。

數據字典用於描述所有數據庫對象的數據庫對象的集合。

SQL> select * from v$fixed_table;   #查看系統中所有的動態表。

SQL> select * from dict;          #查看數據字典。

SQL> select object_name,object_type,created from dba_objects where object_name in ('TEST','T1');                      #從數據字典的dba_objects表中查詢指定數據庫對象的相關描述。

SQL> select * from dba_users;         #從數據字典dba_users表中查詢數據庫用戶的相關描述。

SQL> select * from dba_data_files;  #從數據字典dba_data_files表中查詢所有數據庫文件的相關描述。

數據字典中表的分類:

靜態表:對各類數據庫對象的各類屬性的描述,常見的有下面三類字母開頭:

  1. dba_*:存儲當前數據庫中所有數據庫對象的描述
  2. all_*:存儲當前用戶能夠訪問的數據對象的描述
  3. user_*:存儲當前用戶所擁有的數據庫對象的描述

動態表:不斷動態更新以反映數據庫當前運行狀況,常見以“v$”開頭。

 

查看data dictionary cache的大小:

SQL> select sum(sharable_mem) from v$sqlarea;

測試的data dictionary cache作用:

SQL> set autot on stat                                #打開統計信息顯示。
SQL> select count(*) from dba_source;             #查詢一張表。

  COUNT(*)
----------
    292167

Statistics
----------------------------------------------------------
        312  recursive calls                                   #recursive calls 次數。
          0  db block gets
       1998  consistent gets
        698  physical reads
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> select count(*) from dba_source;             #再次查同一張表。

  COUNT(*)
----------
    292167

Statistics
----------------------------------------------------------
          0  recursive calls                                  #可見recursive calls 次數明顯減少。
          0  db block gets
       1927  consistent gets
          0  physical reads
          0  redo size
        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

3、Large pool

large_pool用來分配大內存塊,來處理比shared pool更大的內存,實際常用做備用池,用以緩解oracle對共享池和PGA區內存的使用壓力。使用large pool的對象主要有:

多線程服務器MTS:在SGA的large_pool中分配UGA;

語句的並行查詢Parallel Exection:用作進程間的消息緩衝器;

恢復管理器RMAN:備份時用作磁盤I/O緩衝區。

SQL> show parameter large_pool             #查看large_pool參數默認值,爲0則應表示ASMM已開啓。

SQL> select pool,sum(bytes) from v$sgastat group by pool;   # 查看large_pool當前運行期間ASMM實際分配大小。

4、Java pool

oracle在內核中加入了對java的支持。該緩衝區轉爲java開發和應用所設,若不用java程序則沒必要改變該緩衝區的默認大小。

SQL> show parameter java_pool             #查看java_pool參數默認值,爲0則應表示ASMM已開啓。

SQL> select pool,sum(bytes) from v$sgastat group by pool;   # 查看java_pool當前運行期間ASMM實際分配大小。

5、redo_log_buffer

對數據庫的任何修改都按順序被記錄在該緩衝區,然後由LGWR進程根據條件將更改信息批量寫入磁盤上的redo log文件,以節省磁盤IO。該緩存不參與ASMM的動態管理,不能自動調整大小。

SQL> select name,bytes from v$sgastat where name='log_buffer';   #查看log_buffer實際大小。

SQL> show parameter log_buffer              #查看log_buffer預設大小。

SQL> alter system set log_buffer=2000000 scope=spfile;     #手工修改log_buffer大小,需重啓。

6、streams_buffer

用於對流複製進行緩衝。

SQL> show parameter streams_pool     #查看streams_pool參數默認值。

 

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