天天看点

ORACLE的动态注册行为 zt

http://www.laoxiong.net/oracle_dynamic_register.html[@more@]

大家都知道,ORACLE实例在启动时,或使用命令ALTER SYSTEM REGISTER 或每隔一分钟,实例的PMON会向监听进行注册,告知监听,实例的服务名,实例名等信息。

不同的平台有不同的行为,本文所描述的是在LINUX下的行为。ORACLE版本为10.2.0.1。

讲到动态注册,跟监听密切相关,下面先看看监听的行为:

监听在启动时,会从$ORACLE_HOME/network/admin/listener.ora读取监听配置,如果该文件不存在,则监听会在 主机名对应的IP和1521端口上进行监听。如果主机名在/etc/hosts里没有配置(或不能通过DNS解析---这是我的猜想,没有验证),则在等 待较长一段时间后,将在所有的地址上(0.0.0.0:1521)进行监听,但此时实例并不会进行动态注册,客户端可通过主机的任意IP地址连接,但均会 报ORA-12514错误。除非设置LOCAL_LISTENER参数,将本地LISTENER地址指向本机的任意一IP。

如果存在listener.ora文件,则监听会根据该文件配置内容进行启动。如果主机名在/etc/hosts没有条目,监听 启动比较慢(可能是监听起来后,在根据主机名作什么操作),因此必须要保证主机名要在/etc/hosts中有记录。

同一个网络接口(网卡)上,如果绑定了两个或以上的IP地址,则监听这样的网络接口时,最多只能使用一个主机名,比如:

[[email protected] ~]$ cat /etc/hosts

# Do not remove the following line, or various programs

# that require network functionality will fail.

127.0.0.1 localhost.localdomain localhost

192.168.0.114 xty

192.168.0.115 xty_vip

192.168.0.116 xty_vip2

这里xty和xty_vip对应的IP绑定在同一网卡上

cat listener.ora

# Generated by Oracle configuration tools.

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

(SID_NAME = PLSExtProc)

(ORACLE_HOME = /u01/app/oracle/oracle/product/10.2.0/db_1)

(PROGRAM = extproc)

)

)

LISTENER =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = xty_vip )(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = xty )(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = xty_vip2 )(PORT = 1521))

(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))

)

)

启动监听时,报下面的错误:

TNSLSNR for Linux: Version 10.2.0.1.0 - Production

System parameter file is /u01/app/oracle/oracle/product/10.2.0/db_1/network/admi

n/listener.ora

Log messages written to /u01/app/oracle/oracle/product/10.2.0/db_1/network/log/l

istener.log

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521

)))

Error listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=xty)(PORT=1521)))

TNS-12542: TNS:address already in use

TNS-12560: TNS:protocol adapter error

TNS-00512: Address already in use

Linux Error: 98: Address already in use

Listener failed to start. See the error message(s) above…

将listener.ora中的(ADDRESS = (PROTOCOL = TCP)(HOST = xty )(PORT = 1521))行,改为(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.114 )(PORT = 1521)),则监听能够正常启动

下面再来看一下PMON向监听注册实例的行为:

在缺省情况下(也就是没有LOCAL_LISTENER参数配置的情况下),PMON会根据主机名(hostname),查找其IP地址,通常是在 /etc/hosts中找对应的条目,如果没有找到hostname的IP地址,则PMON不会注册,同时,必须是本机的IP地址,PMON才能注册。比 如在/etc/hosts中将hostname对应的IP地址改为其他非本机的IP地址,PMON也不会进行注册。PMON根据hostname找到IP 后,同时判断这个是本机IP,则会通过这个IP连接至监听进行注册。如果listener没有监听这个IP,则PMON也不会注册,因为通过这个IP连接 不上监听。

举一个简单的例子,现有两台IBM小机,作双机热备,双机采用HACMP。在监听设置中,只监听了HA的服务IP地址,而hostname对应的 IP地址为服务IP绑定的网卡上的另一个地址。在这种情况下,PMON不能进行动态注册,在客户端连接这个ORACLE服务器时,将会报ORA- 12514错误。

解决上面提到的这个问题的办法,除了静态注册(本文主要讨论动态注册),还有两种办法,第一种我个人认为最好的一种,是在LISTENER上监听两个IP地址,类似于下面这样:

LISTENER =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = xty_vip )(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.114 )(PORT = 1521))

(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))

)

)

另一个办法就是设置LOCAL_LISTENER参数,假如LISTENER只监听了xty_vip(192.168.0.115)这个地址,则通过下面的命令设置LOCAL_LISTENER:

ALTER SYSTEM SET LOCAL_LISTENER=’ (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.115 )(PORT = 1521))’

这里建议使用IP地址,特别是对RAC,后文细述。

LOCAL_LISTENER使PMON改变用hostname连接LISTENER进行注册的默认行为。改而用LOCAL_LISTENER参数 指定的地址连接LISTENER进行注册。当然LOCAL_LISTENER指定的IP地址必须是本机的IP地址。如果是非本机IP,则会忽略此参数,但 是会从前一个已注册的监听中取消注册。

与LOCAL_LISTENER对应的参数有REMOTE_LISTENER参数。REMOTE_LISTENER使PMON在远程(即非本机)监听上进行注册,这个参数在RAC中经常使用(用于负载均衡)。

下面来作一个测试:

主机1,LINUX AS4

主机2,Windows 2003,IP地址:192.168.0.100

,在主机2上启动监听:

D:oracleproduct10.2.0db_1BIN>lsnrctl start

LSNRCTL for 32-bit Windows: Version 10.2.0.1.0 - Production on 02-2月 -2008 09:5

6:44

Copyright (c) 1991, 2005, Oracle. All rights reserved.

启动tnslsnr: 请稍候…

TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 - Production

写入d:oracleproduct10.2.0db_1networkloglistener.log的日志信息

监听: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dreamf)(PORT=1521)))

正在连接到 (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

LISTENER 的 STATUS

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

别名 LISTENER

版本 TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 - Produ

ction

启动日期 02-2月 -2008 09:56:47

正常运行时间 0 天 0 小时 0 分 3 秒

跟踪级别 off

安全性 ON: Local OS Authentication

SNMP OFF

监听程序日志文件 d:oracleproduct10.2.0db_1networkloglistener

监听端点概要…

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

监听程序不支持服务

命令执行成功

在主机1上启动监听:

[[email protected] ~]$ lsnrctl start

LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 01-FEB-2008 17:28:57

Copyright (c) 1991, 2005, Oracle. All rights reserved.

Starting /u01/app/oracle/oracle/product/10.2.0/db_1/bin/tnslsnr: please wait…

TNSLSNR for Linux: Version 10.2.0.1.0 - Production

System parameter file is /u01/app/oracle/oracle/product/10.2.0/db_1/network/admi

n/listener.ora

Log messages written to /u01/app/oracle/oracle/product/10.2.0/db_1/network/log/l

istener.log

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521

)))

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.114)(PORT=1521

)))

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC0)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=xty_vip)(PORT=1521)))

STATUS of the LISTENER

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

Alias LISTENER

Version TNSLSNR for Linux: Version 10.2.0.1.0 - Production

Start Date 01-FEB-2008 17:28:57

Uptime 0 days 0 hr. 0 min. 0 sec

Trace Level off

Security ON: Local OS Authentication

SNMP OFF

Listener Parameter File /u01/app/oracle/oracle/product/10.2.0/db_1/network/adm

in/listener.ora

Listener Log File /u01/app/oracle/oracle/product/10.2.0/db_1/network/log

/listener.log

Listening Endpoints Summary…

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

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

(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC0)))

Services Summary…

Service "PLSExtProc" has 1 instance(s).

Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service…

The command completed successfully

[[email protected] ~]$

然后在主机1上启动数据库。输入命令:

alter system set remote_listener=’(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.100)(PORT=1521))’;

在主机2上查看LISTENER的状态

正在连接到 (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

LISTENER 的 STATUS

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

别名 LISTENER

版本 TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 - Produ

ction

启动日期 02-2月 -2008 09:56:47

正常运行时间 0 天 0 小时 16 分 54 秒

跟踪级别 off

安全性 ON: Local OS Authentication

SNMP OFF

监听程序日志文件 d:oracleproduct10.2.0db_1networkloglistener.log

监听端点概要…

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

服务摘要..

服务 "XTY" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

服务 "XTY1XDB" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

服务 "XTY_XPT" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

命令执行成功

在主机2上再执行lsnrctl service命令:

D:oracleproduct10.2.0db_1BIN>lsnrctl service

LSNRCTL for 32-bit Windows: Version 10.2.0.1.0 - Production on 02-2月 -2008 10:

5:21

Copyright (c) 1991, 2005, Oracle. All rights reserved.

正在连接到 (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

服务摘要..

服务 "XTY" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"DEDICATED" 已建立:0 已拒绝:0 状态:ready

REMOTE SERVER

(ADDRESS=(PROTOCOL=TCP)(HOST=xty)(PORT=1521))

服务 "XTY1XDB" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"D000" 已建立:0 已被拒绝:0 当前: 0 最大: 1022 状态: ready

DISPATCHER

(ADDRESS=(PROTOCOL=tcp)(HOST=xty)(PORT=32801))

服务 "XTY_XPT" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"DEDICATED" 已建立:0 已拒绝:0 状态:ready

REMOTE SERVER

(ADDRESS=(PROTOCOL=TCP)(HOST=xty)(PORT=1521))

命令执行成功

主机1上的实例已经成功注册到主机2上的监听

在主机2上的TNSNAMES.ORA中有:

XTY_R =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.100)(PORT = 1521))

)

(CONNECT_DATA =

(SERVICE_NAME = xty)

)

)

在主机2上连接XTY_R(这个实例实际运行在主机1上)

D:oracleadminXJbdump>sqlplus test/[email protected]_r

SQL*Plus: Release 9.2.0.1.0 - Production on 星期六 2月 2 10:19:41 2008

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

ERROR:

ORA-12535: TNS: 操作超时

请输入用户名:

报了ORA-12536错误。

从上面的lsnrctl service命令可以查看到REMOTE SERVER的地址为:

(ADDRESS=(PROTOCOL=TCP)(HOST=xty)(PORT=1521))

因此客户端连接时,LISTENER判断这是个远程SERVER,会将这个地址返回给客户,客户端再去连接这个地址。但这里HOST=xty,客户端不能解析这个地址,所以就报超时错误。

但如果在主机1上的数据库中执行下面的命令:

alter system set local_listener=’(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521))’;

我们再看看主机2上的LISTENER SERVICE:

正在连接到 (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

服务摘要..

服务 "XTY" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"DEDICATED" 已建立:0 已拒绝:0 状态:ready

REMOTE SERVER

(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521))

服务 "XTY1XDB" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"D000" 已建立:0 已被拒绝:0 当前: 0 最大: 1022 状态: ready

DISPATCHER

(ADDRESS=(PROTOCOL=tcp)(HOST=xty)(PORT=32801))

服务 "XTY_XPT" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"DEDICATED" 已建立:0 已拒绝:0 状态:ready

REMOTE SERVER

(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521))

命令执行成功

注意看到上面REMOTE SERVER已经变成了 (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521))

这个时候再次连接,由成功连接到ORACLE服务器上:

D:oracleadminXJbdump>sqlplus test/[email protected]_r

SQL*Plus: Release 9.2.0.1.0 - Production on 星期六 2月 2 10:39:25 2008

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

连接到:

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

With the Partitioning, OLAP and Data Mining options

SQL>

在RAC中,服务器开启了负载均衡,则客户端有时连接时会出现ORA-12514错误,这里需要设置LOCAL_LISTENER参数,以解决该问题。

注意:在通过REMOTE_LISTENER参数向远程监听注册时,本地的LISTENER也需要处于启动状态,否则监听中服务的状态为BLOCKED状态:

正在连接到 (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

服务摘要..

服务 "XTY" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"DEDICATED" 已建立:1 已拒绝:0 状态:blocked

REMOTE SERVER

(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521))

服务 "XTY1XDB" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"D000" 已建立:0 已被拒绝:0 当前: 0 最大: 1022 状态: ready

DISPATCHER

(ADDRESS=(PROTOCOL=tcp)(HOST=xty)(PORT=32801))

服务 "XTY_XPT" 包含 1 个例程。

例程 "XTY1", 状态 READY, 包含此服务的 1 个处理程序…

处理程序:

"DEDICATED" 已建立:1 已拒绝:0 状态:blocked

REMOTE SERVER

(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.115)(PORT=1521))

命令执行成功

而这个时候客户端连接报ORA-12516错误

另外,数据库实例版本必须与LISTENER版本兼容,否则不能进行动态注册。

本文主要是通过实验和分析网络包,然后进行总结的结果,没有参考相关的理论文档。有所错误在所难免,欢迎讨论。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/82387/viewspace-1028027/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/82387/viewspace-1028027/