此博文已經參加了2014 CSDN博文大賽,如果您覺得本文對你有用,請動動小手幫我投票: http://vote.blog.csdn.net/Article/Details?articleid=32939867,謝謝。
對於Oracle初學者,甚至有些經驗的Oracle DBA來說,Oracle的賬戶登入問題往往非常棘手,即便成功登入oracle也是知其然而不知其所以然。作者經過系統學習和反覆實踐,本著打破砂鍋問到底的態度,總算對Oracle的登入原理與操作細節有了較全面的認識。本文記錄下這些體會與經驗,希望能協助Oracle初學者自信地順利登入oracle。
1 學習本文的先決條件
Oracle相關的知識很多,但一些基本的術語是所有dba都應該熟悉的。為更好的理解本文內容,讀者需要理解如下術語: Instance和Database,IP/TCP,sqlplus,Oracle 帳號與作業系統帳號, Oracle DBA。
2 Oracle登入概述
2.1 Oracle的C/S架構與通訊協定
Oracle軟體的整體架構是基於C/S的,按照功能分為用戶端和伺服器端。用戶端負責接受使用者的輸入和接收並顯示來自伺服器端的結果,常見用戶端有Sql Developer, SqlPlus;伺服器端則負責解析來自用戶端的SQL請求,並把結果返回給用戶端。
任何C/S架構的軟體,通訊部分都是至關重要的,重中之重就是通訊協定的設計了。Oracle也不例外,採用的通訊協定被稱為oracle net。它是一個應用程式層協議,目前oracle net可以運行在很多底層協議上,如TCP, 安全TCP,具名管道,SDP等。另外,針對不同的底層作業系統平台,oracle net也支援作業系統的本地處理序間通訊協議。
無論底層是什麼平台,無論用戶端軟體是什麼、運行在哪裡,用戶端和伺服器通訊只能採用唯一的Oracle net協議,別無它方。
2.2 oracle賬戶與驗證方式
通過賬戶進行許可權控制是很多軟體採取的方法,例如每個OS都有自己的賬戶。Oracle也不例外,要想進入Oracle進行操作,必須以某種身份進入,這就是Oracle的賬戶。Oracle賬戶按照許可權大致分為特權賬戶和普通賬戶。特權賬戶擁有極大的許可權,而而普通使用者的許可權受到很大限制。典型的特權賬戶就是SYS,SYSTEM。
那麼oracle是如何對賬戶進行驗證的呢?答案是有很多種方式,最容易理解的就是本地密碼驗證了,另外還有使用OS賬戶驗證、利用LDAP驗證、以及Kerberos等外部驗證。本文只涉及最基本的密碼驗證方式。
3 Oracle偵聽與密碼存放作為C/S架構程式,帳號登入過程分成前後兩個部分,一是網路連接,二是帳號驗證。
3.1 兩種伺服器端偵聽程式
前面說過Oracle net支援多種底層通訊協定,其中包括作業系統本地的處理序間通訊協議。 無論底層是何種協議,伺服器端程式必須進行某種形式的偵聽,以等待來自客戶的串連請求。
(1)網路偵聽程式tnslsnr
當底層協議是網路通訊協定時,Oracle tnslsnr提供偵聽服務。這是一個單獨的進程,與其他進程獨立。下面是Oracle專用伺服器工作方式下的接聽程式工作。
如所示,用戶端進程首先與接聽程式串連(紅色連線),並驗證賬戶與許可權,如果所有驗證通過,偵聽進程負責產生出一個新的伺服器處理序,並讓用戶端進程和新產生的伺服器處理序直接連接(藍色連線),稱之為一個會話,同時自身斷開與用戶端的串連,並與建立立的會話不再有任何關係。可見偵聽進程起到了一個牽線的作用。之後,即使接聽程式停止了工作,已經建立的會話也絲毫不受影響。
(2)本地偵聽程式
本地偵聽程式與網路接聽程式完全不同,它不需要網路通訊協定棧,具體實現嚴重依賴於底層OS。在Oracle中,本地偵聽與tnslsnr完全獨立。在Linux平台的本地偵聽不需要執行任何程式。也就是說本地登入不依賴於tnslsnr。這對於dba是很實用的,當接聽程式發生故障不能正常工作時,我們仍然可以通過本地串連來登入oracle進行操作。
3.2 兩種密碼存放方式
本文只關心本地密碼方式的驗證。
(1)密碼存放在資料字典中
此時要想驗證密碼,資料庫必須處於開啟狀態,大多數普通使用者的密碼都是按照這種方式存放的。密碼存放於資料字典中會帶來一個問題,那就是資料庫開啟之前,資料字典不可用,從而賬戶密碼也無法得知,導致使用者無法登入。這對於DBA來說是個致命的問題,試想某一天資料庫出現問題無法載入,此時DBA必須登入系統進行修複,如果DBA賬戶的密碼存放在資料字典中,要想登入必須先開啟資料庫,這豈不是陷入死迴圈了。所以oracle規定凡是具有DBA特殊許可權的賬戶的密碼資訊會自動複製一份存放到外部檔案中。
(2)密碼存放在外部檔案中
這個密碼檔案通常的存放位置是@ORACLE_HOME/dbs/orapw$SID。需要注意的是,只有具有DBA許可權的賬戶密碼才會存放到外部檔案中,而且是在授予特殊許可權時系統自動添加的,不能手工修改外部密碼檔案。
4 Oracle登入的幾種情形分析針對不同的偵聽方式和不同的密碼存放方式,可以排列出如下幾種登入情形。用戶端進程是按照連接字串來判斷具體採用那種情形的。
4.1 本地偵聽+無需密碼
使用前提:
(1)用戶端與伺服器端運行在同一機器上;
(2)使用安裝oracle的OS賬戶登入OS;
(3)設定了$ORACLE_SID環境變數。
連接字串:
此時,的連接字串必須為 connect / as sysdba。
使用情境:
值得說明的是,這種情況下,登入成功的唯一前提就是需要指定$ORACLE_SID環境變數。不需要接聽程式,也不需要資料庫載入,甚至不需要執行個體啟動。如所示,執行個體沒有啟動。此時,會預設使用oracle的sys賬戶登入。
這種情形的使用方式是,DBA啟動資料庫。
4.2 本地偵聽+外部檔案密碼
使用前提:
(1)用戶端與伺服器端運行在同一機器上;
(2)使用任何賬戶登入OS;
(3)設定了$ORACLE_SID環境變數。
連接字串:
此時,的連接字串必須為 connect 特權賬戶名/密碼 as sysdba。
使用情境:
與4.1類似,只是此時的OS賬戶只要有許可權運行sqlplus即可,無需是Oracle的安裝使用者。
4.3 本地偵聽+資料字典密碼適用前提:(1)用戶端與伺服器端運行在同一機器上;(2)資料庫已經載入開啟。(3)設定了$ORACLE_SID環境變數。
連接字串:connect username/password。
使用情境:此時適用於本地登入的普通使用者。注意,由於密碼存放在資料字典裡,所以資料庫必須處於開啟狀態。
4.4 網路偵聽+外部檔案密碼適用前提:(1)tnslsnr必須已經正常工作;(2)資料執行個體啟動;無需載入資料庫。
連接字串:connect 特權使用者名稱/password@serverIP/servicename as sysdba
使用情境:dba遠程登入進行資料庫維護。此時資料庫無需載入。需要注意:連接字串中有服務名,所以偵聽程式必須知道這個服務名的資訊,然而預設情況下只有資料庫載入後才動態向接聽程式註冊服務資訊。而現在的情況是,只有資料庫執行個體啟動了,沒有載入資料庫。此時,要想讓接聽程式得知服務資訊,必須靜態註冊服務。方法是修改伺服器端的listener.ora設定檔,如下所示:
4.5 網路偵聽+資料字典密碼適用前提:(1)tnslsnr必須已經正常工作;(2)資料執行個體啟動,資料庫已經載入,並且開啟;
連接字串:connect 普通使用者名稱/password@serverIP/servicename
使用情境:這是普通oracle應用最常用的情形了,大多數的web程式,應用程式一般都是使用普通賬戶遠程接入oracle伺服器來讀寫資料。
5 密碼中特殊字元的處理前面說過用戶端是根據連接字串來確定採用哪種方式向伺服器登入的,連接字串有特定的文法格式和特殊字元,如/,@,"。對於oracle賬戶名來說,一般要盡量避免名字中出現這些特殊字元,防止衝突。而對於賬戶的密碼來說,很多人都喜歡使用特殊的字元,一旦密碼中包含了/,@,",則勢必導致與登入字串的文法衝突。下面看幾個例子。
(1)密碼 p@ssw0rd此時如果連接字串為 connect username/p@ssw0rd, 那麼@會被當做關鍵字,ssw0rd被當成是偵聽地址,從而報錯。解決方案是使用雙引號把密碼部分包圍起來。 connect username/"p@ssw0rd"。
(2)密碼 1/2方法與上面相同, connect username/"1/2"。
(3)密碼 1"2密碼裡帶有雙引號,我還真沒見過,也不知道怎麼建立這種密碼,還請高人指教。
oracle解析連接字串時,如果使用者名稱沒有使用引號包圍,則自動轉換為大寫字元;而對密碼部分的解析則原樣不變。(4)注意平台shell的元字元轉義sqlplus支援在作業系統的CUI介面直接給出使用者名稱和密碼參數進行登入。如 sqlplus username/password@server/service當密碼本身中含有bash元字元或者用引號包圍密碼時,都需要進行轉義。以bash為例,如上面的密碼 p@ssw0rd 的情況,此時需要寫成:sqlplus username/\"p@ssw0rd\"因為"本身在bash中是元字元,要想把"本身作為參數的一部分傳遞給sqlplus,必須對其進行轉義。
最後推薦一本OracleDBA的書籍,該書把很多的Oracle術語與原理講述的非常清楚,只是翻譯的略顯粗糙,建議下載英文版比較閱讀。英文版下載連結:http://download.csdn.net/detail/smstong/7534001。