暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

Oracle数据库的访问——动态监听器注册服务

原创 eygle 2019-12-26
3094

从Oracle 8i开始,Oracle引入了动态服务注册(Dynamic Service Registration)的功能,所谓动态注册是指当实例启动之后,由后台进程PMON在监听器中注册数据库服务信息。在动态注册机制下,原来监听器中的SID_LIST部分将不再需要。

通过服务注册可以获得如下收益:
1.简化配置
服务注册可以减化监听器的配置,SID_LIST_<listener_name>参数将不再需要.

2.连接时Failover
在动态注册时,由数据库主动向监听器注册实例,因此监听器总是可以知道实例的状态,在RAC环境下,当某个数据库实例出现故障时,动态服务注册功能可以快速自动的Failover客户端请求到其他实例;而如果在静态注册模式下,监听器将首先启动一个专用服务器进程接受客户端请求,然后向数据库服务器发起连接,随后才能发现实例已经停止,给出“Oracle not available”的错误提示,这个过程要缓慢低效得多。

3.运行时连接负载均衡
在RAC环境下,服务注册使得监听器能够向负载最轻的实例转发连接请求,从而实现运行时连接的负载均衡。

动态注册在Oracle 9i里是自动启用的,监听器文件可以不再需要,或者可以配置一个经过极大简化的监听器文件。现在一个简单的监听器配置可能类似如下示例(缺省的监听PLSExtProc是为外部存储过程调用而配置的):

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.33.50)(PORT = 1521))
      )
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
      )
    )
  )
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /opt/oracle9/product/9.2.0)
      (PROGRAM = extproc)
    )
    )

这样监听器启动后可以看到如下信息:

bash-2.03$ lsnrctl start
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.16.33.50)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Solaris: Version 9.2.0.4.0 - Production
Start Date                16-FEB-2007 20:42:27
Listener Parameter File   /opt/oracle9/product/9.2.0/network/admin/listener.ora
Listener Log File         /opt/oracle9/product/9.2.0/network/log/listener.log
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=172.16.33.50)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully

已经启动的实例随后会将服务名(初始化参数中定义的SERVICE_NAMES)注册到监听器中:

bash-2.03$ lsnrctl status
。。。。。。。。。。。。。。。。。。。。
Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "eygle" has 1 instance(s).
  Instance "testora9", status READY, has 1 handler(s) for this service...
Service "julia" has 1 instance(s).
  Instance "testora9", status READY, has 1 handler(s) for this service...
Service "testora9XDB" has 1 instance(s).
  Instance "testora9", status READY, has 1 handler(s) for this service...
The command completed successfully

动态注册的服务名,由于监听器确切地知道实例的状态,所以正常状态通常显示为READY,而对于静态注册的服务名,则状态显示为UNKNOW,这也是我们经常看到某些数据库的监听器会有如下显示的原因:

Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "hsbill" has 2 instance(s).
  Instance "hsbill", status UNKNOWN, has 1 handler(s) for this service...
  Instance "hsbill", status READY, has 1 handler(s) for this service...

缺省情况下,实例使用数据库服务器主机名对应的IP地址和1521端口连接监听进行动态注册,如果监听器使用了服务器主机名或主机名对应的IP地址、缺省的1521端口及TCP协议,则无需任何特殊配置,Oracle就能执行动态注册。否则需要设置LOCAL_LISTENER参数。

对于专用服务器模式,参数可以设置为:

LOCAL_LISTENER=listener_alias

对于共享服务器模式,参数可以设置为:

DISPATCHERS="(PROTOCOL=tcp)(LISTENER=listener_alias)"

Listener_alias随后通过Oracle命名方式(例如tnsnames.ora文件)解析为其他协议地址。例如如果监听器监听端口为1522,可以设置初始化参数为:

LOCAL_LISTENER=listener1

对于共享服务期模式,可以设置为:

DISPATCHERS="(PROTOCOL=tcp)(LISTENER=listener1)"

在tnsnames.ora文件中listener1可以按如下方式解析:

listener1=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=prod-server)(PORT=1522)))

同样,监听器还可以向远程服务器注册,例如在RAC环境中,配置监听器远程注册需要设置REMOTE_LISTENER参数,假定两个实例的实例名称分别为prod1和prod2,那么两个实例的REMOTE_LISTENER参数应该分别设置如下。

对于prod1服务器设置:

REMOTE_LISTENER=listener_prod2

对于prod2服务器设置为:

REMOTE_LISTENER=listener_prod1

在prod1服务器上的tnsnames.ora文件中可以如下配置listener_prod2命名:

listener_prod2=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=prod2-server)(PORT=1521)))

在prod2服务器上的tnsnames.ora文件中可以如下配置listener_prod1命名:

listener_prod1=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=prod1-server)(PORT=1521)))

而为了进一步简化,REMOTE_LISTENER参数的配置在RAC环境中可以相同,以下是来自Oracle 10g RAC环境中的示例,多个实例的参数设置相同:

SQL> show parameter remote_lis
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
remote_listener                      string      LISTENERS_SMSDB

这个设置可以通过手工方式修改,类似如下命令可以用于完成这一工作:

alter system set REMOTE_LISTENER = ‘LISTENERS_ALIAS’ scope=both sid=’*’;

然后tnsnames.ora文件配置包含如下信息:

LISTENERS_SMSDB =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.200.13)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.200.14)(PORT = 1521))
  )

这样监听器启动之后就会同时自动在远程和本地进行注册,这个RAC数据库的初始化参数SERVICE_NAMES设置如下:

SQL> show parameter service_name
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
service_names                        string      smsrac, smsdb

以下输出是RAC环境中数据库的注册信息(做了适当简化):

[oracle@smsdbrac2 admin]$ lsnrctl status
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 10.2.0.4.0 - Production
Start Date                05-MAY-2008 16:04:44
------------------------
Services Summary...
Service "+ASM" has 1 instance(s).
  Instance "+ASM2", status BLOCKED, has 1 handler(s) for this service...
Service "smsdb" has 2 instance(s).
  Instance "smsdb1", status READY, has 1 handler(s) for this service...
  Instance "smsdb2", status READY, has 2 handler(s) for this service...
Service "smsrac" has 2 instance(s).
  Instance "smsdb1", status READY, has 1 handler(s) for this service...
  Instance "smsdb2", status READY, has 2 handler(s) for this service...
The command completed successfully

对应于RAC环境,客户端的tnsnames.ora文件配置也有所不同,以下是一段RAC环境下客户端的配置示例。与单实例的不同之处在于地址列表段包含多个实例的地址信息,同时支持负载均衡和在多实例之间的FailOver切换:

SMSRAC =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.200.13)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.200.14)(PORT = 1521))
    (LOAD_BALANCE = yes)
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = smsrac)
      (FAILOVER_MODE =
        (TYPE = SELECT)
        (METHOD = BASIC)
        (RETRIES = 180)
        (DELAY = 5)
      )
    )
  )
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论