11G DRCP(Database Resident Connection Pooling)的一些問題

viadeazhu發表於2009-01-20

DRCP (Database Resident Connection Pooling) 是11G的New feature,

網上討論它的文章還不多,也有可能是我太過孤寡。。。

個人覺得它的思想還是挺成熟的,透過動態釋放idle connections來達到多系統資源的重用,期望節省更多的資源,這樣就可以支援更多的連線。

相信DBA肯定做過很多balance connections的事情,當系統負荷太重的時候,尤其當用MTS,large pool快滿的時候我們就需要kill 一些idle的sessions。

現在,用DRCP,oracle的connection broker程式幫我們解決了這個問題。

oracle在white paper上寫到

"In one of our test scenarios on a 2GB system,
DRCP was able to support 10 times the number of connections compared to shared
servers, and 20 times the number of connections compared to dedicated servers."

我自己也做過一個小實驗,在redhat上,一個小型11G資料庫:

For 1 session using dedicated server,its memory of PGA is about 600KB;
For 1 session using MTS ,its memory in the large pool of SGA is about 140KB;
For 1 session using DRCP,its memory in the PGA is about 130KB.

We can see that the difference between MTS and DRCP is little on the memory allocated.
So I think the benifit of DRCP is because it can callback the idle pooled servers quickly and
then re-allocate the pooled servers to newly created connections.

好啦,說了這麼多,還是簡單介紹下如何配置DRCP吧。

其實很簡單,目前就一個package管理DRCP,那就是:DBMS_CONNECTION_POOL。

SQL> desc DBMS_CONNECTION_POOL
PROCEDURE ALTER_PARAM
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 POOL_NAME                      VARCHAR2                IN     DEFAULT
 PARAM_NAME                     VARCHAR2                IN
 PARAM_VALUE                    VARCHAR2                IN
PROCEDURE CONFIGURE_POOL
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 POOL_NAME                      VARCHAR2                IN     DEFAULT
 MINSIZE                        BINARY_INTEGER          IN     DEFAULT
 MAXSIZE                        BINARY_INTEGER          IN     DEFAULT
 INCRSIZE                       BINARY_INTEGER          IN     DEFAULT
 SESSION_CACHED_CURSORS         BINARY_INTEGER          IN     DEFAULT
 INACTIVITY_TIMEOUT             BINARY_INTEGER          IN     DEFAULT
 MAX_THINK_TIME                 BINARY_INTEGER          IN     DEFAULT
 MAX_USE_SESSION                BINARY_INTEGER          IN     DEFAULT
 MAX_LIFETIME_SESSION           BINARY_INTEGER          IN     DEFAULT
PROCEDURE RESTORE_DEFAULTS
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 POOL_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE START_POOL
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 POOL_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE STOP_POOL
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 POOL_NAME                      VARCHAR2                IN     DEFAULT

首先第一步,是開啟DRCP:

EXECUTE DBMS_CONNECTION_POOL.START_POOL('SYS_DEFAULT_CONNECTION_POOL');

目前11G版本支援一個pool name,就是“SYS_DEFAULT_CONNECTION_POOL”,所以寫不寫無所謂。

這樣其實就已經可以了,當資料庫重啟時,如果之前已經start了DRCP,則啟動後DRCP已經start了。

第二步,就是配置tnsnames.ora:

poolls=
        (DESCRIPTION=
        (SDU=8192)
        (TDU=8192)
        (ADDRESS=
        (PROTOCOL=TCP)
        (HOST=HaoRedHat)
        (PORT=1521))
        (CONNECT_DATA=(SID=hao)
        (SERVICE_NAME= poolls)
        (SERVER=pooled)))

記住最重要的是service=pooled是必須的。

第三部,sqlplus

 

配置它很簡單,接著就是自己需要根據自己系統的特性,配置個性化的DRCP,我們可以使用:

DBMS_CONNECTION_POOL.CONFIGURE_POOL (
   pool_name                IN VARCHAR2 DEFAULT 'SYS_DEFAULT_CONNECTION_POOL',
   minsize                  IN NUMBER   DEFAULT 4,
   maxsize                  IN NUMBER   DEFAULT 40,
   incrsize                 IN NUMBER   DEFAULT 2,
   session_cached_cursors   IN NUMBER   DEFAULT 20,
   inactivity_timeout       IN NUMBER   DEFAULT 300,
   max_think_time           IN NUMBER   DEFAULT 120,
   max_use_session          IN NUMBER   DEFAULT 500000,
   max_lifetime_session     IN NUMBER   DEFAULT 86400);


DBMS_CONNECTION_POOL.ALTER_PARAM (
   pool_name     IN  VARCHAR2 DEFAULT 'SYS_DEFAULT_CONNECTION_POOL',  
   param_name    IN  VARCHAR2,  
   param_value   IN  VARCHAR2);

這兩個過程來實現。具體使用查手冊就可以了。

有三個檢視可以用來tunning DRCP:

DBA_CPOOL_INFO
V$CPOOL_STATS
V$CPOOL_CC_STATS

 

其中有兩個很迷惑的問題我想問oracle:

1.maxsize 引數是用來設定一個pool最多能允許的pooled server數。但是我發現真正的maxsize其實是maxsize-1.

很容易證明這一點:

exec DBMS_CONNECTION_POOL.ALTER_PARAM ('','maxsize','3');

當我們已經有兩個connections時,當你在試圖建立一個新的connection時,第三個connection會等待前面兩個之一被回收。

Doc 577865.1 on metalink已經說明了這個case。

2.incsize 引數是用來設定當pool裡當前pooled server都被使用了,但還沒到maxsize的大小時,又有新的connection進來,

pooled server一次增長的個數。但我發現真正的incsize其實是incsize+1.

也很容易證明這一點:

exec DBMS_CONNECTION_POOL.ALTER_PARAM ('','minsize','3');
exec DBMS_CONNECTION_POOL.ALTER_PARAM ('','maxsize','100');
exec DBMS_CONNECTION_POOL.ALTER_PARAM ('','incrsize','10');

當我連線第三個connections時,

透過select NUM_OPEN_SERVERS from V$CPOOL_STATS;

或者透過在作業系統層面 ps -ef|grep ora_l0|grep -v grep

都可以看出增長之後的pooled server變成了14個,增長了11個。

 

這兩個mis-leading 的引數的例子都可以透過設定不通初始值reproduce出來,我已經發了SR問oracle了。

希望新的版本會改進這些mis-leading的引數。(雖然也沒啥意義。。。)

 

最後還有一個最不解的問題關於DRCP:

我們有一個系統檢視V$CPOOL_CC_STATS 來顯示connection級別的資訊,

另一個檢視V$CPOOL_STATS 來顯示pooled server總體的資訊。

我每次建立連線都是透過同樣的命令來實現,而且很明顯pooled server也被重用了,

但是這兩個檢視都把所有connections記錄為miss,居然一次hits都沒有。。。

SQL> select NUM_REQUESTS,NUM_HITS,NUM_MISSES from V$CPOOL_STATS;

NUM_REQUESTS   NUM_HITS NUM_MISSES
------------ ---------- ----------
          46          0         46

SQL> select NUM_REQUESTS,NUM_HITS,NUM_MISSES from V$CPOOL_CC_STATS;

NUM_REQUESTS   NUM_HITS NUM_MISSES
------------ ---------- ----------
          40          0         40
           6          0          6

十分詭異,如果前面那兩個迷惑的問題算做是misleading的引數問題,那麼這個應該能算作DRCP的一個小bug了吧。

 

如果有誰知道這以上三個問題是怎麼回事,請不靈賜教!

 

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

相關文章