同事反馈他连接一个新搭建的测试数据库时,报“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)需要如何修改。
注意: 下面所谓正确、错误配置,仅仅指服务器配置不改动的情况下,正确配置仅仅指客户端这种配置方式不会报错。而错误配置仅仅指这种配置方式报错。