一、簡介
MTS(Multi-Threaded Server)是ORACLE SERVER的一個可選的配置選擇,是相對DEDICATE方式而言,它最大的優點是在以不用增加物理資源(內存)的前提下支持更多的并發的連接。換句話說,如果你只有2G的物理內存,而你又想支持2000個連接,在獲取最好性能的前提下,你就應該選擇MTS了。
本文先說一說MTS的工作方式,然后與DEDICATE方式的做一下比較,接下來說一下MTS具體配置實現,最后說一些優化MTS配置選項的問題。
二、MTS的工作方式
1、Joseph C.Johnson以餐館給出一個MTS的形象的比喻
假設ORACLE是一家餐館,當你走進一家餐館時你感覺最舒服的服務方式就是有一個專門的waiter來為你服務,而不管餐館中來了多少人,她只對你請求應答,這是DEDICTE的處理方式,也就是說每一個ORACLE客戶端的連接都有一個專門的服務進程來為它服務。而大部的餐館的服方式都不是一對一的,當你走進的時侯,你就被指定了一個waiter,她也可能為其它桌服著務,這對于餐館來說是最有利的,因為他們可以服務更多的客人而不需要增加他們的員工。這樣對你來說也可能是不錯的,如果餐館不是太忙,她服務的客人的請求都很簡短且容易完成,你的感覺也好像自己擁有一個專門的waiter,waiter把你的ORDER轉給廚師,然后把做好的菜拿給你,這就是MTS的處理方式,這些共享的waiters我們叫她們為Dispatchers,廚師我們則叫他們為Shared Server Processes。
2、以簡圖說一下MTS的工作方式(SYBEX書中的一幅圖)

1)客戶端向Dispatcher發一個服務請求
2)Dispatch把這個請求放到SGA區的請求對隊列中
3)由一個或幾個服務進程來處理這個請求
4)服務進程把進行的結果放到Dispatch的SGA區的的響應隊列中
5)Dispatcher從響應隊列拾起結果
6)完成客戶端的請求并把結果回送給客戶端
三、MTS與DEDICATE方式方面做一下比較,為方便比較繪制如下的簡表
序號
|
比較項
|
MTS
方式
|
DEDICATE
方式
|
1
|
服務進程
|
多個連接共享一個服務進程
|
一個連接有一個專門的服務進程
|
2
|
每個客戶端的連接使用的內存量
|
3-4M
|
150-200K
|
3
|
適合的應用環境
|
適合連接數很多且請求很短少的
OLTP
環境
|
如果
Oracle
服務器的資源夠用,這種方式是優選
|
4
|
CPU
負載
|
會造成一些
CPU
的負載,如果你的
CPU
有瓶頸,則不要用這種方式
|
?
|
四、? MTS的配置實現
1、? Oracle8i MTS環境常用到的幾個參數
序號
|
參數
|
說明
|
1
|
mts_dispatchers
|
用于配置當
Instance
啟動的時侯啟用的
Dispatcher
的數量、及
Dispatcher
所響應的協議,它是一個動態的參數,可以用
Alter system
進行動態修定,它沒有默認值。
|
2
|
mts_max_dispatchers
|
用于指定同時運行的
Dispatcher
進程的最大數量,對于大部分的應用,每
250
個連接啟用一個
Dispatcher
可以獲得較好的性能。默認值是
5
或所配置的
Dispatcher
的數量
|
3
|
mts_servers
|
用于指定當
Instance
啟動時你想啟用的服務進程的數量,它是一個動態參數,可以用
Alter systme
動態修定。
|
4
|
mts_max_servers
|
用于指定同時進行的共享的庫的服務進程的數量,如果你的系統經常出現死鎖,應該適當的增加這個值。
|
5
|
mts_service
|
設為
SID
|
6
|
mts_listener_address
|
TNS
監聽的地址
|
2、? Oracle9i MTS環境常用到的幾個參數
序號 | 參數 | 說明 |
1 | Dispatchers | 等同于8i中的mts_dispatchers參數 |
2 | max_dispatchers | 等同于8i中的mts_max_dispatchers參數 |
3 | shared_servers | 等同于8i中的mts_server參數 |
4 | max_shared_servers | 等同于8i中的mts_max_servers參數 |
3、? 以我一個實際環境(Oracle8.1.7.4)舉個例子,9i類似,我在Init<SID>這個初始化參數文件中加入了如下的MTS的參數,完成了MTS的配置。
#mts set by qiuyb
mts_dispatchers="(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.223.125))(DISPATCHERS=10)"
mts_max_dispatchers=20
mts_servers=10
mts_max_servers=50
mts_service=BILLING
mts_listener_address="(address=(protocol=tcp)(host=192.168.223.125)(port=1521))" large_pool_size=400M
#end of qiuyb's set?
需要說明的是large_pool_size這個初始化參數,在MTS環境中為獲取更好的性能建議設置這個參數,這樣UGA都從large_pool這樣一個固定的區域中進行分配,而不用從Shared Pool中動態進行分配,這樣也可以減少ORA-04031錯誤的發生。
五、 優化MTS配置選項及你可能問的幾個問題
1、? large_pool_size這個參數我該設為多大呢?
當large_pool_size的大小能夠滿足所有的共享服務進程所需的內存就可以了,當然如果內存夠用的話可以適當的加大一點,如下的語句便可以得出自實例啟動來MTS連接所用的內存的最大數量,可以看出來是200多M。
?
SELECT?sum(value)?"Max?MTS?Memory?Allocated"
FROM?v$sesstat??ss,?v$statname?st?
WHERE?name?=?'session?uga?memory?max'
AND?ss.statistic#=st.statistic#
Max MTS Memory Allocated
------------------------
214457296
2、? 如何判斷我dispatcher的數量是不是夠用呢?
使用如下的語句,當dispatcher的繁忙比率超過50%的時侯,你就要考慮增加Dispatcher的數量了,用Alter system動態卻可完成。
SELECT?name,?(busy?/?(busy?+?idle))*100?"Dispatcher?%?busy?Rate"
FROM?V$DISPATCHER
3、? 如何判斷共享服務進程是不是夠用呢?
使用如下的語句來確定每次請求的平均等待時間,監測Average Wait time per reques這個值,當這個值持續增長時你該考慮增加shared servers了。
SELECT?decode(totalq,0,'No?Requests')?"Wait?Time",
???????Wait/totalq?||'hundredths?of?seconds'?"Average?Wait?time?per?request"
FROM?V$QUEUE
WHERE?type?=?'COMMON'
4、? 如何在MTS配置的Server請求Dedicate的連接著?
你在tnsnames.ora中做服務名配置時加入SRVR=DEDICATED這個選項就可以了,示例如下:
billing =
(DESCRIPTION =
? (
?? ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = ks3)(PORT = 1521))
? )
? (
?? CONNECT_DATA =
??? (SERVICE_NAME = billing)
??? (SRVR = DEDICATED)
? )
)
六、 結文
在你的Oracle的服務器出現高的內存利用率和出現頻繁換頁時,使用MTS是一個不錯的選擇。總體上說來,MTS較適合OLTP這種類型的應用,對于那些數據倉庫、DDS這些類型的應用它則是不適合的。
繼續說一說Oracle的MTS
1、在Oracle Server調整為MTS方式后,一些客戶端出現了連不上Oracle Server的狀況,大部分報的錯為TNS-12509,如何解決?
回答:
在實際過程中是存在著這方面的情況,我總結了一下,大部是由Oracle8 的client引起的,就是那些配服務名還得掛著個.world的那種客戶端,其實解決起來很簡單,只需要把tnsname.ora這個文件中你的那個服務名配置的"sid="改成"service_name=",這就Ok了。
2、我使用了成都邁普公司的"隧道網關"這種產品,以前在dedicated方式是好好的,可是改成MTS后,為什么Client死活連不是Oracle的Server呢?
回答:
其實我們公司也用了這種產品,在MTS應用之初也遇到了這個問題。出現這個問題的原因為邁普的這種產品只為監測靜態的端返回,它認為Oracle的監聽端口即為返回端口,實際在MTS中不是這樣的,多進行幾次連接,用netstat -n在客戶端觀看一下就會明白,MTS返回的端口是動態的,所以邁普的這個產品就不好用了。解燃眉之急的辦法可以這樣:在MTS客戶端配置"服務名"時,請求個Dedicate的連接,即使用SERVER = DEDICATED選項,這就把問題解決了。
3、如何跟蹤一下MTS的dispatcher和shared server進程?
回答:
這需用到診斷事件了,dispatcher的診斷事件號為10248,shared server的為10249,如下以shared server為例簡單說一下,假定s015的操作系統的進程號為13161.
sql>conn sys/pass as sysdba
sql>oradebug setospid 13161?
sql>oradebug TRACEFILE_NAME?? --看一下跟蹤文件的名稱
sql>oradebug EVENT 10249 trace name context forever, level 10
也可以在init<SID>.ora中加入如下兩行完成trace:
event="10248 trace name context forever, level X"? -- dispatchers
event="10249 trace name context forever, level X"? -- shared servers
4、如何在MTS中設置IPC
回答:
LISTENER.ORA:
=============
?
LISTENER=
? (ADDRESS_LIST=
???? (ADDRESS=
??????? (PROTOCOL=IPC)
??????? (KEY=<sid name>)
???? )
???? (ADDRESS=
??????? (PROTOCOL=IPC)
??????? (KEY=<alias in tnsnames.ora for the sid>)
???? )
? )
CONNECT_TIMEOUT_LISTENER=10
STARTUP_WAIT_TIME_LISTENER=0
SID_LIST_LISTENER=
? (SID_LIST=
??? (SID_DESC=
????? (SID_NAME=<sid name>)?
????? (ORACLE_HOME=<home directory path for Oracle>)
??? )
? )
?
地址列表中可以使用其它的協議,加入應的地址。這個例子完全是一個IPC的例子
?
TNSNAMES.ORA:
=============
?
<alias>=
? (DESCRIPTION=
???? (ADDRESS=
??????? (PROTOCOL=IPC)
??????? (KEY=<sid name>)
???? )
???? (CONNECT_DATA=
??????? (SID=<sid name>)
???? )
? )
?
?
INIT.ORA entries for MTS:
=========================
?
MTS_DISPATCHERS="IPC,2"
MTS_SERVERS=1
MTS_MAX_DISPATCHERS=6
MTS_MAX_SERVERS=3
MTS_SERVICE=<sid name>
MTS_LISTENER_ADDRESS="(ADDRESS=(PROTOCOL=IPC)(KEY=<sid name>))"
5、如何查看一下某個shared_server正在忙什么?
回答:
其實這與Dedicated方式的查看方法是一樣的,還以s015為例,它的spid為13161,使用如下的sql便可查出:
SELECT?a.username,
???????a.machine,
???????a.program,
???????a.sid,
???????a.serial#,
???????a.status,
???????c.piece,
???????c.sql_text
??FROM?v$session?a,
???????v$process?b,
???????v$sqltext?c
?WHERE?b.spid=13161
???AND?b.addr=a.paddr
???AND?a.sql_address=c.address(+)
?ORDER?BY?c.piece
6、我在unix看到一個shared server的進程占用了大量的CPU資源,通過select addr from v$process where spid=<os process pid>查到進程的address,而select * from v$session where paddr=<paddr>確沒的結果,所以我無法得知我的這個shared server在忙什么,我該怎么辦呢?
回答:
SELECT?status?FROM?v$circuit?
?WHERE?CIRCUIT?IN?
??(
???SELECT?circuit?FROM?v$shared_server?
????WHERE?paddr=<your?paddr>
??)
如果status的返回是EOF,說明實際這個shared server已經掉死了,你可以把它在操作系統上清除掉了:
eg:
? oracle$kill -9 <shared server's pid>
你不用擔心kill掉會有什么大的影響,其它幾分鐘之后,pmon會為你把這個shared server進程給重新啟動的。
7、如何在非down庫的情況下恢復到Dedicate的連接方式,及啟用更多的dispatcher?
回答:
7.1關掉:
? sql>ALTER SYSTEM SET MTS_DISPATCHERS='TCP,0';
7.2啟用更多的dispatcher
? sql>ALTER SYSTEM SET MTS_DISPATCHERS='TCP,40';
本文轉載自CSDN上hrb_qiuyb的三篇文章
說一說如何配置Oracle的MTS Part1
說一說如何配置Oracle的MTS part2
繼續說一說Oracle的MTS