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 ,這樣在連線出現問題時才能分析問題是出在哪個環節。




2020年11月2日 星期一

5.7 管理 Data File

Oracle Data File 為資料庫的實體結構,針對 Data File 可以將其 Resize 或是搬移,如果 Tablespace 空間不足時, DBA 可以選擇為其新增 Data File 或是將原本的 Data File 放大。更改 Data File 大小只需簡單的使用 resize 命令,例如將 users01.dbf 更改大小為 100M :


SQL> alter database datafile '/opt/app/oradata/orcl/users01.dbf' resize 100M;


這邊要注意的是,將 Data File 放大只要作業系統空間足夠,或是沒超過 Small File 的上限 32G 都沒問題,但是 Data File 要縮小的話就不一定能夠成功,要視此 Data File 裡面是否已經分配給資料庫所使用,如果已經被分配的空間就無法回收縮小,此時如果執行 resize 命令就會出現 ORA-03297 錯誤:

D:\Blog\picture\5-30.jpg


Data File 除了可以更改大小外,當 filesystem 空間不足時, Data File 也可以搬移至其他可用空間,搬移 Data File 需要注意的是, Data File 的實體檔案是存放在作業系統上,這個實體的位置我們可以透過作業系統的命令得知,而資料庫所認為的 Data File 位置是紀錄在 Control File 裡,也就是要透過資料庫的 view (v$datafile 或是 dba_data_files) 來得知資料庫所認為的位置,當我們搬移 Data File 時必須要注意實體位置與資料庫認為的位置要相符,否則會造成此 Data File 無法使用。


搬移 Data File 的方式取決於資料庫是否處於 Archive Log Mode,只有在資料庫為 Archive Log Mode 之下才可以線上搬移 Data File,否則就必須把資料庫 shutdown 之後開啟至 mount 模式才能夠搬移 Data File。


在 No Archive Log Mode 搬移 Data File 的步驟如下:

1. Shutdown 資料庫並開啟至 mount (startup mount)

2. 複製或搬移 Data File 實體位置,例如將 user01.dbf 從 /u01 換到 /u02: (mv 或 cp)

$ cp '/u01/app/oradata/orcl/users01.dbf' '/u02/app/oradata/orcl/users01.dbf'

3. 使用 sqlplus 進入資料庫更改 control file 裡面的紀錄:

SQL> alter database rename file '/u01/app/oradata/orcl/users01.dbf' to '/u02/app/oradata/orcl/users01.dbf';

4. 將資料庫開啟 (alter database open) 便完成 Data File 的搬移

 

在 Archive Log Mode 搬移 Data File 的步驟如下:

1. 將 Data File Offline

SQL> alter database datafile '/u01/app/oradata/orcl/users01.dbf' offline;

2. 複製或搬移 Data File 實體位置,例如將 user01.dbf 從 /u01 換到 /u02: (mv 或 cp)

$ cp '/u01/app/oradata/orcl/users01.dbf' '/u02/app/oradata/orcl/users01.dbf'

3. 使用 sqlplus 進入資料庫更改 control file 裡面的紀錄:

SQL> alter database rename file '/u01/app/oradata/orcl/users01.dbf' to '/u02/app/oradata/orcl/users01.dbf';

4. Recover Data File

SQL> recover datafile '/u02/app/oradata/orcl/users01.dbf';

5. 將 Data File Online

SQL> alter database datafile '/u02/app/oradata/orcl/users01.dbf' online;


雖然在 Archive Log 模式之下搬移 Data File 不必關閉資料庫,但是將 Data File Offline 的時候,表示此 Data File 為靜止狀態,暫時脫離資料庫的控管,而此 Data File 相關的資料也就無法讀取,直到再次 Online 的時候才可以使用。由於資料庫是一直處於運行的狀態,所以要將 Data File 再次 Online 的時候必須做 Recover 的動作,目的就是要追上資料庫這段的時間差,否則資料庫會提示 ORA-01113 錯誤:


搬移 Data File 除了使用 sqlplus 之外,另外也可以使用 RMAN 來做搬移更為方便,同樣的是以線上搬移 user01.dbf 為例:

1. 將 Data File Offline

RMAN> alter database datafile '/u01/app/oradata/orcl/users01.dbf' offline;

(11g 以前在 RMAN 裡需要使用 sql 關鍵字,12c 以後不用)

2. 複製 user01.dbf 至 /u02 底下

RMAN> copy datafile '/u01/app/oradata/orcl/users01.dbf' to '/u02/app/oradata/orcl/users01.dbf';

3. 使用 switch 命令更改 control file 裡面的紀錄

RMAN> switch datafile '/u01/app/oradata/orcl/users01.dbf' to copy;

4. Recover Data File

RMAN> recover datafile '/u02/app/oradata/orcl/users01.dbf';

5. 將 Data File Online

RMAN> alter database datafile '/u02/app/oradata/orcl/users01.dbf' online;


與 sqlplus 的差別在於,RMAN 的 copy 命令會於作業系統上複製檔案,我們不需要在另外執行作業系統命令去搬移 Data File。


到了 Oracle 12c ,推出了 Online Move Data File 的新功能,只需執行 move datafile 命令便自動幫我們搬移了,過程中無須將 Data File Offline、Online,也無須於作業系統上搬移實體檔,所有的動作都簡化由一個命令自動完成:

SQL> alter database move datafile '/u01/app/oradata/orcl/users01.dbf' to '/u02/app/oradata/orcl/users01.dbf';


經由同樣的方式,我們也可以用來搬移 Redo Log File,但差別在於 Redo Log File 的搬移必須將資料庫啟動在 mount 模式,不可以線上搬移,而且只能透過 sqlplus 來進行:

1. Shutdown 資料庫並開啟至 mount (startup mount)

2. 複製或搬移 Redo Log 實體位置,例如將 redo01.log 從 /u01 換到 /u02: (mv 或 cp)

$ cp '/u01/app/oradata/orcl/redo01.log' '/u02/app/oradata/orcl/redo01.log'

3. 使用 sqlplus 進入資料庫更改 control file 裡面的紀錄:

SQL> alter database rename file '/u01/app/oradata/orcl/redo01.log' to '/u02/app/oradata/orcl/redo01.log';

4. 將資料庫開啟 (alter database open) 便完成 Redo Log File 的搬移


最後來談一下實體結構的最後一部分,Control File 的搬移。由於 Control File 的位置是記錄在參數檔裡面,因此我們只需要更改參數 control_files 之後將資料庫重啟,就可以搬移 Control Files。例如將 Control Files 搬至 /u02:

1. 更改參數檔

SQL> alter system set control_files='/u02/app/oradata/orcl/control01.ctl' scope=spfile;

2. 關閉資料庫 (shutdown immediate)

3. 複製或搬移 Control File 實體位置

$ cp '/u01/app/oradata/orcl/control01.ctl' '/u02/app/oradata/orcl/control01.ctl'

4. 啟動資料庫 (startup)


不論我們要搬移資料庫的哪一種檔案,都要注意必須與資料庫所記錄的位置相符,因此必須要不斷的透過查詢來確認檔案位置無誤, Data File 相關的 view 為 v$datafile 、 dba_data_files; Redo Log 相關的 view 為 v$log 、 v$logfile,而 Control File 則是直接確認參數檔的內容,使用 show parameter control_files 或是查詢 v$parameter,DBA 必須熟悉這些 view ,有助於 Oracle 資料庫的管理。