Oracle 11g DRCP連接方式

在Oracle 11g中,提出了突破傳統專用/共享連接的第三種連接方式——Database Resident Connection Pooling(DRCP)。本篇我們一起來探討這項技術。

 

1、 從Dedicated Server到Shared Server

 

Oracle Client Process連接到Server Process的方式,傳統上有兩種方式:Dedicated Server和Shared Server。在Client連入到Oracle Server的過程中,默認是通過監聽器listener監聽器進行Oracle實例服務定位。只有再由監聽器fork出的子進程向Instance請求出一個Server Process與Client Process遠程通信。不同的連接方式,就體現在數據庫實例在接受到Server Process請求後,是怎麼樣提供出Server Process進程,以及該進程如何管理的。

 

Dedicated Server模式也稱爲專用連接方式,就是Oracle Instance會專門創建出一個新的Server Process與Client Process進行遠程通信。在整個Client Process請求過程中,Server Process只爲該Client提供服務。UGA信息也保存在Server Process的PGA空間中。當會話結束,Client連接中斷,Server Process就失去“存在意義”被清除掉,分配內存回收。Dedicated方式是我們最常使用的數據庫連接方式。在長會話或前端應用使用連接池組件的情況下,Dedicated方式的優勢是很明顯的。

 

與Dedicated Server模式對應的是Shared Server。在該模式下,Oracle實例會維持兩種Server Process:分發進程(Dispatcher DXXX)和共享進程(SXXX)。

 

 

SQL> select addr, pid, spid, username, program from v$process where program like '%000%';

 

ADDR            PID SPID         USERNAME        PROGRAM

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

6D24BA1C         13 648          SYSTEM          ORACLE.EXE (D000)

6D24C00C         14 1736         SYSTEM          ORACLE.EXE (S000)

 

 

 

當監聽器向數據庫實例提出Server Process分配請求的時候,在Shared Server模式下,監聽器會向分發進程DXXX請求分配Server Process。DXXX會根據當前的空閒Server情況,分配出一個Server Process供使用。當Client使用結束之後,Server Process(SXXX)並不是被釋放,而是重新回到D000管制下。系統也會依據參數設置,維持一個穩定的SXXX數量。

 

 

SQL> show parameter shared_servers

 

NAME                                 TYPE        VALUE

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

max_shared_servers                   integer    

shared_servers                       integer     1

 

 

Shared Server連接模式的出現,是和短會話、高併發的互聯網應用發展相關。每次創建和回收Server Process的成本是很高的。如果應用沒有中間層連接池,而是高併發的創建Server Process並且快速回收,這對於數據庫來說是很高的壓力。

 

從現在的應用設計開發看,連接池管理已經滲透入主流應用系統框架,shared server方式實際中應用不是很廣泛。

 

2、Database Resident Connection Pooling(DRCP)

 

如果我們站在軟件模式的角度看,Shared Server本質上也是想實現一種在數據庫層面上的連接池。這點在Oracle 11g上得到了實現,Oracle駐留連接池(DRCP)就是一個允許在多進程(Multi-Process)和多線程(Multi-Threads)之間共享連接的新特性。

 

Shared server在一定程度上緩解了Server process IDEL和頻繁創建銷燬Server process的問題。但是,Shared Server沒有解決Session數據共享的問題。當存在client需要長時間持有session,同時其他client沒有大量會話要求的時候,這種模型是有效的。但是,在每次請求會話的時間很短(短會話)和數據庫活動需要多次會話交互的時候,DRCP就是更加理想的連接池模型了。

 

DRCP新特性主要針對的就是應用程序在訪問數據庫時,出現高併發連接數問題。DRCP連接池將Server和Session信息進行緩存,爲多個訪問的應用程序提供連接共享。

 

同Shared Server一樣,DRCP前端存在一個代理(Connection Broker),負責應用中間件連接的共享要求,同時負責管理數據庫實例上的連接池連接。當應用中間件想Broker提出連接請求的時候,Broker會從連接池中找出空閒連接。當交互結束後,Server Process被釋放回連接池供重用。

 

同shared server不同的方面在於。當共享池中連接池被分配出之後,等價於dedicated server方式。

 

 

3、三種連接方式的內存使用情況

 

三種連接方式下,Oracle實例、Server Process和內存使用方式截然不同。

 

ü        Dedicated Server方式

 

當Client Server請求連接的時候,全新的Server Process和session信息被創建。當連接中斷,Server Process和Session全部被釋放。內存分配是一個連接要分配Server Process和Session的空間。UGA信息是保存在PGA裏的。

 

ü        Shared Server方式

 

當接收到Client Server的請求之後,Dispatcher會將請求放置在一個common隊列中。可用的Server Process就從隊列中獲取請求信息。當終止會話之後,對應的會話信息就被釋放掉。Session信息是從SGA中分配出。

 

ü        DRCP方式

 

當Client Server請求之後,Connection Broker從連接池中尋找一個空閒Pooled Server提供給Client Server。如果沒有空閒的,Connection Broker就會創建出一個新的連接。如果當前連接池已經達到最大數量限制,就將請求放置在等待隊列中,等待空閒Server。

 

當釋放Pooled Server回到Connection Pool的時候,相應的數據庫資源被釋放掉。DRCP的內存要求與存儲池大小和會話有關。每個Pooled Server有一個Session信息,且存儲在PGA中。

 

下面一個分配實例,來說明情況:

 

場景:一個應用程序,其每個session需要400k的空間。每個Server process對應4M空間。連接池大小爲100,共享shared Server大小數據量也是100。如果有5000個連接數。

 

在Dedicated Server模式下:

 

Memory Usage=5000*(0.4M+4M)=22GB;

 

在Shared Server模式下:

 

Memory Usage=5000×0.4M+4M×100=2.5GB;注意,其中Session信息的2G是從SGA中分配的。

 

在DRCP模式下:

 

Memory Usage=100×(4M+0.4M)+5000×35K=615MB。注意:35K爲維護會話信息使用的內存大小。

 

4、結論

 

DRCP模式在傳統的shared server基礎上,爲前端應用提供更加成熟的數據連接池解決方案。從目前的資料看,DRCP對OCI、PHP等多種驅動提供了支持。注意:對JDBC Thin和JDBC OCI的支持還不存在。


1、Database Level Configuration

 

配置DRCP是分爲兩個步驟:database level configuration和application level configuration。首先在Database Server層面創建連接池對象。我們使用Oracle 11g進行試驗。

 

 

SQL> select * from v$version;

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0    Production

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0  Production

 

 

在默認情況下,Oracle 11g中是有一個默認的連接池對象。在視圖dba_cpool_info中,可以看到連接池信息。

 

 

SQL> select connection_pool, status, minsize, maxsize, INACTIVITY_TIMEOUT from dba_cpool_info;

 

CONNECTION_POOL                STATUS              MINSIZE    MAXSIZE INACTIVITY_TIMEOUT

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

SYS_DEFAULT_CONNECTION_POOL    INACTIVE                  4         40                300

 

 

連接池sys_default_connection_pool就是默認連接池,狀態是inactive。使用dbms_connection_pool包,可以方便的對其進行管理。

 

 

SQL> exec dbms_connection_pool.start_pool();

PL/SQL procedure successfully completed

 

 

使用start_pool方法,可以對默認池進行開啓。注意:該方法還有參數pool_name,如果指定了名稱,就可以創建出一個自定義的連接池,也可以同時管理多個連接池情況。如果不指定名稱,就針對默認連接池進行管理。

 

Start_pool之後,dba_cpool_info視圖中可以看到連接池狀態。

 

 

SQL> select connection_pool, status from dba_cpool_info;

 

CONNECTION_POOL                STATUS               MINSIZE   

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

SYS_DEFAULT_CONNECTION_POOL    ACTIVE                    4    

 

 

注意,此時沒有連接,但是我們觀察後臺進程,發現新增加了連接池Server Process對象。

 

 

[oracle@oracle11g ~]$ ps -ef | grep ora_n

oracle    5800     1  1 05:07 ?        00:00:00 ora_n000_wilson

oracle    5816  5584  0 05:07 pts/0    00:00:00 grep ora_n

[oracle@oracle11g ~]$ ps -ef | grep ora_l

oracle    5689     1  0 05:03 ?        00:00:00 ora_lgwr_wilson

oracle    5802     1  0 05:07 ?        00:00:00 ora_l000_wilson

oracle    5804     1  0 05:07 ?        00:00:00 ora_l001_wilson

oracle    5806     1  0 05:07 ?        00:00:00 ora_l002_wilson

oracle    5808     1  0 05:07 ?        00:00:00 ora_l003_wilson

oracle    5818  5584  0 05:07 pts/0    00:00:00 grep ora_l

 

 

其中ora_n000進程是對應的Connection Broker對象,負責連接管理。Ora_lxxx進程就是連接池中的連接對象。當沒有連接的時候,連接池維持minsize大小,與配置minsize=4相匹配。

 

下面進行application level configuration。

 

2、Application Level Configuration

 

在應用層面,可以從連接字符串或者本地服務名上進行配置。本篇主要從本地服務名上進行配置。

 

在tnsnames.ora中,我們可以進行本地命名配置。爲了保證正確性,筆者傾向使用Oracle提供的netca工具來進行基礎配置。

 

 

--開啓X Windows Passive模式

[oracle@oracle11g ~]$ export DISPLAY=192.168.0.1:0.0

[oracle@oracle11g ~]$ netca

 

Oracle Net Services Configuration:

Default local naming configuration complete.

    Created net service name: wilsondrcp

Oracle Net Services configuration successful. The exit code is 0

 

 

之後,修改tnsname.ora文件的相關內容。

 

 

WILSONDRCP =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.88)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = POOLED) --新增加到其中,表明連接使用連接池;

      (SERVICE_NAME = wilson)

    )

  )

 

 

可以使用tnsping方法進行驗證。

 

 

[oracle@oracle11g ~]$ tnsping wilsondrcp

 

TNS Ping Utility for Linux: Version 11.2.0.1.0 - Production on 01-MAR-2012 05:10:46

 

Copyright (c) 1997, 2009, Oracle.  All rights reserved.

 

Used parameter files:

/u01/oracle/network/admin/sqlnet.ora

 

 

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.88)(PORT = 1521))) (CONNECT_DATA = (SERVER = POOLED) (SERVICE_NAME = wilson)))

OK (0 msec)

 

 

配置了wilsondrcp名稱之後,就可以使用sqlplus等工具進行連接。

 

 

[oracle@oracle11g ~]$ sqlplus /nolog

 

SQL*Plus: Release 11.2.0.1.0 Production on Thu Mar 1 05:11:47 2012

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

 

SQL> conn scott/tiger@wilsondrcp

Connected.

SQL> select sid from v$mystat where rownum<2;

       SID

----------

       146

 

 

 

此時,會話(sid=146)已經連接。此時,我們可以查看後臺進程情況。

 

 

--標記LOCAL的本地連接進程不存在;

[oracle@oracle11g ~]$ ps -ef | grep LOCAL

oracle    5963  5931  0 05:14 pts/1    00:00:00 grep LOCAL

 

 

那麼,我們連接的會話進程究竟是哪一個呢?

 

 

SQL> select paddr from v$session where sid=146;

PADDR

--------

38BCD994

 

SQL> select pid, spid from v$process where addr='38BCD994';

       PID SPID

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

        31 5806 OS Level的進程編號;

 

[oracle@oracle11g ~]$ ps -ef | grep 5806

oracle    5806     1  0 05:07 ?        00:00:00 ora_l002_wilson

oracle    5975  5931  0 05:15 pts/1    00:00:00 grep 5806

 

 

對應的ora_l002_wilson進程就是我們剛剛看到的連接池進程。說明:我們使用sqlplus連接使用的連接池對象是通過DRCP。

 

在sqlplus退出之後,l002進程依然存在,只是被釋放回連接池。

 

 

SQL> quit

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

 

[oracle@oracle11g ~]$ ps -ef | grep 5806

oracle    5806     1  0 05:07 ?        00:00:00 ora_l002_wilson

oracle    5981  5931  0 05:15 pts/1    00:00:00 grep 5806

[oracle@oracle11g ~]$

 

 

3、連接池關閉

 

DRCP連接池是可以關閉的,同樣使用dbms_connection_pool的stop_pool方法。

 

 

--關閉connection pool

SQL> exec dbms_connection_pool.stop_pool;

PL/SQL procedure successfully completed

 

[oracle@oracle11g ~]$ ps -ef | grep ora_n

oracle    5800     1  0 05:07 ?        00:00:00 ora_n000_wilson

oracle    6008  5931  0 05:18 pts/1    00:00:00 grep ora_n

[oracle@oracle11g ~]$ ps -ef | grep ora_l

oracle    5689     1  0 05:03 ?        00:00:00 ora_lgwr_wilson

oracle    6010  5931  0 05:18 pts/1    00:00:00 grep ora_l

 

 

關閉連接池後,連接池中連接lxxx立即被銷燬釋放。Connection Broker進程暫時存在。但是,過一會之後,該進程消失。

 

 

[oracle@oracle11g ~]$ ps -ef | grep ora_n

oracle    6027  5931  0 05:22 pts/1    00:00:00 grep ora_n

 

 

 

4、配置DRCP關鍵參數

 

在dba_cpool_info視圖中,我們可以查看到相應的參數信息。

 

 

SQL> desc dba_cpool_info;

Name                   Type          Nullable Default Comments                                                    

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

CONNECTION_POOL        VARCHAR2(128) Y                Connection pool name                                        

STATUS                 VARCHAR2(16)  Y                connection pool status                                       

MINSIZE                NUMBER        Y        Minimum number of connections                               

MAXSIZE                NUMBER        Y         Maximum number of connections                               

INCRSIZE               NUMBER        Y       Increment number of connections                             

SESSION_CACHED_CURSORS NUMBER        Y                Session cached cursors                                      

INACTIVITY_TIMEOUT     NUMBER        Y                Timeout for an idle session                                 

MAX_THINK_TIME         NUMBER    Y     Max time for client to start activity on an acquired session

MAX_USE_SESSION        NUMBER        Y    Maximum life of a session based on usage                    

MAX_LIFETIME_SESSION   NUMBER        Y     Maximum life of a session based on time                     

NUM_CBROK              NUMBER        Y                                                                            

MAXCONN_CBROK          NUMBER        Y                                                                            

 

 

在DRCP連接池中,最常用的幾個參數是minsize、maxsize和inactivity_timeout。

 

Minsize是說明DRCP連接池初始連接進程數量,如果請求數量超過這個minsize值,就會進行自動拓展。每次進行拓展的進程個數是incrsize參數。

 

Maxsize表示DRCP最大的拓展進程數量。當已經達到這個數量之後,DRCP連接池就不會獲取到連接,被hange住。

 

DRCP對應的應用需求是“短會話、高併發”的應用場景。所以DRCP服務的連接必然是短時間交互。Inactivity_timeout參數就是設置這個timeout值。如果會話連接到這個連接之後,超過一定時間沒有inactive交互,Oracle會自動將其斷開。Server Process被釋放回連接池。

 

配置connection pool,我們可以使用dbms_connection_pool方法configure_pool。

 

 

SQL> exec dbms_connection_pool.configure_pool(minsize => 1,maxsize =>3,incrsize => 1,inactivity_timeout =>60);

PL/SQL procedure successfully completed

 

 

SQL> select connection_pool, status, minsize, maxsize, INACTIVITY_TIMEOUT from dba_cpool_info;

CONNECTION_POOL        STATUS        MINSIZE    MAXSIZE INACTIVITY_TIMEOUT

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

SYS_DEFAULT_CONNECTION_POOL    INACTIVE         1          3                 60

 

--啓動連接池;

SQL> exec dbms_connection_pool.start_pool;

PL/SQL procedure successfully completed

 

 

--後臺進程情況;

[oracle@oracle11g ~]$ ps -ef | grep ora_n

oracle    6035     1  3 05:22 ?        00:00:00 ora_n000_wilson

oracle    6039  5931  0 05:23 pts/1    00:00:00 grep ora_n

[oracle@oracle11g ~]$ ps -ef | grep ora_l

oracle    5689     1  0 05:02 ?        00:00:00 ora_lgwr_wilson

oracle    6037     1  0 05:22 ?        00:00:00 ora_l000_wilson

oracle    6041  5931  0 05:23 pts/1    00:00:00 grep ora_l

 

 

5、maxsize值突破實驗

 

我們實驗一下,當突破maxsize值的時候,會出現什麼現象。我們啓用sqlplus連接。

 

 

--第一會話

SQL> conn scott/tiger@wilsondrcp 

Connected.

 

SQL> set time on;

05:23:45 SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

        14

 

--第二會話

SQL> conn scott/tiger@wilsondrcp

Connected.

 

SQL> set time on

05:24:26 SQL> select sid from v$mystat where rownum<2;

       SID

----------

        22

 

 

啓動了兩個連接,此時連接池進程情況如下:

 

 

[oracle@oracle11g ~]$ ps -ef | grep ora_l

oracle    5689     1  0 05:03 ?        00:00:00 ora_lgwr_wilson

oracle    6037     1  0 05:22 ?        00:00:00 ora_l000_wilson

oracle    6052     1  0 05:23 ?        00:00:00 ora_l001_wilson

oracle    6054     1  0 05:23 ?        00:00:00 ora_l002_wilson

oracle    6118  5931  0 05:24 pts/1    00:00:00 grep ora_l

 

 

拓展到三個連接進程。但是,此時如果我們進行第三個連接連入,就不允許了。

 

 

SQL*Plus: Release 11.2.0.1.0 Production on Thu Mar 1 05:25:16 2012

 

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

 

SQL> conn scott/tiger@wilsondrcp

(數據庫連接動作hange住)

 

 

這裏,我們需要注意一個細節:連接池中存在三個server process,但是爲什麼第三個連接不能連入。注意:在DRCP連接池中,Oracle是要保留一個連接作爲身份權限驗證等操作使用的。不能將其分配出去。Maxsize我們設置爲3,所以自然沒有連接。

 

第三個連接hange住一段時間後,自動連入。

 

 

Connected.

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

        14

 

 

第三個會話連入。此時第一個和第二個會話是被強制斷開。

 

 

--第一會話

05:24:37 SQL> select sid from v$mystat where rownum<2;

select sid from v$mystat where rownum<2

*

ERROR at line 1:

ORA-03113: end-of-file on communication channel

Process ID: 6052

Session ID: 14 Serial number: 5

 

--第二會話

05:24:47 SQL> select sid from v$mystat where rownum<2;

select sid from v$mystat where rownum<2

*

ERROR at line 1:

ORA-03113: end-of-file on communication channel

Process ID: 6054

Session ID: 22 Serial number: 17

 

 

 

此時,後臺進程狀態有釋放連接。

 

 

[oracle@oracle11g ~]$ ps -ef | grep ora_l

oracle    5689     1  0 05:03 ?        00:00:00 ora_lgwr_wilson

oracle    6037     1  0 05:22 ?        00:00:00 ora_l000_wilson

oracle    6052     1  0 05:23 ?        00:00:00 ora_l001_wilson

oracle    6202  5931  0 05:28 pts/1    00:00:00 grep ora_l

 

 

附帶,dbms_connection_pool的restore_defaults方法,可以將設置值置回。

 

 

SQL> exec dbms_connection_pool.stop_pool;

PL/SQL procedure successfully completed

 

SQL> select connection_pool, status, minsize, maxsize, INACTIVITY_TIMEOUT from dba_cpool_info;

CONNECTION_POOL                STATUS              MINSIZE    MAXSIZE INACTIVITY_TIMEOUT

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

SYS_DEFAULT_CONNECTION_POOL    INACTIVE                  1          3                 60

 

 

SQL> exec dbms_connection_pool.restore_defaults;

PL/SQL procedure successfully completed

 

SQL> select connection_pool, status, minsize, maxsize, INACTIVITY_TIMEOUT from dba_cpool_info;

CONNECTION_POOL                STATUS              MINSIZE    MAXSIZE INACTIVITY_TIMEOUT

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

SYS_DEFAULT_CONNECTION_POOL    INACTIVE                  4         40                300

 

 

 

6、結論

 

DRCP是Oracle 11g中的新特性。藉助DRCP,一些高併發、短會話應用可以獲得數據庫層面的高效連接池。筆者猜測Shared Server模式就是DRCP的一種早期雛形。在現代企業級應用系統中,連接池是中間件的一個重要組件。當一些應用,如PHP不能提供有效連接池的時候,DRCP也許是不錯的選擇。


轉載自:

http://blog.itpub.net/17203031/viewspace-717634/

http://blog.itpub.net/17203031/viewspace-717754/

http://blog.itpub.net/17203031/viewspace-717887/

感謝原作者!

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