天天看点

oracle监听 动态注册与静态注册

看了这篇文章对 动态注册和静态注册又有了进一步的了解,转发过来学习;来自:http://blog.163.com/[email protected]/blog/static/1646245052010524101149835/

首先说说最近自己遇到的一个问题,应该说以前也遇到过,只不过在网上查找了一下解决方法,能够解决,但是不知道原理是什么;

"正在连接...ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务"  这个错误,其实现在一般用的都是动态监听,不管监听和oracle服务哪一个先启动,有时候需要等一分钟,由pmon检查到之后动态注册,但是能够注册是没问题的;今天我遇到的就是一直出现这个错误;到后来知道其实监听和tns配置都没有问题,问题出在了spfile中service_names 和 instance_name 上,因为下面这篇文章会讲到,动态注册的话会读取init.ora里的这两个变量,如果用spfile启动,那么需要先创建一个pfile,然后看看*.DB_UNIQUE_NAME 和db_name ,这里的db_unique_name 就是用网络配置助手配置tns时的“服务名”; 其实这里也不用这么麻烦,直接用呢lsnrctl  status  能够看到:

LSNRCTL> status

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.217.130)(PORT=1521)))

LISTENER 的 STATUS

------------------------

别名                      LISTENER

版本                      TNSLSNR for 32-bit Windows: Version 11.2.0.1.0 - Production

启动日期                  03-9月 -2013 14:50:27

正常运行时间              0 天 0 小时 2 分 7 秒

跟踪级别                  off

安全性                    ON: Local OS Authentication

SNMP                      OFF

监听程序参数文件          E:\app\xuniji\product\11.2.0\dbhome_1\network\admin\listener.ora

监听程序日志文件          e:\app\xuniji\diag\tnslsnr\xunijida-59c75f\listener\alert\log.xml

监听端点概要...

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.217.130)(PORT=1521)))

  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))

服务摘要..

服务 "CLRExtProc" 包含 1 个实例。

  实例 "CLRExtProc", 状态 UNKNOWN, 包含此服务的 2 个处理程序...

服务 "orclXDB" 包含 1 个实例。

  实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...

服务 "standby" 包含 1 个实例。

  实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...

命令执行成功

蓝色部分,很多时候服务和实例都是一样的名称,只不过这里不一样,所以再创建tns时的服务名应该是standby;

一、什么是注册:

注册就是将数据库作为一个服务注册到监听程序中。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请链接到数据库。这个服务名可以与数据库名一样,也有可能不一样。

在数据库服务启动的过程中,数据库服务器会像监听程序注册相应的服务,无论何时启动数据库,默认的都有两条信息注册到监听器中,数据库服务器对应的实例和服务,客户端和服务器之间的链接,只需要提供一个服务名就可以了。

二、区分动态注册和静态注册

(1)使用listener.ora文件判断

动态注册

SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (PROGRAM = extproc)

      (SID_NAME = PLSExtProc)

      (ORACLE_HOME = D:\oradata\orcl)

    )

  )

静态注册

SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (PROGRAM = extproc)

      (SID_NAME = PLSExtProc)

      (ORACLE_HOME = D:\oradata\orcl)

    )

    (SID_DESC =

      (GLOBAL_DBNAME = orcl)

      (ORACLE_HOME = D:\oradata\orcl)

      (SID_NAME = ORCL)

    )

    (SID_DESC =

      (GLOBAL_DBNAME = orcl1)

      (ORACLE_HOME = D:\oradata\orcl)

      (SID_NAME = ORCL)

    )

  )

通过查看虽然可以大致看出,但是这种方法并不能和明确的现实数据库在运行时的实际情况

(2)使用lsnrctl status命令

三、动态注册

动态注册是在instance启动的时候PMON(Process Monitor进程监视器)进程根据INIT.ORA中的instance_name,service_name两个参数将实例和服务注册到监听器中.

动态注册时的listener.ora的文件内容如下

SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (PROGRAM = extproc)

      (SID_NAME = PLSExtProc)

      (ORACLE_HOME = D:\oradata\orcl)

    )

  )

由于动态注册需要pmon进程,所以监听必须在数据库启动之前启动,否则动态注册将失败;在数据库运行的过程中,如果重启监听也会造成动态注册失败

动态注册只是注册默认的监听器上(名称是listener、端口是1521、协议时TCP),如果需要向非默认的监听注册,则需要改变local_listener参数

将监听的信息添加到tnsnames.ora  文件中。 注意,是tnsnames.ora 文件, 因为pmon在动态注册监听时要从tnsnames.ora中读取相关信息。

LISTENER =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = DaveDai)(PORT = 1522))

)

 然后以sys用戶运行:

SQL> alter system set local_listener=listener;

SQL> alter system register;

或者:

SQL> alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = DaveDai)(PORT = 1522))';

SQL> alter system register;

动态注册的好处是简单方便,但是容易发生注册失败

四、静态注册

静态注册就是实例启动时读取listener.ora文件的配置,将实例和服务注册到监听程序中

静态注册时的listener.ora中的内容如下

SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (PROGRAM = extproc)

      (SID_NAME = PLSExtProc)

      (ORACLE_HOME = D:\oradata\orcl)

    )

    (SID_DESC =

      (GLOBAL_DBNAME = orcl)

      (ORACLE_HOME = D:\oradata\orcl)

      (SID_NAME = ORCL)

    )

    (SID_DESC =

      (GLOBAL_DBNAME = orcl1)

      (ORACLE_HOME = D:\oradata\orcl)

      (SID_NAME = ORCL)

    )

  )

golbal_dbname是数据库对外提供的服务名,sid_name是实例名,该文件说明数据库是单实例数据库,实例名为orcl,向外提供了两个服务orcl和orcl1.

静态注册的好处可以总结为

1、监听不是最早启动

2、数据库运行期间,监听发成重启

3、oracle实例还没有open

当发生上述三种情况时,不会发生监听注册失败。

继续阅读