在有Oracle Listener的動态注冊之前,采用的是靜态注冊,所謂靜态注冊是指Oracle執行個體在啟動時,讀取listener.ora裡的配置,然後注冊到Listener,它主要有兩個缺點:
1. Listener不知道Oracle執行個體的實時狀态
2. listener.ora裡的配置比較麻煩,常需要手動修改。
動态注冊
所謂動态注冊是指Oracle執行個體啟動後,會通過pmon程序實時的把執行個體狀态和參數(instance_name,service_name)同步給Listener,其中參數instance_name如果為空,則預設為SID,參數service_name如果為空,則預設為db_name.db_domain
有了動态注冊之後,我們甚至不需要listener.ora,這時指令lsnrctl start将啟動預設的Listener(TCP協定、1521端口,Service和Instance分别來自參數service_name和instance_name。
這裡有一個小tip:pmon并不是真正實時同步Oracle執行個體至Listener,而是隔幾十秒,但你可以通過alter system register指令手動同步。
下面我們來看一個例子:
在這個例子裡,我們沒有配置listener.ora,listener.ora啟動後的狀态如下:
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production
Start Date 18-SEP-2013 16:58:01
Uptime 0 days 0 hr. 12 min. 54 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Log File /opt/oracle/diag/tnslsnr/data/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.15)(PORT=1521)))
Services Summary...
Service "orcl.localdomain" has 1 instance(s).
Instance "orcl", status READY, has 1 handler(s) for this service...
The command completed successfully
instance_name和service_names參數配置如下:
SQL>show parameter instance_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
instance_name string orcl
SQL>show parameter service_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string orcl.localdomain
從上面我們可以發現:Listener裡的Service、Instance是和instance_name、service_names參數相對應。這裡需要特别說明的是:參數service_names可以指定多個service_name,它們之間用逗号隔開。
在用戶端tnsnames.ora裡我們可以設定SID等于instance_name:
test =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.15)(PORT = 1521))
)
(CONNECT_DATA =
(sid = orcl)
)
)
也可以設定service_name等于services_names中的任意一個:
test =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.15)(PORT = 1521))
)
(CONNECT_DATA =
(service_name = orcl.localdomain)
)
)
Local_listener
上面那個動态注冊的例子非常簡單,是因為我們使用的是預設的監聽器(這也是一般推薦的做法),但如果想要使用非預設的監聽器該怎麼辦?(比如端口不是1521的)
此時, local_listener就派上用場了,它需要配合listener.ora和tnsnames.ora使用(注意:這裡的tnsnames.ora是在伺服器端,而不是在用戶端)。
首先,我們需要把非預設的監聽器添加到listener.ora:
LISTENER_2 =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = data)(PORT = 1522))
)
)
然後,我們在伺服器端的tnsnames.ora裡添加:
tnsnames.ora:
LISTENER_2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.15)(PORT = 1522))
)
接着,我們以sys使用者設定local_listener:
SQL>alter system set local_listener=listener_2;
System altered.
SQL>alter system register;
System altered.
執行如下指令啟動listener_2并檢視其狀态:
$ lsnrctl start listener_2
$ lsnrctl status listener_2
STATUS of the LISTENER
------------------------
Alias listener_2
Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production
Start Date 18-SEP-2013 17:36:43
Uptime 0 days 0 hr. 2 min. 53 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /opt/oracle/product/11.2.0/network/admin/listener.ora
Listener Log File /opt/oracle/diag/tnslsnr/data/listener_2/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=data)(PORT=1522)))
Services Summary...
Service "orcl.localdomain" has 1 instance(s).
Instance "orcl", status READY, has 1 handler(s) for this service...
The command completed successfully