聊聊Oracle 11g的Result Cache(二)

startay發表於2016-06-22

本篇我們繼續討論Result Cache

 

4、聊聊理論

 

在之前的文章中,我們已經介紹了Result Cache的基本使用方法。這部分我們討論一下Oracle 11g Result Cache的深層原理。

 

從引數看,Oracle提供了Client Result CacheServer Result Cache兩種機制。

 

 

SQL> show parameter result_cache

 

NAME                                 TYPE        VALUE

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

client_result_cache_lag              big integer 3000

client_result_cache_size             big integer 0

result_cache_max_result              integer     5

result_cache_max_size                big integer 2080K

result_cache_mode                    string      MANUAL

result_cache_remote_expiration       integer     0

 

 

首先我們說說Server Result CacheOracleResult Cache引數就是表示Server端的Cache功能。Server Result Cache是在Oracle SGA中的Shared Pool裡面一塊記憶體池。這個Memory Pool包括兩個組成部分,或者說包括兩種快取內容,就是SQL語句的查詢結果和PL/SQL函式的返回值結果。Server Result Cache功能的初衷,就是為了緩解一些系統長期高頻度的訪問某些“穩定性好”的資料。(筆者按:也是權益之計,詳見下文)

 

當我們啟用Result Cache的時候,Oracle的工作流程是這樣的。首先,如果result_cache_mode引數是MANUAL,表示只有在使用result_cacheno_result_cache引數的時候,才能啟用Result Cache功能。

 

Oracle解析到SQL語句使用了hint後,就回到快取中查詢相應的記錄。如果不存在對應的結果集資訊,Oracle就會真正執行這個SQL語句,附帶將結果以一個ID儲存在shared poolcache pool中。第二次相同SQL到來之後,就會發現與現有ID的一致性,將結果直接返回。

 

應該說,OracleResult Cache是消除邏輯讀,更進一步的快取策略。但是,所有的快取都存在一個相同的問題,就是冗餘資料(Cache)的一致性。

 

從目前分析看,Oracle是藉助物件之間的“依賴”關係來做到資料同步。首先,我們看一個系列例子:

 

 

SQL> create table t_tab as select * from dba_tables;

Table created

 

SQL> select /*+result_cache*/count(*) from t_tab, t where t.owner=t_tab.owner and t.object_name=t_tab.table_name;

 

  COUNT(*)

----------

      4108

 

SQL> col name for a30;

SQL> select id, type, status, name, row_count from v$result_cache_objects;

 

        ID TYPE       STATUS    NAME                            ROW_COUNT

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

         1 Dependency Published SCOTT.T_TAB                             0

         0 Dependency Published SCOTT.T                                 0

         2 Result     Published select /*+result_cache*/count(          1

                                *) from t_tab, t where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

 

操作涉及到兩個物件tt_tab。我們從v$result_cache_objects檢視中,可以看到,Oracle不僅僅將那個結果集合(TYPE=RESULT)儲存下來,而且將兩個資料表的資訊儲存下來,作為“Dependency”關係。

 

從我們第三部分的實驗,我們可以知道,一旦發生資料表tt_tab的任何變化,包括資料DML變化操作,兩個快取的依賴物件就會失效,從而引發Result Cache結果集合的失效。注意:這個依賴是非常敏感的,即使是許可權變化這樣的小事,都會引起Cache的失效。

 

 

SQL> grant select on t to hr;

 

Grant succeeded

 

SQL> select id, type, status, name, row_count from v$result_cache_objects;

 

        ID TYPE       STATUS    NAME                            ROW_COUNT

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

         1 Dependency Published SCOTT.T_TAB                             0

         0 Dependency Published SCOTT.T                                 0

         2 Result     Invalid   select /*+result_cache*/count(          1

                                *) from t_tab, t where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

 

那麼,字面值(SQL語句結構)對快取有影響嗎?

 

 

 

SQL> select /*+result_cache*/count(*) from t_tab, t where t.owner=t_tab.owner and t.object_name=t_tab.table_name;

 

  COUNT(*)

----------

      4108

 

--新成立一個result cache

SQL> select id, type, status, name, row_count from v$result_cache_objects;

 

        ID TYPE       STATUS    NAME                            ROW_COUNT

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

         1 Dependency Published SCOTT.T_TAB                             0

         0 Dependency Published SCOTT.T                                 0

         3 Result     Published select /*+result_cache*/count(          1

                                *) from t_tab, t where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

         2 Result     Invalid   select /*+result_cache*/count(          1

                                *) from t_tab, t where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

--交換位置

SQL> select /*+result_cache*/count(*) from t, t_tab where t.owner=t_tab.owner and t.object_name=t_tab.table_name;

 

  COUNT(*)

----------

      4108

 

SQL> select id, type, status, name, row_count from v$result_cache_objects;

 

        ID TYPE       STATUS    NAME                            ROW_COUNT

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

         1 Dependency Published SCOTT.T_TAB                             0

         0 Dependency Published SCOTT.T                                 0

         4 Result     Published select /*+result_cache*/count(          1

                                *) from t, t_tab where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

         3 Result     Published select /*+result_cache*/count(          1

                                *) from t_tab, t where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

         2 Result     Invalid   select /*+result_cache*/count(          1

                                *) from t_tab, t where t.owner

                                =t_tab.owner and t.object_name

                                =t_tab.table_name             

 

 

SQL語句結構變化比較大的時候,Result Cache是不會共用的。

 

下面聊聊Client Result CacheClient Result Cache全名為Oracle Call InterfaceOCIClient Result CacheClient Result Cache主要是為了基於OCI的應用程式,每一個Client Result Cache是在一個應用程式中的,所有這個Process的會話,都會共享這個Result Cache

 

注意:Client Result CacheServer Result Cache是完全不同的兩個特點。相互之間沒有關係。

 

OCI Client Result Cache是直接在客戶端建立快取,適用於OCCIJDBC OCIODP.NET應用程式。OCI Client Result Cache最直接的好處就是減少資料庫相應和資源消耗,提高整體應用體驗。

 

對資料失效的問題,Oracle一旦發現依賴物件的失效,就會反向向客戶端傳送資訊,引起Client Cache的失效。

 

 

5Result Cache的相關引數解析

 

Result Cache的功能是透過Oracle一系列加入的引數來進行控制的。本部分介紹一下Oracle Result Cache所使用的引數資訊。

 

Server Result Cache是主體,預設Result CacheSGA中是有一塊區域pool的,透過hint Result_cacheno_result_cache來控制。從shared_pool中,我們可以看到當前result cache的資訊。

 

 

SQL> select * from v$sgastat where lower(name) like '%result_cache%'

  2  ;

 

POOL         NAME                                BYTES

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

shared pool  Result Cache: State Objs             2852

shared pool  Result Cache                        98396

shared pool  Result Cache: Memory Mgr              124

shared pool  Result Cache: Bloom Fltr             2048

shared pool  Result Cache: Cache Mgr              4416

 

SQL> show parameter result_cache

 

NAME                                 TYPE        VALUE

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

client_result_cache_lag              big integer 3000

client_result_cache_size             big integer 0

result_cache_max_result              integer     5

result_cache_max_size                big integer 2080K

result_cache_mode                    string      MANUAL

result_cache_remote_expiration       integer     0

 

 

ü  RESULT_CACHE_MAX_SIZE

 

大小控制引數,控制shared poolResult Cache可以達到的最大容量大小。如果這個引數設定為0,就表示不使用Result Cache功能。

 

ü  RESULT_CACHE_MAX_RESULT

 

比例控制引數,表示每一個Result Cache記錄可以使用到的Result Cache總大小比例。預設為5%

 

ü  RESULT_CACHE_REMOTE_EXPIRATION

 

遠端資料自我失效時間。在所有的資料集合中,Remote資料集合是最敏感的。因為資料從遠端來,受到網路因素影響。而且,通常比較難讓Invalid通知機制起作用。

 

REMOT_EXPIRATION的引數就是設定一個過期時間,以分鐘計數。超過這個時間的遠端結果集合會失效。預設這個引數取值為0

 

相對於傳統的Oracle記憶體池,在自動調整時代,Oracle是怎麼管理Result Cache大小呢?在啟動的時候,根據不同的情況設定,Oracle會選擇出Cache Pool的大小。

 

當設定MEMORY_TARGET的時候,Oracle會將Result Cache的大小設定為Target值的0.25%。如果沒有設定MEMORY_TARGET引數,只設定了SGA_TARGET,這個大小為0.5%。如果設定了SHARD_POOL_SIZE引數,這個演算法的引數值為1%

 

從引數上看,我們可以看到,對於每個Result Cache記錄,Oracle都是有保留的。並不是所有結果集合都會被記錄。當Result Cache Pool達到設定了本身的限制之後,比可用空間大的結果集合,都不會被快取。

 

Result Cache Pool自身使用的是LRU演算法,將結果Age Out出去。在RAC環境下,每個例項Instance都可以設定自己的Result Cache大小。

 

下面我們繼續介紹Result Cache相關的資訊。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17086096/viewspace-2120731/,如需轉載,請註明出處,否則將追究法律責任。

相關文章