2021年3月26日 星期五

8.1 Oracle Redo Log

Oracle Redo Log 簡單來說就是用來記錄交易資訊的 Transaction Log,用途在於紀錄每一筆異動資料的紀錄,藉由這些交易紀錄,在進行資料庫還原時就可以將資料回復到之前最新的狀態。Redo Log 的內容會記錄每一筆交易的 Transaction ID、DML與DDL的SQL Statement,以及 Checkpoint/SCN 的資訊,在進行資料庫還原時,需要藉由 Redo Log 所記錄的SCN來恢復每個階段的交易,資料庫在 Apply 完所有 Redo Log 的交易資訊後,所有 Data File 的SCN便會一致,達成資料還原以及資料的完整與一致性。


在 Oracle 資料庫當中,Redo Log 是以 Group 的方式存在,每一個 Redo Log Group 可以有一個或多個 Redo Log File,在同一個 Group 裡面的 Redo Log File 稱為 Redo Log File Member,且每一個 Member 的內容都是相同的,建立多個 Member 的目的是可以互相作為備份,避免當有 Redo Log File 損壞而造成交易資訊的遺失。Redo Log Group 是以循環的方式來使用:


例如資料庫目前有四個 Redo Log Group,當 Redo Log Group 1 的 Redo Log File 被寫滿時,便會切換至下一個 Redo Log Group 2 繼續寫交易資訊,Group 2 被寫滿時再切換至 Group 3,同理 Group 3 寫滿後切換至 Group 4,而當 Group 4 被寫滿之後,便會把 Group 1 的內容清空然後循環回 Group 1 開始再寫交易資訊,如此不斷的循環。那麼把 Group 1 的內容清空,交易資訊不是會不見嗎 ? 為了避免這個問題,在 Redo Log 寫滿的時候會把所有的內容複製一份出來,而這些被複製出來的內容就稱作 Archive Log,如此就可以避免因為 Redo Log Group 的循環而造成交易資訊的遺失。


當交易發生時,並不會直接寫入到Redo Log,而是會先暫存在Log Buffer,然後再透過LGWR(Log Writer) 這個 Background Process寫入Redo Log:

當發生以下的現象時,便會觸發LGWR將資料寫入Redo Log:

  • 交易被 commit 時。

  • Log Buffer 以使用 1/3 時。

  • 發生 checkpoint 時。


由以上可知實際上交易資訊存放在 Log Buffer 時間並不長,因此Log Buffer實際上不需要設定太大,一般使用預設的32M就已經足夠。


除了等待 Redo Log寫滿之後切換,我們也可以透過 “alter system switch logfile” 這個命令來手動強制切換一個Redo Log Group。透過 v$log 與 v$logfile 可以知道目前所有Redo Log Group 的狀態:

SQL> select a.thread#,a.group#,a.sequence#,b.member,a.bytes/1024/1024 mb,a.status

        from v$log a,v$logfile b

     where a.group#=b.group# order by 1,2


Redo Log Group 會有四種狀態,ACTIVE、INACTIVE、CURRENT與UNUSED。CURRENT表示目前交易正在寫入這個 Group 的 Redo Log File;ACTIVE表示這個 Group 正在等待 Checkpoint;INACTIVE表示目前為閒置狀態,可以被使用;UNUSED表示這是一個新的 Group,裡面的 Redo Log File還從未被使用。


由 Redo Log Group的狀態欄可以得知,必須為 INACTIVE狀態的Group才可以重複再被使用,如果交易量太大導致Redo Log Group 切換速度過快,這時候可能造成所有的Group都為ACTIVE狀態,此時前端的交易就會產生等待的情形,直到有Group變為INACTIVE時,前端交易才有辦法再進行下去,這個時候在資料庫的 alert log 當中可能就會看到 “checkpoint not complete” 字樣,表示Redo Log 切換的速度趕不上交易產生的速度,這個時候就必須要增加 Redo Log Group,提供多一點的Group來切換,或者是增加Redo Log File的大小,減少切換的頻率來避免大交易量的問題。


Redo Log Group 或是Redo Log File Member可以在線上進行新增或刪除的動作,只要是狀態為 INACTIVE的Group就可以進行刪除,使用 alter database命令進行操作:

SQL> alter database add logfile group 4 '/oradata/ORA11/redo04.log' size 200M;

     (新增 group 4 且大小為 200M)

SQL> alter database add logfile member '/oradata/ORA11/redo04b.log' to group 4;

     (為 group 4 添加一個 Redo Log File)

SQL> alter database drop logfile group 5;

     (刪除 Redo Log Group 5)

SQL> alter database drop logfile member '/oradata/ORA11/redo05b.log';

     (刪除這一個 Redo Log File)


Redo Log File 的大小在建立後就無法更改,如果有變更 Redo Log 大小的需求,必須將他刪除後再重建才行。早期資料庫預設的Redo Log Size為50M,這大多時候是不足的,而現在版本的資料庫已經把預設值改為200M了。


Oracle 資料庫預設是 No archive log Mode,也就是說在預設的狀態下,Redo Log 的交易資訊會被覆蓋掉,當資料庫發生問題時便無法由備份還原到最新的狀態,只能還原到備份當下的時間點,而中間的交易資料便遺失了,所以一般來說都會將資料庫設定為 archive log Mode,以確保資料能夠被完全的保護,我們可以簡單的在 sqlplus 裡面使用 archive log list 命令來檢查目前設定是否為 archive log Mode:


在設定 archive log Mode 之前必須先設定兩個參數 log_archive_dest_1 與 log_archive_format,log_archive_dest_1 設定 archive log 存放的位置,可以指定一個或多個位置,log_archive_dest_n 可以從 1 ~ 31,最多可以設定 32 個 archive log 位置;log_archive_format 則是設定產出的 archive log 的格式(檔名),比較要注意的是,log_archive_format設定上必須包含 %s、%t與 %r 三個參數,%s表示交易的 sequence number、%t表示instance的thread number,%r則表示為 resetlogs number。


將log_archive_dest_1 設定為 use_db_recovery_file_dest 表示將 archive log 存放在 recovery area 裡面,如果是這個設定,那麼就還要先設定兩個參數db_recovery_file_dest與db_recovery_file_dest_size來指定 recovery area 的位置與大小,log_archive_dest_1 也可以設定在任何一個指定的目錄,例如設定將 archive log 存放至 /u01/app/arch 底下:

SQL> alter system set log_archive_dest_1='location=/u01/app/arch';


設定完參數之後,便可以將資料庫設定為 archive log Mode,在 mount 模式下使用 alter database archivelog 指令便可以設定為 archive log Mode;如果要設定為 No archive log Mode,則是使用 alter database noarchivelog 指令:


設定完 archive log Mode之後,可以馬上使用 “alter system switch logfile”,手動切換一個 Redo Log Group來檢查 archive log 是否有產生在指定的位置,驗證設定是否正確。




沒有留言:

張貼留言