2021年10月7日 星期四

1. RAC 介紹

Oracle Real Application Cluster (簡稱 RAC) 是一種資料庫的叢集 (Cluster) 架構,最早在 Oracle 8i 稱作 Parallel Server ,從 Oracle 9i 開始有了 RAC 這個名稱。早在 Oracle 9i 當時, Oracle 還沒有屬於自己的 Cluster Ware ,搭建 RAC 需要配合第三方的 Cluster 軟體來輔助,例如 Sun Cluster 、 IBM 的 HACMP 、 HP 的 Service Guard 、 Veritas Cluster (VCS) …等,到了 Oracle 10g 以後便推出了屬於 Oracle 自己的 Cluster Ware 並配合 ASM 的架構下來搭建 RAC ,從此以後就不再需要第三方的 Cluster 軟體了,到了 Oracle 11g 之後, RAC 改稱為 Grid Infrastructure 直至今日的版本,不論是早期的 Parallel Server 或者是 RAC 、 Grid Infrastructure ,指的都是 Oracle Cluster 架構。


所謂的 Cluster ,指的就是將多台 Server 組成一個 Group ,這個 Group 底下所有的成員用來支撐同一種服務,如果是只有一台 Server ,那麼當這台 Server 有問題的時候,運行在上面的服務也就不能使用;而 Cluster 的好處在於有多台 Server 來支撐服務,所以當其中有一台 Server 發生問題時,這個 Cluster 群組裡還有其它的 Server 可以用來運行服務,此時不會因為單一 Server 發生狀況而導致服務中斷,而多台 Server 如何能夠組成一個 Group ,這時候就是需要叢集軟體 (Cluster Ware) 來達成。



Cluster 在種類上可以分為 Sharing Everything 與 Sharing Nothing 兩大類, Sharing Everything 表示所有的 Server 必須共享一個存儲,這個 Storage 的空間必須共同給所有的 Server 來使用;而 Sharing Nothing 表示每台 Server 都有屬於自己的存儲空間,並且每台 Server 都擁有這項服務的一部分資料。對於 RAC 來說,使用的是 Sharing Everything 架構,所以搭建 RAC 前的其中一項任務,就是要設定好 Shared Storage 來給所有 Server 來使用。



Cluster 架構在服務的提供上,多數的 Cluster 只能做到 Active – Standby 架構,也就是平時只有 Cluster 群組中的一個 Server 來提供服務,如果這台 Server 發生問題的話,再由另一台 Server 接手繼續提供服務:

 


而 Oracle RAC 是少數能夠真正做到 Active – Active 服務的架構,並且不需要額外的 Management Server 來避免叢集發生腦裂 (Split-brain) 的情況。 Active – Active 架構是在叢集中所有的 Server 都能夠用來提供服務,當中如果有 Server 發生問題的話,其餘的 Server 仍然是可以馬上接手提供服務:



有了 Cluster 的概念之後,那麼就可以進一步理解 RAC Database 的構成,傳統單機資料庫來說,是一個 Instance 對應一個 Database :


而 RAC Database ,是多台 Server ,每個 Server 都有一個 Instance ,共同來支撐同一個資料庫:


RAC Database 的優點是,由於有多個 Instance 來支撐這個資料庫,因此不會因為有某台 Server 或某個 Instance 發生問題導致資料庫無法運行,只要其中有一個 Instance 還活著,那麼資料庫就可以正常的運行;其次是可以把服務分散在不同個 Instance 上執行,傳統單一 Server 的狀況下,如果 Server 的負載過重,那麼只能想辦法來增加硬體資源,而 RAC 的好處是有多個 Instance ,把服務分散在這些 Instance 上執行也就等於分散了每台 Server 的負載,萬一所有的 Server 都已經滿載,那麼 RAC 還可以添加 Server 到這一個叢集當中,而這個添加的過程不需要停止資料庫服務。


目前現實環境來說,都希望提供的服務可以不中斷, RAC 就提供了非常好的 HA (High Availability)  機制,為多數企業建置資料庫時的優先選擇,但這邊要注意的是, RAC 的優點在於它的高可用性機制,資料庫的效能不會因為把它轉換為 RAC 然後就會提升,如果使用不好的話很有可能因為 Global Cache 的因素導致效能下降,雖然 RAC 本身提供了 Load Balance 機制,但是建議在 RAC 的使用上,把服務區分並且運行在不同的 Instance 上會是比較好的做法,例如一個 RAC 資料庫 ORCL 提供了 A,B 兩種服務,那麼規劃上把 A 服務運行在 Instance 1 (ORCL1) 、 B 服務運行在 Instance 2 (ORCL2) ,這種使用方式會是比較好的選擇。



2021年10月5日 星期二

11.2 RMAN

RMAN 是 Oracle 用來備份的主要工具,最早起源於 Oracle 8i ,直到目前已經是 Oracle 資料庫主要的備份方式了,不論是冷備份或是熱備份都可以使用 RMAN 來達成, RMAN 進行冷備份必須將資料庫開啟至 mount 狀態下再進行備份,由於資料庫需重新啟動至 mount ,此時不如將資料庫 shutdown 後直接將檔案 copy 備份起來比較直觀,因此很少用 RMAN 來進行冷備份,多數的情況下都是在資料庫運行的過程中,使用 RMAN 來做一個熱備份。RMAN 取代了傳統使用 alter database begin backup 的方式,將備份統一由 RMAN 的介面單一完成,不須像 begin backup 那樣要使用作業系統命令來 copy 資料庫檔案,而且只要撰寫好一個腳本便可以適用所有的資料庫。


透過 RMAN 連線到資料庫便可以進行備份與還原的動作,使用 " rman target / " 或者是 " rman 帳號/密碼@<db_tnsnames> " 就可以進入 RMAN> 的提示符號下進行作業, RMAN 的指令大致上可以作為以下分類:


1. 連線指令: "connect" ,例如 "connect target /" 、 "connect catalog rman/rman@rman" 、 "connect auxiliary sys/welcome1@stby" 。


2. SQL 指令: "sql" ,主要用途是在 RMAN> 介面底下執行 SQL 指令,只需在前面加上 "sql" 就可以執行 SQL 指令,例如 "SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT';" 。到了 Oracle 12c 之後, RMAN> 介面可以直接執行 SQL 指令了,不須再加上 "sql" 。


3. 設定 RMAN 參數指令: "configure" ,例如設定 archive log 清理規則 "configure archivelog deletion policy to shipped to all standby" 。


4. 顯示設定內容: "show" ,例如顯示目前 RMAN 所有設定 "show all" 。


5. 備份還原相關指令: 備份 "backup" 、 還原 "restore" ,復原 "recover" ,其中 "restore" 指的是把 Data File 還原回來;而 "recover" 則是用來 apply archive log 。


6. 管理相關指令: "list" 列出備份相關資訊,例如 "list backup of database" ; "report" 用來分析備份與還原資訊,例如列出超過 retention policy 的備份 "report obsolete" 、 列出需要備份的檔案 "report need backup" ; "crosscheck" 用來檢查實際上存在於作業系統的備份檔案與資料庫所記錄的備份資訊是否相符,如果不相符,那麼那些紀錄將會被標示為 expired ,例如 "crosscheck backup" 、 "crosscheck archivelog all" 。


RMAN 指令執行的方式可分為兩種,一種是直接在 RMAN> 底下執行,另外一種是使用批次方式執行,所有命令必須寫在 RUN{} 底下這個區塊。


RMAN 可以將資料庫備份到作業系統的 filesystem ,或者是直接備份到磁帶,在執行備份前必須使用 "allocate channel" 來告訴 RMAN 要備份到哪裡,如果是備份到 filesystem 則執行 "allocate channel ch1 type disk" ;如果是備份到磁帶,則是 "allocate channel ch1 type sbt_tape" ,一個 channel 代表一個 RMAN 的 process ,我們可以 allocate 多個 channel 來讓 RMAN 使用多個 process 來進行備份或還原的任務。


一個完整的 RMAN 資料庫備份必須包含 Data File 、 Control File 、 Archive Log 與 Spfile ,例如備份到 filesystem :

$ rman target /

RMAN> run {

 crosscheck backup;

 crosscheck archivelog all;

 allocate channel ch1 type disk;

 allocate channel ch2 type disk;

 backup database format '/opt/app/dump/rman/fulldb_%s_%t.bak';

 sql 'alter system archive log current';

 backup archivelog all format '/opt/app/dump/rman/archivelog_%t_%s.bak' delete input;

 backup current controlfile format '/opt/app/dump/rman/controlfile_%s_%t.bak';

 backup spfile format '/opt/app/dump/rman/spfile_%t_%s.bak';

 release channel ch1;

 release channel ch2;

}        


其中 %s 用來設定 backup set 的編號; %t 為 backup set 加上時間戳記;備份 Archive Log 可加上 delete input 指令,用途是在備份完成後將 Archive Log 刪除。


如果是備份到磁帶的話,則需將 channel 設定為 type sbt_type ,例如透過 NBU 來做備份:

$ rman target /

RMAN> run {

 allocate channel ch1 type sbt_tape;

 allocate channel ch2 type sbt_tape;

 send 'NB_ORA_SERV=nbubak,NB_ORA_CLIENT=oradb1';

 backup database format '/opt/app/dump/rman/fulldb_%s_%t.bak';

 release channel ch1;

 release channel ch2;

}        


如果在 NBU 的 bp.conf 裡面有設定好 SERVER 與 CLIENT_NAME 的話,那麼在 RMAN 裡面則可以省去 "send 'NB_ORA_SERV=nbubak,NB_ORA_CLIENT=oradb1'" 這一段。


又例如透過 IBM TSM 來做備份,則設定環境變數如下:

$ rman target /

RMAN> run {

 allocate channel ch1 type sbt_tape parms

'ENV=(TDPO_OPTFILE=/usr/tivoli/tsm/client/oracle/bin64/tdpo.opt)';

 backup database format '/opt/app/dump/rman/fulldb_%s_%t.bak';

 release channel ch1;

 release channel ch2;

}        


RMAN 備份到不同廠牌的磁帶機設定都略有不同,大體上都是提供磁帶機 library 的位置給 RMAN 就可以備份到磁帶上面。


RMAN 除了做 full database backup 之外,也可以進行 incremental backup ,使用 incremental backup 必須賦予一個 backup level <號碼> ,這個 backup level 是用來對備份做一個旗標,用來告訴 RMAN 需要 incremental backup 的範圍在哪裡,所以在進行 incremental backup 之前必須要做一次 full backup ,往後的備份才有 incremental 的基準,在這邊做 full backup 時必須要特別指定 incremental level 0 ,有了這個 level 0 之後才可以進行 incremental backup:

$ rman target /

RMAN> run {

 allocate channel ch1 type disk;

 backup incremental level 0 database format '/orabak/fulldb_%s_%t.bak';

 release channel ch1;

 }        


有了 incremental level 0 之後就可以進行 incremental backup ,有兩種模式 Differential Incremental Backup 與 Cumulative Incremental Backup 。 Differential 模式所 incremental 的區間為 incremental level 小於或等於前一個 level ;而 Cumulative 模式所 incremental 的區間只有抓與小於前一個 level 。例如每日所設定的 incremental level 如下:


週日進行 incremental level 0 的全備份,週一、二、四、五設定為 incremental level 2 ,週三與週六設定為 incremental level 1 。對於週一來說,它只需找前一個比它 level 小的來作為 incremental 區間,所以週一會備份 incremental 週日 ~ 週一這個區段;對於週二來說,它的設定為 incremental level 2 ,在 Differential 模式下,它會找前一個與它相同或是小於它的 level 來做 incremental 區間,週一同樣為 level 2 ,所以它會 incremental 週一 ~ 週二這段區間 (綠色部分) ,而在 Cumulative 模式下,它只會找前一個比它小的 level ,所以它會 incremental 週日 ~ 週二這段區間 (紅色部分) ,後面以此類推。


預設為 Differential 模式,備份時只需提供 incremental level 就好:

$ rman target /

RMAN> run {

 allocate channel ch1 type disk;

 backup incremental level 2 database format '/orabak/fulldb_%s_%t.bak';

 release channel ch1;

 }        


如果要使用 Cumulative 模式,則需要加上 Cumulative 關鍵字:

$ rman target /

RMAN> run {

 allocate channel ch1 type disk;

 backup incremental level 2 cumulative database format '/orabak/fulldb_%s_%t.bak';

 release channel ch1;

 }


一個完整的資料庫還原,必須逐步的還原 Spfile 、 Control File 與 Data File ,最後再 apply 所需的 archive log , RMAN 提供了特殊的啟動指令 "startup force nomount" ,有了這個指令可以不需要任何的參數檔暫時的啟動 Database Instance ,透過這個暫時的啟動,我們就可以用來還原參數檔 spfile ,還原完 spfile 再正常地將 instance 啟動至 nomount :

$ rman target /

RMAN> startup force nomount;

RMAN> restore spfile from '/orabak/spfile_20211004_470aonnu_1_1';

RMAN> shutdown immediate

RMAN> startup nomount


還原完 spfile 之後,接下來必須要還原 Control File ,由於資料庫的備份資訊都存放在 Control File 裡面,所以必須將 Control File 還原,有了備份資訊,接下來系統才能夠逐步找到備份檔來還原 Data File :

RMAN> restore controlfile from '/orabak/controlfile_132_1085038213';

RMAN> alter database mount;


順帶一提,如果是使用 NBU 備份,則可以使用 NBU 命令 "bplist -t 4 -l -R /" 來檢視備份檔。


還原完 Control File 之後,就可以簡單執行 restore 與 recover 命令來還原整個資料庫,此時系統就會自動的從 Control File 裡面所記錄的備份資訊抓取所需的備份檔來還原:

RMAN> restore database;

RMAN> recover database;


更進階一點,可以使用 set 指令來指定要還原到哪個時間點或 scn , set 指令必須放入 RUN{} 裡面來執行:

RMAN> run {

set until scn 99410585;

restore database;

recover database;

 }

  (指定還原到哪個 SCN)

RMAN> run {

set until time "to_timestamp('20211005 17:00:00','yyyymmdd hh24:mi:ss')";

restore database;

recover database;

 }

  (指令還原到哪個時間點)


還原完畢後就可以將資料庫開啟,完成整個步驟:

$ sqlplus / as sysdba

SQL> alter database open resetlogs;


由於備份紀錄存放在 Control File 當中,因此 Control File 顯得相對重要,如果 Control File 遺失,那麼很有可能就無法還原整個資料庫,為了避免這個問題,我們可以建立一個 Catalog DB ,將備份的紀錄存放在 Catalog DB 當中,如此一來等於多添加了一份保險。


建立 Catalog DB ,實際上就是建立一個 DB ,然後把經由 RMAN 備份的資料庫的備份資訊存放在這個 DB 當中,一個 Catalog DB 可以存放多個 DB 的備份資訊,這邊要注意的是, Catalog DB 的字元集必須要是這些 DB 的 Superset ,且資料庫版本必須要大於或等於這些 DB ,例如經由 RMAN 備份的 DB 有 11.2.0.2 、 10.2.0.4 、 12.1.0.1 …等版本,那麼在 Catalog DB 建置的挑選上,就要選擇使用 12.1.0.1 的版本。


建置 Catalog DB ,首先必須先創立一個 Catalog 的使用者,並授予recovery_catalog_owner 的權限,例如創建一個使用者 RCAT作為 Catalog 的使用者:

SQL> create user rcat identified by welcome1 default tablespace users;

SQL> grant connect,resource,recovery_catalog_owner to rcat;


使用者創建完成後,接下來要創建 Catalog 所使用的物件,使用 RMAN 登入 Catalog DB ,並執行 create catalog 建立物件,這樣就完成 Catalog DB 的建置:

$ rman catalog rcat/welcome1@catalogdb

RMAN> create catalog;


建置完 Catalog DB 後,接下來就是要把需要存放備份資訊的 DB 註冊進來,例如將 orcl 這個資料庫註冊到 Catalog DB:

$ export ORACLE_SID=orcl

$ rman target / catalog rcat/welcome1@catalogdb

RMAN> register database;


註冊完成後,可執行 report schema 來檢查,如果有列出此 DB 的相關資訊,那麼就表示有註冊成功:


有了 Catalog DB 後,那麼在備份的同時就可以將備份紀錄存放到 Catalog DB 當中:

$ rman target / catalog rcat/welcome1@catalogdb

RMAN> run {

 allocate channel ch1 type disk;

 backup incremental level 0 database format '/orabak/fulldb_%s_%t.bak';

 release channel ch1;

 }        


對於資料庫還原來說,我們只需要藉由 Catalog DB 把 Control File restore 回來:

$ rman target / catalog rcat/welcome1@catalogdb

RMAN> startup nomount;

RMAN> restore controlfile;

RMAN> alter database mount;

RMAN> exit;

$ rman target /

RMAN> restore database;

RMAN> recover database;

RMAN> alter database open resetlogs;


Control File 還原回來後,因為所有的備份資訊 Control File 都有紀錄,因此接下來的還原過程就不需要 Catalog DB 了。


目前 RMAN 已經是 Oracle 資料庫最主要的備份還原方式了, DBA 必須要對這項工具非常熟悉才行。



2021年10月1日 星期五

11.1 冷備份與熱備份

Oracle 資料庫的備份方式可以分為兩類,冷備份與熱備份,冷備份指的是在資料庫完全靜止的狀態之下進行備份;而熱備份則是在資料庫處於運行的狀態之下進行備份。


Oracle 資料庫是由 Control File 、 Data File … 等檔案所構成,所以資料庫備份就是針對這些檔案來做備份,使用冷備份必須把資料庫 shutdown ,讓資料庫完全處於靜止的狀態,然後把 Control File 、 Data File … 等檔案複製起來做一個備份,結束後再重新將資料庫 startup ,這樣一個過程就完成了冷備份。

SQL> shutdown immediate

SQL> exit;

$ cp /u01/oradata/* /u01/orabak

$ sqlplus / as sysdba

SQL> startup


使用冷備份的資料庫還原,只需要把複製出來的備份檔案再 copy 回來,這樣就完成了資料庫還原的動作,這邊要注意的是,由於冷備份是在資料庫完全處於靜止的狀態之下將所有檔案複製出來,因此還原的時候必須把所有檔案一起複製回來,不能只單獨還原某一個檔案。


在某種程度上,使用 export (Datapump) 的方式將資料進行備份,也屬於冷備份的一種,雖然執行 export 的時候資料庫無須 shutdown ,但 export 出來的資料是當下做 export 那個時間點的資料,並不會包括後續的資料異動,例如在每日的 02:00 進行 export 的動作,如果早上 10:00 資料庫有異狀需要進行還原,那麼 import 回來也只有 02:00 那個時間點的資料, 02:00 ~ 10:00 中間的異動等於就遺失了。


熱備份是在資料庫運行的狀態之下進行備份,資料庫必須是使用 archive log 模式才能夠使用熱備份,藉由 archive log 不僅可以讓資料庫在運行的狀態之下進行備份,而資料庫還原的時候更可以讓資料庫還原到最接近現在的時間點,減少中間資料的遺失。熱備份同樣也是把資料庫的檔案複製備份出來,只是在資料庫運行的當下必須先使用 alter database begin backup 指令,然後再複製檔案,複製結束後再使用 alter database end backup ,這樣就完成了一個熱備份。

SQL> alter database begin backup;

SQL> !cp /u01/oradata/* /u01/orabak

SQL> alter database end backup;


熱備份的原理是在執行 begin backup 的當下,資料庫會暫時把 Data File 的 SCN 凍結起來不再更新,雖然凍結了 SCN 但不會影響到資料庫的運行,這時間所發生的交易都會保存在 archive log 當中,當備份結束後執行了 end backup ,此時資料庫會 apply 這中間所產生的 archive log ,讓 Data File 的 SCN 更新到目前的時間點。由於 archive log 在熱備份當中扮演了重要的角色,因此在備份檔案的時候不要忘了將 archive log 複製備份起來。


使用熱備份的還原,同樣的是把備份的檔案 copy 回來,與冷備份不同的是,將熱備份的檔案 copy 回來之後,可以再使用 archive log 將資料庫還原到最接近現在的時間點,將資料庫開啟到 mount 狀態,使用 recover database until cancel using backup controlfile開始 apply archive log :

SQL> !cp /u01/orabak/* /u01/oradata

SQL> startup mount

SQL> recover database until cancel using backup controlfile;


執行了 recover 之後,系統會提示所需要的 archive log 序號以及檔案:


系統會顯示 archive log 的檔案位置,如果位置正確的話,可以使用 AUTO 讓資料庫自行 apply 所有需要的 archive log ,如果路徑不正確的話,也可以自行提供 archive log 檔案的絕對路徑給它:


資料庫會一直 apply archive log 直到找不到下一個檔案為止,例如上述以經 apply 到 #41 號的 archive log ,而此時 #42 序號的交易可能還在線上的 Redo Log 裡面還沒 switch 出來,如果線上的 Redo Log 沒有遺失的話,此時可以提供線上的 Redo Log 讓它 recover ,這樣的話就可以達到完整的資料庫還原,資料是完全沒有遺失的;如果線上的 Redo Log 已經遺失不存在了,那麼我們就只能 apply 到 #41 這個序號,這樣就會損失一個 Redo Log 的交易資料,雖然如此,但熱備份的還原已經是可以還原到最接近現在的時間點了。


recover 完成後,使用 alter database open resetlogs 將資料庫開啟,完成資料庫還原的程序:


由於有 archive log 的存在,因此熱備份是可以只單獨還原某一個檔案的,同樣需經過 recover 的程序,例如單獨將 users01.dbf 這個檔案進行還原:

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

SQL> !cp /u01/orabak/users01.dbf /u01/oradata/

SQL> recover datafile '/u01/oradata/users01.dbf';

SQL> alter database datafile '/u01/oradata/users01.dbf' online;


實務上來說,資料庫系統必須 7x24 不停地提供服務,不太會為了備份而將資料庫 shutdown ,因此冷備份很少使用,幾乎都是以熱備份為主要的方式。