對於Oracle初學者,甚至有些經驗的Oracle DBA來說,Oracle的賬戶登錄問題往往非常棘手,即便成功登錄oracle也是知其然而不知其所以然。作者經過系統學習和反復實踐,本著打破砂鍋問到底的態度,總算對Oracle的登錄原理與操作細節有了較全面的認識。本文記錄下這些體會與經驗,希望能幫助Oracle初學者自信地順利登錄oracle。
Oracle相關的知識很多,但一些基本的術語是所有dba都應該熟悉的。為更好的理解本文內容,讀者需要理解如下術語: Instance和Database,IP/TCP,sqlplus,Oracle 賬號與操作系統賬號, Oracle DBA。
Oracle軟件的整體架構是基於C/S的,按照功能分為客戶端和服務器端。客戶端負責接受用戶的輸入和接收並顯示來自服務器端的結果,常見客戶端有Sql Developer, SqlPlus;服務器端則負責解析來自客戶端的SQL請求,並把結果返回給客戶端。
任何C/S架構的軟件,通信部分都是至關重要的,重中之重就是通信協議的設計了。Oracle也不例外,采用的通信協議被稱為oracle net。它是一個應用層協議,目前oracle net可以運行在很多底層協議上,如TCP, 安全TCP,命名管道,SDP等。另外,針對不同的底層操作系統平台,oracle net也支持操作系統的本地進程間通信協議。
無論底層是什麼平台,無論客戶端軟件是什麼、運行在哪裡,客戶端和服務器通信只能采用唯一的Oracle net協議,別無它方。
通過賬戶進行權限控制是很多軟件采取的方法,例如每個OS都有自己的賬戶。Oracle也不例外,要想進入Oracle進行操作,必須以某種身份進入,這就是Oracle的賬戶。Oracle賬戶按照權限大致分為特權賬戶和普通賬戶。特權賬戶擁有極大的權限,而而普通用戶的權限受到很大限制。典型的特權賬戶就是SYS,SYSTEM。
那麼oracle是如何對賬戶進行驗證的呢?答案是有很多種方式,最容易理解的就是本地密碼驗證了,另外還有使用OS賬戶驗證、利用LDAP驗證、以及Kerberos等外部驗證。本文只涉及最基本的密碼驗證方式。
前面說過Oracle net支持多種底層通信協議,其中包括操作系統本地的進程間通信協議。 無論底層是何種協議,服務器端程序必須進行某種形式的偵聽,以等待來自客戶的連接請求。
(1)網絡偵聽程序tnslsnr
當底層協議是網絡協議時,Oracle tnslsnr提供偵聽服務。這是一個單獨的進程,與其他進程獨立。下面是Oracle專用服務器工作方式下的偵聽器工作示意圖。
如上圖所示,客戶端進程首先與偵聽器連接(紅色連線),並驗證賬戶與權限,如果所有驗證通過,偵聽進程負責產生出一個新的服務器進程,並讓客戶端進程和新產生的服務器進程直接連接(藍色連線),稱之為一個會話,同時自身斷開與客戶端的連接,並與新建立的會話不再有任何關系。可見偵聽進程起到了一個牽線的作用。之後,即使偵聽器停止了工作,已經建立的會話也絲毫不受影響。
(2)本地偵聽程序
本地偵聽程序與網絡偵聽器完全不同,它不需要網絡協議棧,具體實現嚴重依賴於底層OS。在Oracle中,本地偵聽與tnslsnr完全獨立。在Linux平台的本地偵聽不需要執行任何程序。也就是說本地登錄不依賴於tnslsnr。這對於dba是很實用的,當偵聽器發生故障不能正常工作時,我們仍然可以通過本地連接來登入oracle進行操作。
本文只關心本地密碼方式的驗證。
(1)密碼存放在數據字典中
此時要想驗證密碼,數據庫必須處於打開狀態,大多數普通用戶的密碼都是按照這種方式存放的。密碼存放於數據字典中會帶來一個問題,那就是數據庫打開之前,數據字典不可用,從而賬戶密碼也無法得知,導致用戶無法登錄。這對於DBA來說是個致命的問題,試想某一天數據庫出現問題無法加載,此時DBA必須登入系統進行修復,如果DBA賬戶的密碼存放在數據字典中,要想登錄必須先打開數據庫,這豈不是陷入死循環了。所以oracle規定凡是具有DBA特殊權限的賬戶的密碼信息會自動復制一份存放到外部文件中。
(2)密碼存放在外部文件中
這個密碼文件通常的存放位置是@ORACLE_HOME/dbs/orapw$SID。需要注意的是,只有具有DBA權限的賬戶密碼才會存放到外部文件中,而且是在授予特殊權限時系統自動添加的,不能手工修改外部密碼文件。
使用前提:
(1)客戶端與服務器端運行在同一機器上;
(2)使用安裝oracle的OS賬戶登入OS;
(3)設置了$ORACLE_SID環境變量。
連接字符串:
此時,的連接字符串必須為 connect / as sysdba。
使用場景:
值得說明的是,這種情況下,登錄成功的唯一前提就是需要指定$ORACLE_SID環境變量。不需要偵聽器,也不需要數據庫加載,甚至不需要實例啟動。如上圖所示,實例沒有啟動。此時,會默認使用oracle的sys賬戶登錄。
這種情形的使用情況是,DBA啟動數據庫。
使用前提:
(1)客戶端與服務器端運行在同一機器上;
(2)使用任何賬戶登錄OS;
(3)設置了$ORACLE_SID環境變量。
連接字符串:
此時,的連接字符串必須為 connect 特權賬戶名/密碼 as sysdba。
使用場景:
與4.1類似,只是此時的OS賬戶只要有權限運行sqlplus即可,無需是Oracle的安裝用戶。
4.3 本地偵聽+數據字典密碼適用前提:(1)客戶端與服務器端運行在同一機器上;(2)數據庫已經加載打開。(3)設置了$ORACLE_SID環境變量。
前面說過客戶端是根據連接字符串來確定采用哪種方式向服務器登錄的,連接字符串有特定的語法格式和特殊字符,如/,@,"。對於oracle賬戶名來說,一般要盡量避免名字中出現這些特殊字符,防止沖突。而對於賬戶的密碼來說,很多人都喜歡使用特殊的字符,一旦密碼中包含了/,@,",則勢必導致與登錄字符串的語法沖突。下面看幾個例子。