關於Oracle服務和監聽啟動順序問題,結合自身經驗和網上資料做個筆記:
經常用oracle的人對下面的這條信息肯定不會陌生:“監聽程序當前無法識別鏈接描述符中請求的服務”,或者你發現你的實例和監聽都已經正常啟動了,或者當實例和監聽都正常運行時你無意間重啟了監聽服務但是並沒有重啟實例,此時可能會發生用PLSQL去連Oracle時提示“ORA-12541:TNS:無監聽程序”,但是你在SQLPlus用sqlplus /as sysdba登陸時他沒有從你的實例中進去就不會報錯。其實產生這個問題的根本原因不是監聽沒有起來,而是監聽沒有監聽你要連接的oracle實例。
首先oracle只有兩者兼備才能向外界提供服務:一個是監聽,用於接收用戶的請求;一個是實例,真正的提供服務的。但是這兩者要協調好才能工作,即實例要告訴監聽我准備好了,可以接受外界的服務了。
這里面有個主動和被動的問題,當主動監聽時,監聽認為實例永遠都是准備好的,外界對實例的請求監聽都接受,哪怕實例還關着呢。被動就是實例起來后由PMON來向監聽注冊,告訴監聽我准備好了,可以接收外界請求了。
到這里,就要說啟動順序的問題了,在兩者同時啟動的情況下察覺不到問題,但是當兩者不是同時啟動情況下有問題了,但這只是個小問題:在等待“很小的一段時間”后問題會自己解決的(這個等待時間正常大概一分鍾作用,但也可能更長)。
先啟動監聽,后啟動實例,當從遠程客戶端連接實例時沒有問題,根本察覺不到,因為在啟動實例時PMON已經向監聽注冊實例了,當用戶請求時,兩者都准備好了,就沒問題。
先啟動實例,后啟動監聽,此時會有問題,但是只是個“很小的一段時間”的問題。如果監聽剛起來,用戶馬上就請求連接,這時可能會報“監聽程序當前無法識別鏈接描述符中請求的服務”或者“無監聽程序”的錯誤,原因在於PMON還沒來得及向監聽注冊實例。但是等一會為什么就好了呢?因為PMON是輪循的,它每隔一段時間向監聽注冊實例,只要監聽起來了,當PMON注冊時就能注冊成功,此時用戶在請求就沒問題了,但是這個“很小的一段時間”可能不一樣,就會影響系統運行和用戶體驗。
那有沒有辦法解決這點很短時間的問題呢?有 。這就是變被動監聽為主動監聽。將實例的描述添加到listener.ora中,這樣只要啟動監聽,就能監聽實例,而不管實例的狀態如何,只要兩者都准備好,OK就沒問題。
下面給出例子:
修改前:(單純的監聽描述)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))
)
)
修改后:(將實例的描述添加到listener.ora后)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
)
(SID_DESC =
(GLOBAL_DBNAME = orcl)
(ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))
)
)
注:什么是PMON——
PMON (進程監控進程):
進程監控進程:負責服務器進程的管理和維護工 作,在進程失敗或連接異常發生時該進程負責以下一些清理工作:
1、回滾沒有提交的事務
2、釋放所持有的當前的表或行鎖
3、釋放進程占用的SGA資源
4、監視其他oracle的后台進程,在必要時重啟這些后台進程
5、向oracle TNS監聽器注冊剛啟動的實例。如果監聽器在運行,就與這個監聽器通信並傳遞,如服務名和實例的負載等參數,如果監聽器沒有啟動,進程監控(PMON)會定期 地嘗試連接監聽來注冊實例。