经常用oracle的人对下面的这条信息肯定不会陌生:“监听程序当前无法识别链接描述符中请求的服务”。其实产生这个问题的根本原因不是监听没有起来,而是监听没有监听你要连接的oracle实例。
大家都明白,oracle只有两者兼备才能向外界提供服务:一个是监听,用于接收用户的请求;一个是实例,真正的提供服务的。但是这两者要协调好才能工作,即实例要告诉监听我准备好了,可以接受外界的服务了。
这里面有个主动和被动的问题,当主动监听时,监听认为实例永远都是准备好的,外界对实例的请求监听都接受,哪怕实例还关着呢。被动就是实例起来后由PMON来向监听注册,告诉监听我准备好了,可以接收外界请求了。
谈到这里,就要说说启动顺序的问题了,在两者同时启动的情况下察觉不到问题,但是当两者不是同时启动情况下有问题了,但这只是个小问题:在等待“很小的一段时间”后问题会自己解决的。
先启动监听,后启动实例,当从远程客户端连接实例时没有问题,根本察觉不到,因为在启动实例是PMON已经向监听注册实例了,当用户请求时,两者都准备好,没问题。
先启动实例,后启动监听,此时会有问题,但是只是个“很小的一段时间”的问题。如果监听刚起来,用户马上就请求连接,这时可能会报“监听程序当前无法识别链接描述符中请求的服务”的错误,原因在于PMON还没来得及向监听注册实例。但是等一会为什么就好了呢?因为PMON是轮循的,它每隔一段时间向监听注册实例,只要监听起来了,当PMON注册时就能注册成功,此时用户在请求就没问题了,但是这个“很小的一段时间”可能不一样,但是可以肯定不会很长。
那有没有办法解决这点很短时间的问题呢?有 。这就是变被动监听为主动监听。将实例的描述添加到listener.ora中,这样只要启动监听,就能监听实例,而不管实例的状态如何,只要两者都准备好,OK就没问题。
下面给出例子:(改前)
- SID_LIST_LISTENER =
- (SID_LIST =
- (SID_DESC =
- (SID_NAME = PLSExtProc)
- (ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
- (PROGRAM = extproc)
- )
- )
- LISTENER =
- (DESCRIPTION_LIST =
- (DESCRIPTION =
- (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
- (ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))
- )
- )
改后:
- SID_LIST_LISTENER =
- (SID_LIST =
- (SID_DESC =
- (SID_NAME = PLSExtProc)
- (ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
- (PROGRAM = extproc)
- )
- (SID_DESC =
- (GLOBAL_DBNAME = orcl)
- (ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
- (SID_NAME = orcl)
- )
- )
- LISTENER =
- (DESCRIPTION_LIST =
- (DESCRIPTION =
- (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
- (ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))
- )
- )