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/