天天看點

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/