2022年4月6日 星期三

3. 建立 Physical Standby

建立 Physical Standby 的流程大致如下:

前置作業設定 🡪 資料庫參數設定 🡪 初始化 Standby 🡪 開啟 MRP 同步


  • 前置作業設定

在進行 Physical Standby 建置之前,有幾個前置作業必須要先進行,首先 Primary 資料庫必須是 Archive Log Mode ,並且啟用 force logging :

SQL> alter database force logging;

SQL> select force_logging from v$database; (進行確認)


於 Primary 資料庫添加 Standby Redo Log , Standby Redo Log 在 Primary 資料庫上是沒有任何用途的,不過考量未來有可能進行 Data Guard 的角色切換, Primary 有可能切換為 Standby ,因此在這邊就先幫 Primary 添加 Standby Redo Log ,除此之外,在 Primary 先添加的好處是,在資料庫初始化階段也會把 Standby Redo Log 的設定帶過去,到時候 Standby Database 就不用再加一次了。 Standby Redo Log 的 Group 數量與大小至少要與 Primary 的 Online Redo Log 數量相同:

SQL> alter database add standby logfile group 4 '/u01/oradata/orcl/stdby_redo01.log' size 200M;

SQL> alter database add standby logfile group 5 '/u01/oradata/orcl/stdby_redo02.log' size 200M;

SQL> alter database add standby logfile group 6 '/u01/oradata/orcl/stdby_redo03.log' size 200M;


如果是 RAC Database ,則每個節點都必須添加 Standby Redo Log :

SQL> alter database add standby logfile thread 1 group 4 '/u01/oradata/orcl/stdby_redo01.log' size 200M;

SQL> alter database add standby logfile thread 1 group 5 '/u01/oradata/orcl/stdby_redo02.log' size 200M;

SQL> alter database add standby logfile thread 1 group 6 '/u01/oradata/orcl/stdby_redo03.log' size 200M;

SQL> alter database add standby logfile thread 2 group 7 '/u01/oradata/orcl/stdby_redo04.log' size 200M;

SQL> alter database add standby logfile thread 2 group 8 '/u01/oradata/orcl/stdby_redo05.log' size 200M;

SQL> alter database add standby logfile thread 2 group 9 '/u01/oradata/orcl/stdby_redo06.log' size 200M;


接下來於 tnsnames.ora 添加 Primary 與 Standby Database 的連線設定:

ORCL_P =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.49.250)(PORT = 1521)))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orcl)))


ORCL_S =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.49.150)(PORT = 1521)))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orcldg)))


ORCL_P 代表為 Primary 資料庫, ORCL_S 表示為 Standby , Primary 端與 Standby 端的 tnsnames.ora 都需要設定。


最後將 Primary 資料庫的 password file 複製到 Standby 端,這邊要注意的是,如果 Standby 端的 SID 與 Primary 不同,則複製過去的 password file 必須修改為 Standby 端的 SID 名稱。


  • 資料庫參數設定

建立 Data Guard 有幾個相關的參數設定,首先在 Primary 端設定參數如下:

SQL> alter system set log_archive_dest_1='location=USE_DB_RECOVERY_FILE_DEST valid_for=(all_logfiles,all_roles) db_unique_name=orcl';

SQL> alter system set log_archive_dest_state_2='defer';

SQL> alter system set log_arcihve_dest_2='service=orcl_s lgwr async noaffirm optional reopen=180 valid_for=(online_logfiles,primary_role) db_unique_name='orcldg';

SQL> alter system set log_archive_config='dg_config=(orcl,orcldg) ';

SQL> alter system set standby_file_management='AUTO';

SQL> alter system set fal_server='orcl_s';

SQL> alter system set fal_client='orcl_p';


log_archive_dest_1 表示本地 Primary 的 archive log 存放位置,除了原本的 location 參數外,須加上 valid_for 參數, all_logfiles 表示所有的 redo log 都適用此設定、 all_roles 表示資料庫在任何角色都適用此設定; db_unique_name 設定 Primary 資料庫的 unique name ,為 orcl 。


log_arcihve_dest_2 表示添加另一個 archive log 路徑, service=orcl_s 表示 archive log 使用 service name 傳送過去,這邊設定 orcl_s 表示傳送到所設定的 standby 資料庫; lgwr async 表示使用 lgwr 這個 process 並且以 async 模式進行傳送; noaffirm 表示在 Standby 接收到交易之後,不等它寫入到 Standby Redo Log 就當作是完成傳送; optional reopen=180 表示傳送失敗後,等待 180 秒之後進行 retry ; valid_for 參數, online_logfiles 表示只有 Online Redo Log 適用此設定、 primary_role 表示資料庫只有在為 Primary 時才套用此設定; db_unique_name 設定 Standby 資料庫的 unique name ,為 orcldg 。


log_archive_dest_state_2 先設為 defer ,由於 Standby 資料庫還沒建立起來,因此在這一階段的 Primary 先不用進行 archive log 傳送。


log_archive_config 設定 Data Guard 裡面的成員名單, dg_config 設定的是資料庫的 unique name ,代表目前 Data Guard 總共有兩個成員, orcl 與 orcldg 。


當 Primary 與 Standby 有 archive log gap 時,就必須透過 FAL 機制來補足缺少的 archive log , fal_server 設定的是對面的資料庫,這邊是 Primary 所以設定 fal_sever 為 Standby 的連線字串 orcl_s ; fal_client 設定的是自己的連線字串 orcl_p 。


在 Primary 端設定完參數之後,接下來就要建立 Standby 端的參數,由 Primary 建立 pfile 之後,然後進行微調如下,作為 Standby 端的參數 :

*.log_archive_dest_1='location=USE_DB_RECOVERY_FILE_DEST valid_for=(all_logfiles,all_roles) db_unique_name=orcldg';

*.log_archive_dest_state_2='defer';

*.log_arcihve_dest_2='service=orcl_p lgwr async noaffirm optional reopen=180 valid_for=(online_logfiles,primary_role) db_unique_name='orcl';

*.db_unique_name='orcldg'

*.log_archive_config='dg_config=(orcl,orcldg)';

*.standby_file_management='AUTO';

*.fal_server='orcl_p';

*.fal_client='orcl_s';


log_archive_dest_1 的 unique name 改為 Standby 端的 orcldg ,其餘相同。


log_archive_dest_2 的 service 改為 orcl_p ,當有一天做角色切換時, archive log 要反過來傳送回 orcl_p ; unique name 改為 Primary 端的 orcl ,其餘設定相同。


db_unique_name 須設定與 Primary 不同,這邊 Standby 設定為 orcldg 。


standby_file_management 須設定為 AUTO ,表示當 Primary 有進行 Data File 增減時, Standby 端自動的同步增減。


fal_server 與 fal_client 則與 Primary 反過來設定。


在兩邊的參數都設定好之後,接下來就可以進行 Standby 資料庫的初始化。


  • Standby 資料庫初始化

Standby 資料庫的初始化大致上可以使用下列幾個方法來進行:


 1. Cold Backup 

  Standby 資料庫本質上是與 Primary 相同的,因此如果 Primary 在可以 Shutdown 停止的情況下,只要在 Primary 建立一個 Standby Control File ,並且將 Standby Control File 與所有的 Data File 複製到 Standby 端,這樣就完成一個 Standby 的初始化。

SQL> alter database create standby controlfile as '/tmp/stdby_control01.ctl'


2. RMAN Backup Restore

  在多數的情況下, Primary 是無法停止的,因此 1 的理想方式可以使用的機會不多,在 Primary 還在運行的情況下,可以使用 RMAN Backup 先將 Primary 備份起來,然後將備份檔案傳送到 Standby 端進行 Restore ,在 Primary 備份的時候,要把 Control File 備份為 Standby Control File :

run {

allocate channel ch1 type disk;

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

backup current controlfile for standby format '/opt/app/dump/rman/controlfile_%s_%t';

release channel ch1;

}


Primary 備份完之後將備份檔傳送到 Standby 進行 Restore :

RMAN> startup nomount

RMAN> restore standby controlfile from '/opt/app/dump/rman/controlfile_13_10850313';

RMAN> sql 'alter database mount';

RMAN> restore database;


Restore 結束後便完成了 Standby 的初始化。


3. 使用 duplicate from active database

  使用 2 來進行初始化的缺點是,如果資料庫比較龐大,而 Standby 端又沒有那麼大的空間來存放備份檔,那麼 RMAN Backup Restore 將難以進行,從 Oracle 11gR2 開始可以使用 duplicate from active database 來建立 Standby ,好處是直接透過 Oracle Net 還原 Standby ,不需要額外的空間來存放落地的備份檔,在進行 duplicate from active database 之前, Standby 要設定可以使用 RMAN auxiliary 連線,為了這個連線,要於 Standby 的 listener.ora 設定一組靜態註冊如下:

SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (GLOBAL_DBNAME = orcl)

      (ORACLE_HOME = /opt/app/oracle/product/11.2.0.4/dbhome_1)

      (SID_NAME = orcl)))


將 Standby 資料庫開啟至 nomount 之後,使用 RMAN 連線至 target (primary) 與 auxiliary (standby) ,這邊要注意的是,連線的時候必須提供 sys 的帳號密碼,不可使用 "/" 登入,否則會 duplicate 失敗:

$ rman target sys/welcome1@orcl_p auxiliary sys/welcome1@orcl_s


然後就可以進行 duplicate from active database :

run {

allocate channel prmy1 type disk;

allocate auxiliary channel stby type disk;

duplicate target database for standby nofilenamecheck from active database;

}


duplicate 結束後就完成了 Standby 的初始化。


4. 使用 Restore from Service

  Oracle 12c 開始添加了新功能 Restore from Service ,比起原先 duplicate from active database 方便的是無須再使用 auxiliary 連線,整體操作起來更為方便。將 Standby 開啟至 nomount 之後便可以進行 Restore from Service ,與 3 不同的是, duplicate from active database 無需自行 Restore Standby Control File ,而 Restore from Service 必須先 Restore Standby Control File :

$ rman target sys/welcome1@orcl_s

RMAN> restore standby controlfile from service orcl_p;

RMAN> alter database mount;

RMAN> restore database from service orcl_p;

RMAN> switch database to copy;


如果 Primary 的 Data File 使用的是 OMF 格式的話,那麼 Restore from Service 結束後必須再執行 switch database to copy 。


  • 開啟 MRP 同步

在 Standby 初始化完成之後,接下來就可以進行同步,首先要先開啟 Primary 的 log shipping ,將參數 log_archive_dest_state_2 改為 enable 開始傳送 archive log :

SQL> alter system set log_archive_dest_state_2='enable';


然後至 Standby 開啟 MRP :

SQL> alter database recover managed standby database using current logfile disconnect;


使用 using current logfile 表示啟用 real-time apply ,不過至 Oracle 12c 開始,預設已經是 real-time apply 了,不用特別再使用 using current logfile 。


如果要啟用 Active Data Guard ,則必須把 Standby 開啟後再進行 apply :

SQL> alter database recover managed standby database cancel;

SQL> alter database open;

SQL> alter database recover managed standby database using current logfile disconnect;


檢查 Standby 的同步狀態,可以簡單的由 Standby 查詢 v$archive_log 來檢視 archive 序號是否有持續同步:

SQL> select sequence#, applied, first_time, next_time from v$archived_log  where applied='YES' order by sequence#;

如果 Standby 的 archive log 序號沒有與 Primary 同步,那麼就要同時檢視 Primary 與 Standby 的 alert log ,從中找尋發生問題的原因。


Archive Log 在 Data Guard 架構下,只要被使用過後就不會再需要了,可以將其刪除,對於 Primary 來說,只要 Archive Log 傳送到了 Standby 端,那麼對於 Data Guard 來說,這些 Archive Log 就不需要了,可以將這些已經傳送到 Standby 端的 Archive Log 刪除,一般來說 Primary 在使用 RMAN 備份的時候就會順便將 Archive Log 刪除,如果備份刪除到還未傳送到 Standby 的 Archive Log 時,就會出現 RMAN-08137: warning: archived log not deleted, needed for standby or upstream capture process 這個錯誤來防止 Archive Log 被刪除,除非使用 force 指令強制刪除,不然未傳送到 Standby 端的 Archive Log 是無法刪除的,這也算是 RMAN 對於 Data Guard 的一種保護機制吧。


對於 Standby 端來說,只要 Archive Log 被 Apply 之後就沒有作用了,可以將這些已經 Apply 的 Archive Log 刪除,可以透過 RMAN 設定一個排程來定期刪除這溪 Archive Log ,例如建立一個 del_arch.sh 來定期刪除兩天前的 Archive Log :

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0.4/dbhome_1

export PATH=$ORACLE_HOME/bin:$PATH

export ORACLE_SID=orcl

rman target / <<EOF

delete noprompt archivelog until time 'sysdate - 2';

exit;

EOF


如果 Archive Log 是設定在 Recovery Area 裡面,那麼就可以透過 RMAN設定 Archive Deletion Policy 來自動的刪除 Archive Log ,對於 Primary 來說,只要 Archive Log 已經傳送到 Standby 就可以刪除,所以設定為 shipped to all standby :

RMAN> configure archivelog deletion policy to shipped to all standby;


對於 Standby 來說,已經 Apply 的 Archive Log 就可以刪除,所以是 applied on standby :

RMAN> configure archivelog deletion policy to applied on standby;


設定完後在 RMAN 裡面可以使用 show all 指令來檢查設定,這邊要注意的是, RMAN 的 Archive Log Deletion Policy 只有在 Recovery Area 的空間即將額滿時才會觸發刪除 Archive Log 的動作,所以設定完沒有看到 Archive Log 被刪除並不是這個設定無效,而是 Recovery Area 的空間還沒有達到需要刪除這些檔案的臨界值。


Data Guard 架構下的 Archive Log 是需要定期維護清理的,如果 Standby 沒有安排清理,那麼這些 Archive Log 就會一直累積直到系統空間不足為止,刪除 Archive Log 的方式建議一律使用 RMAN 來清理,不要使用作業系統的指令例如 rm 來刪除 Archive Log ,避免誤刪了還沒被使用到的 Archive Log 造成 Data Guard 異常。

沒有留言:

張貼留言