
思考
在Oracle中,什么是动态注册和静态注册,它们之间有什么区别?
♣
答案
Oracle的注册就是将数据库作为一个服务注册到监听程序,而客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务,根据注册方式的不同,目前Oracle支持动态注册和静态注册这两种注册方式。
动态注册是实例启动的时候PMON进程根据参数文件中的INSTANCE_NAME,SERVICE_NAMES两个参数将实例和服务动态注册到LISTENER中。动态注册默认只注册到默认的监听器上(名称为LISTENER、端口为1521),如果要向非默认监听器动态注册,那么需要配置LOCAL_LISTENER参数。需要注意的是,动态注册默认端口在数据库启动后大约1分钟之后才可以查询(lsnrct status),但可以在数据库中使用SQL语句“ALTER SYSTEM REGISTER;”立即注册数据库。
当使用动态注册时,若数据库处于NOMOUNT状态,则监听器中的状态为BLOCKED,此时,即使使用SYS用户也不能远程通过监听器连接到数据库。若将数据库启动到MOUNT状态,则监听器中的状态为READY,此时,只能使用SYS用户远程通过监听器连接到数据库。
有两种使用LOCAL_LISTENER的方式,下面分别介绍。
第一种方式,在Oracle用户下的$ORACLE_HOME/network/admin/tnsnames.ora文件中配置监听器的名称,然后配置LOCAL_LISTENER参数的值,如下所示:
LISTENER_LHR =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.130)(PORT = 1522))
)
其中,LISTENER_LHR可以是任意名称,即使该名称的监听器不存在,依然可以动态注册数据库,但是需要保证HOST的值是正确的,另外需要保证PORT端口号是一个已经存在的监听器的端口号。
接下来以SYS用户设置LOCAL_LISTENER参数的值:
ALTER SYSTEM SET LOCAL_LISTENER=LISTENER_LHR;
ALTER SYSTEM REGISTER;
第二种方式,直接配置LOCAL_LISTENER参数的值,如下所示:
ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.130)(PORT=1522))';--配置1个端口
ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.130)(PORT=1522))','(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.130)(PORT=1523))';--配置多个端口
ALTER SYSTEM REGISTER;
这里的LOCAL_LISTENER参数后的值可以直接从命令lsnrctl status中获取,如下所示:
[oracle@OCPLHR admin]$ lsnrctl status
LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 07-MAR-2018 22:16:52
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.155)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.2.0.3.0 - Production
Start Date 07-MAR-2018 22:10:21
Uptime 0 days 0 hr. 6 min. 31 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/OCPLHR/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.59.155)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM", status READY, has 1 handler(s) for this service...
Service "OCPLHR1" has 1 instance(s).
Instance "OCPLHR1", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
需要注意的是,若将LOCAL_LISTENER设置为空,则在下一次数据库启动的时候会自动配置该参数的值。若LOCAL_LISTENER的值为空,则Oracle会默认动态注册默认监听器。若修改了LOCAL_LISTENER的值,且LOCAL_LISTENER的值中不包含默认监听器的配置,则Oracle不会再将当前数据库动态注册到默认监听器中。
静态注册就是在监听启动的时候,不管实例启动了没有,实例的名字都已经注册到监听中了,主要用于DBA远程启动数据库实例。在DG的搭建过程中也必须配置静态监听。静态注册主要在$ORACLE_HOME/network/admin/listener.ora文件中配置,静态注册的示例如下所示:
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.130)(PORT = 1522))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl.lhr.com)
(SID_NAME = orcl)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
)
(SID_DESC =
(GLOBAL_DBNAME = rman.lhr.com)
(SID_NAME = rman)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
)
)
其中,SID_LIST_XXX,这里的XXX必须是某一个已经存在的监听器的名称。
那么,如何查询某服务是静态注册还是动态注册呢?可以使用命令lsnrctl status来查看某服务是静态注册还是动态注册。实例状态为UNKNOWN时表明此服务是静态注册。这时监听器用来表明它不知道关于该实例的任何信息,只有当客户发出连接请求时,它才检查该实例是否存在。动态注册的数据库通过状态信息中的状态READY或状态BLOCKED(动态监听在NOMOUNT状态下为BLOCKED)来指明。不管何时关闭数据库,动态注册的数据库都会动态地从监听器注销,而与之相关的信息将从状态列表中消失。所以,不管数据库是在运行还是已经关闭,监听器总是知道它的状态。该信息将被用于连接请求的回退和负载平衡。
例如,数据库名为lhrdb,其LOCAL_LISTENER的配置如下所示:
SYS@lhrdb> ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.13)(PORT=1530))';
System altered.
SYS@lhrdb> ALTER SYSTEM REGISTER;
System altered.
SYS@lhrdb> show parameter LOCAL_LISTENER
NAME TYPE VALUE
------------------------------------ ----------- ---------------------------------------------------------
local_listener string (ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.13)(PORT=1530))
其LISTENER.ORA的配置如下所示:
LISTENER_LHRTEST =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.13)(PORT = 1530))
)
)
SID_LIST_LISTENER_LHRTEST =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = lhrdb)
(ORACLE_HOME = /oracle/app/oracle/product/11.2.0/db)
(SID_NAME = lhrdb)
)
)
需要说明的是,该库既配置了动态监听,也配置了静态监听,执行lsnrctl status LISTENER_LHRTEST后可以看到:
[ZFZHLHRDB1:grid]:/home/grid>lsnrctl status LISTENER_LHRTEST
LSNRCTL for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production on 12-OCT-2016 17:35:35
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.13)(PORT=1530)))
STATUS of the LISTENER
------------------------
Alias LISTENER_LHRTEST
Version TNSLSNR for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production
Start Date 12-OCT-2016 17:26:44
Uptime 0 days 0 hr. 8 min. 51 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /oracle/app/11.2.0/grid/network/admin/listener.ora
Listener Log File /oracle/app/grid/diag/tnslsnr/ZFZHLHRDB1/listener_lhrtest/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.59.13)(PORT=1530)))
Services Summary...
Service "lhrdb" has 2 instance(s).
Instance "lhrdb", status UNKNOWN, has 1 handler(s) for this service...
Instance "lhrdb", status READY, has 1 handler(s) for this service...
Service "lhrdbXDB" has 1 instance(s).
Instance "lhrdb", status READY, has 1 handler(s) for this service...
The command completed successfully
[ZFZHLHRDB1:grid]:/home/grid>lsnrctl
LSNRCTL for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production on 12-OCT-2016 17:38:48
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Welcome to LSNRCTL, type "help" for information.
LSNRCTL> services LISTENER_LHRTEST
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.59.13)(PORT=1530)))
Services Summary...
Service "lhrdb" has 2 instance(s).
Instance "lhrdb", status UNKNOWN, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0
LOCAL SERVER
Instance "lhrdb", status READY, has 1 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:ready
LOCAL SERVER
Service "lhrdbXDB" has 1 instance(s).
Instance "lhrdb", status READY, has 1 handler(s) for this service...
Handler(s):
"D000" established:0 refused:0 current:0 max:1022 state:ready
DISPATCHER <machine: ZFZHLHRDB1, pid: 7012814>
(ADDRESS=(PROTOCOL=tcp)(HOST=ZFZHLHRDB1)(PORT=41041))
The command completed successfully
从上面的内容可以看出,监听器中既有UNKNOWN也有READY,UNKNOWN表示静态监听,READY表示动态监听,establicshed表示累计的连接总数,而不是当前连接数。
& 说明:
有关监听更多的内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-1423799/
本文选自《Oracle程序员面试笔试宝典》,作者:小麦苗