Service Name是什么
自从Oracle 8i之后,Oracle就推荐使用service name而不是SID来连接数据库了,SID是数据库的唯一的名字,要连接使用SID连接同一个数据库的话就只能用这一个名字,别无他法。service name是连接数据库的时候使用的别名,你可以在listener.ora中静态的设置好service name,启动listener之后这个service name会被注册到listener,然后就可以使用service name替代SID来连接数据库了。使用service name有以下几个好处:
- SID有长度的限制,只能允许最长8个字符,而service name最长可达到255字节(oerr ORA 12169里面说的),还可以自己取名字,所以完全可以取一个易于读懂的service name,比SID方便多了,比如下面这个。
$ lsnrctl status
Listening Endpoints Summary ...
( DESCRIPTION = ( ADDRESS = ( PROTOCOL = tcp )( HOST = orainst . desktop . mycompany . com )( PORT = 1521 )))
Services Summary ...
Service " this-is-a-very-looong-name-of-mysite.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
The command completed successfully
- 要改SID是一件很难的事情,而修改service name的话就简单多了,这就使得我们可以非常简单的在不修改客户端应用的情况下将应用从一个数据库切换到另外一个数据库上面去。
- 可以将多个service name指向同一个数据库,这样我们可以通过不同的service name来去不同功能的客户端应用,比如说sales应用使用sales.mycompany的service name,purchase应用则使用purchase.mycompany这样的service name。
Service Name的动态注册
在我们安装好一个新的Oracle数据库之后,然后listener.ora什么设置都没做,接着启动数据库,再跑一下lsnrctl start命令,然后再看一下listener的状态,你会惊讶的发现里面已经数据库已经能连接上了,就像下面的listener状态一样:
oracle @ orainst [ orcl ]:~
$ lsnrctl status
LSNRCTL for Linux : Version 10.2.0.2.0 - Production on 13 - AUG - 2009 09 : 16 : 04
Copyright ( c ) 1991 , 2005 , Oracle . All rights reserved .
Connecting to ( ADDRESS = ( PROTOCOL = tcp )( HOST = )( PORT = 1521 ))
STATUS of the LISTENER
---------------------- --
Alias LISTENER
Version TNSLSNR for Linux : Version 10.2.0.2.0 - Production
Start Date 13 - AUG - 2009 08 : 34 : 10
Uptime 0 days 0 hr . 41 min . 53 sec
Trace Level off
Security ON : Local OS Authentication
SNMP OFF
Listener Parameter File / oracle / 10.2.0.2 / network / admin / listener . ora
Listener Log File / oracle / 10.2.0.2 / network / log / listener . log
Listening Endpoints Summary ...
( DESCRIPTION = ( ADDRESS = ( PROTOCOL = tcp )( HOST = orainst . desktop . mycompany . com )( PORT = 1521 )))
Services Summary ...
Service " orcl.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
Service " orcl2.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
Service " orcl_XPT.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
The command completed successfully
这就是Oracle的listener动态注册在起作用了,为了简化数据库的管理工作,Oracle提供了动态注册的功能,默认的情况下PMON进程会将service_names注册到hostname:1521上,注册的结果当然我们不用做任何的listener的设置就可以开始使用数据库了。
上面说的service_names值得是初始化参数,动态注册的时候service name是从这里来的,service_names在安装完了之后默认值是.,如果设置为空动态注册的时候也会使用这个值。要设置多个service name的话只需要在再设置的时候用逗号分隔开多个名字就行了,我现在的service_names设置如下:
SYS @ orcl > show parameter service_names
NAME TYPE VALUE
---------------------------------- -- ----------- ------------------------------
service_names string orcl . mycompany , orcl1 . mycompany
现在问题来了,为什么上面只设置了2个service name而看listener状态的时候却能看到3个呢,那个orcl_XPT.mycompany是怎么来的?答案是PMON进程“私自”加上去的,实际上Oracle listener会注册的service一共有3种,第一种是在listener.ora的中设定的,这个被称为静态注册的service name;第二种是在系统初始化参数service_names中设置的,可以使多个;第三种是Oracle系统进程注册上去的,某些系统进程会注册一个特别的service name到listener上,用于进程之间相互的通讯之用,比如上面的orcl_XPT.mycompany。
另外一个需要说明的是PMON进程会定时的和listener进行交流,以随时将最近的service_names的更新注册到listener中去,但是这个是定时而不是随时,通常有60s的间隔,对于有些情况下有可能是无法接受的,所以Oracle提供了一个命令ALTER SYSTEM REGISTER来完成这件事,执行这个命令之后PMON进程会立马启动service name的注册过程。还有一个是动态注册的service name在lsnrctl status的结果里面显示的状态是“status READY”,而静态注册的service name显示的是“status UNKNOWN”。
如果数据库在使用的时候不使用默认的端口那还会动态注册么?答案是不会,如果你在listener.ora中配置了不适用默认的端口,Oracle将不能再动态的注册service name,只能注册listener.ora中配置的service name。除非你告诉系统你listener在那里监听,这就要靠初始化参数local_listener了,下面我们来做个测试:
先设置下我们的listener.ora,这是的端口不是默认的1521,而是8888。
LISTENER =
( DESCRIPTION_LIST =
( DESCRIPTION =
( ADDRESS = ( PROTOCOL = TCP )( HOST = orainst . desktop . mycompany . com )( PORT = 8888 ))
)
)
然后启动listener,再接着跑一下ALTER SYSTEM REGISTER,再看listener的service
oracle @ orainst [ orcl ]:~
$ lsnrctl service
LSNRCTL for Linux : Version 10.2.0.2.0 - Production on 13 - AUG - 2009 10 : 01 : 02
Copyright ( c ) 1991 , 2005 , Oracle . All rights reserved .
Connecting to ( DESCRIPTION = ( ADDRESS = ( PROTOCOL = TCP )( HOST = orainst . desktop . mycompany . com )( PORT = 8888 )))
The listener supports no services
The command completed successfully
很明白的告诉你“The listener supports no services”,接下来该local_listener出场了
-- 当前没有local_listener的设置
SYS @ orcl > show parameter local_list
NAME TYPE VALUE
---------------------------------- -- ----------- ------------------------------
local_listener string
-- 现在加上,和listener.ora中的设置一样
SYS @ orcl > alter system set local_listener = ' (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=orainst.desktop.mycompany.com)(PORT=8888))) ' ;
System altered .
-- 赶紧让PMON注册去
SYS @ orcl > ALTER SYSTEM REGISTER ;
System altered .
这时候再看listener的service,出来了吧
oracle @ orainst [ orcl ]:~
$ lsnrctl service
LSNRCTL for Linux : Version 10.2.0.2.0 - Production on 13 - AUG - 2009 10 : 03 : 08
Copyright ( c ) 1991 , 2005 , Oracle . All rights reserved .
Connecting to ( DESCRIPTION = ( ADDRESS = ( PROTOCOL = TCP )( HOST = orainst . desktop . mycompany . com )( PORT = 8888 )))
Services Summary ...
Service " orcl.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
Handler ( s ) :
" DEDICATED " established : 0 refused : 0 state : ready
LOCAL SERVER
Service " orcl1.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
Handler ( s ) :
" DEDICATED " established : 0 refused : 0 state : ready
LOCAL SERVER
Service " orcl_XPT.mycompany " has 1 instance ( s ) .
Instance " orcl " , status READY , has 1 handler ( s ) for this service ...
Handler ( s ) :
" DEDICATED " established : 0 refused : 0 state : ready
LOCAL SERVER
The command completed successfully
几个常见的Oracle动态注册service name
_XPT.
这个service name由PMON进程注册,用于在Dataguard中Log Transport Services以及 FAL使用, 当在DG环境中使用了DG Broker之后,DG Borker会自动修改DG的log_archive_dest_n参数,在其中写死Standby的name methods,并且将service name固定为_XPT.。
如果动态注册的条件成立的话不管你用不用DG Broker,你都会看到这个service name,还不能通过一般的方法去掉它。好在Oracle提供了一个隐藏的初始化参数来处理这个,只要设置__dg_broker_service_names=”然后重启下数据库,这个该死的service name就不再出现了。
_DGB .
_DGB .这个service name是有Dataguard Broker Monitoring(DMON)进程注册的,用于同一个Broker配置中的各个数据库之间DMON进程的通讯,只有在启用了DMON进程之后才会动态的注册这个service name,在DMON的DRC.LOG 中我们可以看到DMON注册service name的过程。
DG 2009 - 08 - 10 - 06 : 35 : 06 0 2 0 DMON : >> Starting Data Guard Broker bootstrap <<
DG 2009 - 08 - 10 - 06 : 35 : 06 0 2 0 DMON : Attach state object
DG 2009 - 08 - 10 - 06 : 35 : 06 0 2 0 DMON : chief lock convert for bootstrap
DG 2009 - 08 - 10 - 06 : 35 : 06 0 2 0 DMON Registering service orcl_p_DGB with listener ( s )
DG 2009 - 08 - 10 - 06 : 35 : 06 0 2 0 Executing SQL [ ALTER SYSTEM REGISTER ]
DG 2009 - 08 - 10 - 06 : 35 : 06 0 2 0 SQL [ ALTER SYSTEM REGISTER ] Executed successfully
参考资料
- Oracle Database Net Services Administrator’s Guide
- Oracle Data Guard Broker
- Metalink Doc ID: 339940.1
- Metalink Doc ID: 745201.1