同事反饋他連接一個新搭建的測試數據庫時,報“ORA-12520: TNS: 監聽程序無法為請求的服務器類型找到可用的處理程序”錯誤,在解決他這個問題時,順便分析、總結一下ORA-12520錯誤。下面重現一下這個場景:
Oracle Client段的tnsnames.ora的配置如下:
MY_TEST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.10.5.37)(PORT=49161))
(CONNECT_DATA=
(SERVER = SHARED)
(SERVICE_NAME = XE)
)
)
客戶端SQL*PLUS訪問數據庫報錯:
C:\Users>sqlplus test/test123456@MY_TEST
SQL*Plus: Release 11.2.0.1.0 Production on 星期二 1月 8 23:30:47 2019
Copyright (c) 1982, 2010, Oracle. All rights reserved.
ERROR:
ORA-12520: TNS: 監聽程序無法為請求的服務器類型找到可用的處理程序
請輸入用戶名:
請輸入用戶名:
在服務器檢查是否開啟了shared server模式(注意,如果配置正確,但是沒有開啟共享服務器模式,也會報這個錯誤)
SQL> show parameter shared_servers
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
max_shared_servers integer 10
shared_servers integer 10
SQL>
在服務器檢查SERVICE_NAME的信息:
SQL> show parameter service_name;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string XE
SQL> !
oracle@3c939f31e44b:~$ lsnrctl services
LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 08-JAN-2019 15:33:45
Copyright (c) 1991, 2005, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0
LOCAL SERVER
Service "XE" has 1 instance(s).
Instance "XE", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:102 refused:0 state:ready
LOCAL SERVER
Service "XEXDB" has 1 instance(s).
Instance "XE", status READY, has 1 handler(s) for this service...
Handler(s):
"D000" established:4 refused:0 current:0 max:1022 state:ready
DISPATCHER <machine: 3c939f31e44b, pid: 5980>
(ADDRESS=(PROTOCOL=tcp)(HOST=3c939f31e44b)(PORT=41385))
Service "XE_XPT" has 1 instance(s).
Instance "XE", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:102 refused:0 state:ready
LOCAL SERVER
The command completed successfully
我們知道如果共享服務器模式連接數據庫,是需要通過DISPATCHER的,那么要看看參數dispatchers是如何配置的。如下所示,dispatchers里面設置的是SERVIE_NAME為XEXDB,不是XE,難怪會出這個錯誤。
那么我們修改一下DISPATCHERS參數配置,將SERVICE_NAME改為XE:
SQL> show parameter dispatcher;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
dispatchers string (PROTOCOL=TCP) (SERVICE=XEXDB)
max_dispatchers integer
SQL> ALTER SYSTEM SET DISPATCHERS ='(PROTOCOL=TCP) (SERVICE=XE)';
System altered.
SQL> show parameter dispatcher;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
dispatchers string (PROTOCOL=TCP) (SERVICE=XE)
max_dispatchers integer
SQL>
OK,如下所示,問題解決。此時客戶端可以順利訪問數據庫了。
說到這里,那么我們就不得不說一下SERVICE_NAME,服務名(SERVICE_NAME):指listener提供的對外的服務名,客戶端可以通過配置tnsnmaes.ora連進行連接,tnsnmaes.ora文件中的service_name要等於服務器端listener所注冊的服務名,服務名可以通過輸入lsnrctl后,在輸入service查看,一般的service_name在listener.ora文件中配置(靜態注冊),或者當沒有listener.ora文件時,在初始化文件中配置instance_name和service_names這2個參數進行動態注冊。但是無論采用那種注冊方式,都可以通過lsnrctl-sevice來檢查。上面案例中,配置都沒有錯,而是在於共享連接的分派器(DISPATCHER)的設置問題,因為共享連接的分派器(DISPATCHER)指定SERVICE_NAME為XEXDB,那么客戶端訪問數據庫使用服務名XE的話,就只能使用專用連接服務器模式。
另外,我們看看如果數據庫實例配置不改動的情況下,需要如何修改客戶端的tnsnames.ora的條目(entry)需要如何修改。
注意: 下面所謂正確、錯誤配置,僅僅指服務器配置不改動的情況下,正確配置僅僅指客戶端這種配置方式不會報錯。而錯誤配置僅僅指這種配置方式報錯。
我們先復原數據庫實例的配置,如下所示,然后測試一下其它
錯誤的配置:
MY_TEST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.10.5.37)(PORT=49161))
(CONNECT_DATA=
(SERVER = SHARED)
(SERVICE_NAME = XE)
)
)
正確的配置
1:不指定共享連接服務器模式,那么默認使用專用連接服務器模式,那么也沒有問題。
MY_TEST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.10.5.37)(PORT=49161))
(CONNECT_DATA=
(SERVICE_NAME = XE)
)
2:使用專用連接服務器模式訪問數據庫
MY_TEST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.10.5.37)(PORT=49161))
(CONNECT_DATA=
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
3:將SERVICE_NAME改為XEXDB,也可以解決問題。
MY_TEST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.10.5.37)(PORT=49161))
(CONNECT_DATA=
(SERVER = SHARED)
(SERVICE_NAME = XEXDB)
)
)
)
4:將SERVICE_NAME改為改為ISD,也可以解決問題。
MY_TEST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.10.5.37)(PORT=49161))
(CONNECT_DATA=
(SERVER = DEDICATED)
(SID = XE)
)
)
另外,這個問題問題,我們稍微展開下,其實我們清楚,在下面情況下會關閉數據庫實例的共享服務連接,
1 設置SHARED_SERVERS=0;
2 關閉DISPATCH進程
ALTER SYSTEM SET DISPATCHERS = '';
設置SHARED_SERVERS=0
如下所示,SHARED_SERVERS=0的情況下:
客戶端訪問數據庫也會報ORA-12520錯誤
C:\Users>sqlplus test/test123456@MY_TEST
SQL*Plus: Release 11.2.0.1.0 Production on 星期四 1月 10 22:55:18 2019
Copyright (c) 1982, 2010, Oracle. All rights reserved.
ERROR:
ORA-12520: TNS: 監聽程序無法為請求的服務器類型找到可用的處理程序
請輸入用戶名:
關閉DISPATCH進程
SQL> alter system set shared_servers=10 scope=both;
System altered.
#此時,客戶端訪問數據庫正常
SQL> ALTER SYSTEM SET DISPATCHERS = '';
System altered.
SQL>
#此時,客戶端訪問數據庫報ORA-12520錯誤。
另外,需要注意的是在共享服務器模式下,local naming,tnsnames.ora也可以配置成專用模式,需要注意的是如果使用參數DEDICATED,ORACLE將單獨派生進程進行客戶端處理,也就是專用模式。其實如果你看懂了上面案例,那么我們再來看看官方文檔對ORA-12520的描述,是否有茅塞頓開的感覺呢!
ORA-12520: Listener Could Not Find Available Handler for Requested Type of Server
This message indicates that the type of service handler requested by the client is incorrect or not registered for the requested SERVICE_NAME/INSTANCE_NAME parameters, or the database instance is not registered with the listener.
If you suspect the problem is the wrong type of service handler, then perform the following steps:
If (server=value) is set in the connect descriptor, then ensure that the value is set to the appropriate service handler type for the database, that is, dedicated for dedicated server or shared for dispatchers. You can use the Listener Control utility SERVICES command to see what service handlers are currently registered with the listener.
If the USE_DEDICATED_SERVER parameter is set to ON in the sqlnet.ora file, then ensure the database is configured to use dedicated servers. If it is not, then set this parameter to OFF.
Ensure that the database instance is running. If the instance not running, then start it so that it can register with the listener.
另外,如果運行正常的數據庫服務器,突然報ORA-12520錯誤,一般是因為process不夠引起的。需要增大processes參數的值。網上有許多資料,這里不做展開!在此略過。
|
|