2020年11月30日 星期一

6.3 Net Naming Method

連線至 Oracle 資料庫最簡單的方式就是使用 sqlplus 進行連線,使用 sqlplus 連線時會輸入 <帳號>/<密碼>@<資料庫名稱> , Oracle Net Naming Method 就是用來定義 “@” 後面的資料庫名稱是什麼。 Net Naming Method 總共有四種方式可以用來定義,分別是 Easy Connect Naming 、 Local Naming 、 Directory Naming 以及 External Naming。


  • Easy Connect Naming:

表示在連線的時候直接將資料庫的資訊輸入在連線字串裡面,也就是連線的時候直接指定資料庫的 ip 、 Port 與 Service Name:

$ sqlplus <帳號>/<密碼>@hostname:Port/DB_Service_Name

 

這邊要注意的是,在連線字串中必須一定要輸入密碼,這種連線方式不會提示要輸入密碼,而是會直接報錯:


  • Local Naming:

表示使用 tnsnames.ora 裡面的定義進行連線, “@” 後面使用的就是 tnsnames.ora 所自行定義的名稱,例如在 tnsnames.ora 裡面定義一個名為 “ORCL” 的名稱,而連線到的資料庫服務為 “ORA11”:


  • Directory Naming:

類似於 tnsnames.ora 的連線方式,差別在於將連線的名稱定義在 LDAP 上,而 LDAP 服務必須支援 Oracle Net 協定,例如OID (Oracle Internet Directory) 或是 Windows AD…等。在 LDAP 定義好名稱後必須於 Client 端的 sqlnet.ora 定義 DIRECTORY_PATH 指到 LDAP,這樣連線的時候就會去 LDAP 驗證連線字串:


  • External Naming:

類似於 Directory Naming 方式,差別在於將連線名稱定義在第三方的 Naming Service 服務,例如使用 NIS (Network Information Services)。此種方式同樣在定義完後必須設定 DIRECTORY_PATH 為 NIS 就可以使用:


雖然有四種方式可以連線,不過最常使用的還是 Easy Connect Naming 與 Local Naming,其中又以 tnsnames.ora (Local Naming) 的方式連線居多,差別在於 tnsnames.ora 裡面可以設定其他的參數選項,例如 Connect Failover 或是 Load Balance …等設定,而這些功能是 Easy Connect Naming 辦不到的。 Directory Naming 與 External Naming 使用上就沒有那麼普遍,除非有特殊需求,否則很少會使用這種方式來連線,例如將資料庫裡面的使用者帳號與 LDAP 來做整合以便統一管理,這類的情況才有可能使用 Directory Naming。



2020年11月20日 星期五

6.2 Oracle Listener

Oracle Listener 只會存在 Oracle Server 上,主要的功能是用來建立起Oracle Client 與 Server 之間的連線,一台 Oracle Server 可以建立一個或多個 Listener,每個 Listener 分別設定不同的 Port Number,預設 Listener 使用的是 1521 Port。


建立 Listener 的方式可以透過 netca 或是自行編輯 listener.ora 進行設定,如果是 RAC 系統的話,則是透過 srvctl add listener 命令來建立。listener.ora 存放在 $ORACLE_HOME/network/admin 目錄底下,如果是 Oracle 11g 之後的 RAC 系統,則是存放在 $GRID_HOME/network/admin 底下,listener.ora 裡面定義了 Listener 名稱、ip 位址以及 Port Number:

上述範例中設定了兩個 Listener,一個是預設的名稱 “LISTENER” ,使用的是預設 1521 Port,而另一個是自行設定的名稱 “LISTENER_ORCL” ,使用的是 1522 Port。


Listener 在管理上使用的是 lsnrctl 命令,lsnrctl 後面不指定 Listener 名稱的話則表示是預設的 Listener:

$ lsnrctl start

(開啟預設的 Listener)

$ lsnrctl stop 

(關閉預設的 Listener)

$ lsnrctl status 

(查看預設的 Listener 狀態)

$ lsnrctl start LISTENER_ORCL

(開啟 LISENER_ORCL 這個 Listener)

$ lsnrctl stop LISTENER_ORCL

(關閉 LISENER_ORCL 這個 Listener)

$ lsnrctl status LISTENER_ORCL

(查看LISENER_ORCL 這個 Listener 的狀態)

如果是 RAC 系統的話則是使用 srvctl 命令來管理。


既然一台 Oracle Server 可以建立多個 Listener,那麼我們就可以選擇在這台 Oracle Server 上的資料庫要註冊到哪一個 Listener 上面。資料庫必須進行註冊的動作,Listener 才會有相對應的 Service Name 、 SID 等資訊,在 Client 進行連線時,Listener 便會檢查 Client 所請求的 Service Name 是否有在它的清單上,檢查通過後便會把連線接通到資料庫,如果資料庫沒有註冊的話,那麼 Listener 也不會有它的 Service Name,也就無法連線了。


例如現在有兩個 Listener 分別是 Listener_1 與 Listner_2,而同時也有兩個資料庫 DB1 與 DB2,DB1 只有註冊到 Listener_2 而 DB2 同時註冊在 Listener_1 與 Listener_2:

在這樣的設定下,Client 可以透過 1521 Port 以及 1522 Port 來連線到 DB2,而 DB1 就只能透過 1522 Port 來連線了。


資料庫註冊到 Listener 的方式分為靜態註冊與動態註冊兩種。


靜態註冊是把資料庫的資訊直接定義在 Listener 的設定當中,也就是在 listener.ora 裡面進行設定,只要 Listener 一啟動之後馬上就有此資料庫的資訊,靜態註冊可以註冊多個資料庫,只需要把資料庫的資訊放入 SID_LIST_<Listener_Name> 這個格式底下就完成靜態註冊,例如將 orcl 這個資料庫靜態註冊到名為 “LISTENER” 這個 Listener 底下:

如果要靜態註冊多個資料庫,只需複製 “SID_DESC” 底下這個段落接續在 “SID_LIST” 這個段落底下就可以了。由於是在 listener.ora 進行設定,因此要讓設定生效的話必須 restart 或是 reload Listener ,讓 Listener 重新讀取 listener.ora 後生效。


資料庫動態註冊表示資料庫在啟動之後,會自動的註冊到 Listener 上面,這個動作是藉由 PMON 這個 Background Process 來達成 (Oracle 12c 以後改由 LREG 負責)。既然是自動註冊,那麼資料庫怎麼知道要註冊到哪一個 Listener 上面 ? 這個就要透過 local_listener 這個參數來達成,假如 local_listener 這個參數沒有進行任何設定,那麼資料庫就會自動註冊到預設 1521 Port 的這個 Listener,如果要註冊到其它 Listener,那麼就要設定 local_listener 來提示資料庫要註冊到哪一個 Port 上面,例如註冊到 1522 Port 的 Listener 就需設定如下:

由於動態註冊是透過 Background Process 來進行,運作上需要一些時間,有時在資料庫剛啟動後還沒辦法立即的從 Listener 上面看到 Service Name,這個時候可以透過命令 alter system register 來立即執行註冊。


靜態註冊與動態註冊最大的差別在於顯示的狀態:


由於靜態註冊是直接在 listener.ora 裡面設定,我們只是把這筆紀錄直接寫入到 Listener 當中,因此對於 Listener 來說並不會知道這個資料庫是否存在、開啟或關閉,它只知道有這筆紀錄而已,所以靜態註冊顯示的 Instance 狀態為 “UNKNOWN”;而動態註冊則是資料庫開啟後自動註冊的,這個行為必須是在資料庫開啟的狀態才會發生,因此動態註冊所看到的 Instance 狀態為 “READY”,經由這個邏輯可以簡單觀察 lsnrctl status 裡面 “READY” 的狀態來判斷哪些資料庫有開啟。


Listener 在整個 Oracle Network 環境當中扮演非常重要的腳色,所有 Client 的連線都必須透過 Listener 來完成,對於 Client 使用者來說,可以使用 tnsping 這個命令來檢測 tnsnames.ora 裡面所設定的 ip 與 Port 是否有 Listener 存在:

如果 Listener 不存在或是設定有誤的話則會出現 TNS-12541: TNS:no listener 錯誤,在此值得注意的是,tnsping 只能檢測是否有 Listener ,如果 tnsnames.ora 裡面的 Service Name 設定有誤的話,tnsping 是檢查不出來的,此時必須實際的進行連線來檢測,假如 Service Name 的設定有問題的話,會出現 ORA-12514: TNS:listener does not currently know of service requested in connect descriptor 錯誤,這時就必須檢查 tnsnames.ora 裡面的設定,或者經由 lsnrctl status 來檢查資料庫是否有註冊到相對應的 Listener。





2020年11月19日 星期四

6.1 Client-Server 架構介紹

Oracle 資料庫在架構上走的是 Client-Server 架構,也就是說在一台主機上安裝 Oracle 軟體,這台主機就成為了 Oracle Server,而要從其它主機登入或連線到 Oracle Server 上的資料庫就必須要透過 Oracle Client 來連線。連線到 Oracle 資料庫的方式有很多種,例如使用 sqlplus 、 SQL Developer 、 ODBC…等這些工具都是藉由安裝 Oracle Client 軟體作為驅動來連線,如果是 Java 的話則可以透過 Oracle JDBC Thin Client 來連線。


Client 端發起連線的請求之後首先會在 Client 端的主機上產生 User Process,然後透過網路將連線的請求送到 Oracle Server 上,這時候在 Oracle Server 上有個專門接受連線請求的人物,這個人物我們稱作監聽器(Listener),在 Listener 接收到連線請求之後會確認連線的資訊是否正確,通過檢查後 Listener 便會建立起 Client 與 Server 之間的連線,並且在 Oracle Server 上產生此連線所對應的 Server Process。


在 Oracle Net 的架構中有兩個重要的設定檔,一個是 tnsnames.ora ,用來設定連線資訊,包括 Server ip 、 Port Number ,與資料庫的 Service Name;另一個是 Listener.ora ,只存在 Oracle Server ,此為 Listener 的設定檔。


tnsnames.ora 預設位置為 $ORACLE_HOME/network/admin 底下, $ORACLE_HOME 為 Oracle Client 或 Server 軟體的安裝目錄,連線時便會到這個路徑底下讀取 tnsnames.ora 的設定,如果要改變 tnsnames.ora 讀取的位置可以透過設定系統環境變數 TNS_ADMIN 來達成,但一般不建議更改。tnsnames.ora 為文字模式的檔案,可以直接透過文字編輯器來修改,裡面主要是定義連線到資料庫的連線字串,必須遵循固定個格式設定,例如設定兩個連線字串 ORA11 與 ORA10 如下:


最上面 “ORA11 =” 與 “ORA10 =” 為連線的名稱,主要是給 Client 端識別所用,可以設定任何的名稱,例如要連線到 ORA11 就要執行 sqlplus <帳號>/<密碼>@ORA11 ,連線到 ORA10 執行 sqlplus <帳號>/<密碼>@ORA10 。而在名稱的下面則是定義 Oracle Server 的 ip 位址、Port Number 與資料庫的 Service Name,在執行 sqlplus @ORA11 之後會將這些訊息透過網路傳送到 Listener,資訊正確的話 Listener 便會建立起連線。常見的連線錯誤例如 ORA-12541: TNS: no listener 表示 tnsnames.ora 裡面的 ip 位址或是 Port Number 設定有誤;ORA-12154: TNS:could not resolve the connect identifier specified 表示 tnsnames.ora 裡面的 Service Name 設定有誤,或者是資料庫未註冊到相對應的 Listener。


由於 tnsnames.ora 的設定必須遵循一定個格式,如果格式有誤的話便會產生無法連線的錯誤,也因此 Oracle Client 有一個工具 Net Manager 來輔助我們設定 tnsnames.ora:


如果是 Windows 平台的話可以直接執行 Net Manager,若是 Unix 平台的話,則必須要先啟用 XWindows 工具讓主機可以導出圖形介面,然後於 $ORACLE_HOME/bin 底下執行 netmgr。透過 Net Manager 工具的提示便可以按部就班的設定好 tnsnames.ora 的內容:


除此之外也可以透過網路組態輔助程式(netca) 來設定:


在 $ORACLE_HOME/network/admin 目錄下除了 tnsnames.ora 之外,還有一個重要的檔案 sqlnet.ora ,主要是用來設定一些額外與連線有關的參數來做為輔助,像是連線是否加密、連線 timeout 的時間設定、啟用連線的 trace …等都可以透過 sqlnet.ora 來達成,例如一個 sqlnet.ora 的設定如下:


上述兩個參數只有在 Oracle Server 上才會設定,INBOUND_CONNECT_TIMEOUT 用來設定 Client 與 Server 建立起連線時的超時時間,設定 3 表示在 3 秒鐘之內沒建立起連線表示連線超時; INVITED_NODES 表示 Oracle Server 只能容許這些 Client 的 ip 位址來連線,不在 INVITED_NODES 清單裡的主機不可以連線。


對於使用者來說只需要了解如何連線到 Oracle 資料庫,因此了解 tnsnames.ora 是必須的,而 DBA 則是更需要清楚的了解 tnsnames.ora、listener.ora 與 sqlnet.ora ,這樣在連線出現問題時才能分析問題是出在哪個環節。