重做日誌浪費 redo wastage

2021-09-06 00:20:08 字數 3759 閱讀 4677

oracle中聯機日誌檔案(online redo log)在大多平台上以512 位元組為乙個標準塊。 (hpux,tru64 unix上是1024bytes,sco unix,reliant unix上是2048bytes,而mvs,mpe/ix上是4096bytes,雖然以上許多unix已經不再流行,實際情況可以通過 select max(l.lebsz) log_block_size_kccle from sys.x$kccle l where l.inst_id = userenv('instance')   語句查詢到) lgwr後台程序寫出redo時未必能填滿最後的當前日誌塊。舉例而言,假設redo buffer中有1025位元組的內容需要寫出,則1025=512+512+1 共占用三個重做日誌標準塊,前2個標準塊被填滿而第三個標準塊只使用了1個位元組。在lgwr完成寫出前,需要釋放"redo allocation"閂,在此之前sga中索引"redo buffer"資訊的變數將指向未被填滿塊後面的乙個重做塊,換而言之有511位元組的空間被lgwr跳過了,這就是我們說的redo wastage;我們可以通過分析v$sysstat動態檢視中的redo wastage統計資訊了解例項生命週期中的重做浪費量。

sql> col name for a25

sql> select name,value from v$sysstat where name like '%wastage%';

name                           value

------------------------- ----------

redo wastage                  132032

redo wastage的乙個圖示:

為什麼要浪費這部分空間呢?實際上,這種做法十分有益於lgwr的序列i/o模式。redo wastage並不是問題或者bug,而是oracle故意為之的。當然過量的redo wastage也不是什麼好事,一般是lgwr寫出過於頻繁的症狀表現。9i以後很少有因為隱式引數_log_io_size過小而導致的lgwr過載了,如果在您的系統中發現redo wastage的問題不小,那麼無限制地濫用commit操作往往是引起問題的罪魁禍首,減少不必要的commit語句,把commit從迴圈中移除都將利於減少redo wastage。 我們來看一下關於redo wastage的演示:

sql> select distinct bytes/1024/1024 from v$log;

bytes/1024/1024

---------------

50 /*確認聯機日誌檔案大小為50mb*/

sql> archive log list; /*確認資料庫處於歸檔狀態*/

database log mode archive mode

automatic archival enabled

archive destination /s01/arch

sql> set time on;

19:49:45 sql> alter system switch logfile; /*切換日誌,清理現場*/

system altered.

19:51:07 sql> col name for a25

19:51:16 sql> select name,value from v$sysstat where name in ('redo size','redo wastage');

name value

------------------------- ----------

redo size 1418793324

redo wastage 88286544 /*演示開始時的基礎統計值*/

19:51:19 sql> begin

19:52:10 2 for i in 1..550000 loop

19:52:10 3 insert into tv values(1,'a');

19:52:10 4 commit;

19:52:10 5 end loop;

19:52:10 6 end;

19:52:11 7 /

/*匿名塊中commit操作位於loop迴圈內,將導致大量redo wastage*/

pl/sql procedure successfully completed.

19:53:07 sql> select name,value from v$sysstat where name in ('redo size','redo wastage');

name value

------------------------- ----------

redo size 1689225404

redo wastage 112011352

/*頻繁提交的匿名塊產生了 1689225404-1418793324=257mb的redo,其中存在112011352-88286544=22mb的redo wastage*/

19:53:14 sql> begin

19:53:33 2 for i in 1..550000 loop

19:53:33 3 insert into tv values(1,'a');

19:53:33 4 end loop;

19:53:33 5 commit;

19:53:33 6 end;

19:53:34 7 /

/* 此匿名塊中commit操作被移除loop迴圈中,批量修改資料後僅在最後提交一次*/

pl/sql procedure successfully completed.

19:53:59 sql> select name,value from v$sysstat where name in ('redo size','redo wastage');

name value

------------------------- ----------

redo size 1828546240

redo wastage 112061296

/*稀疏提交的匿名塊最後產生了1828546240-1689225404=132mb的重做,而redo wastage為112061296-112011352=48k*/

可能您會很奇怪前者不是只比後者多出22mb的redo浪費嗎,為什麼總的redo量差了那麼多? 我們需要注意到commit本身也是要產生redo的,而且其所產生的還不少!就以上演示來看頻繁提交的過程中,commit所占用的redo空間幾乎接近一半(257-132-22)/257=40%,而每次commit的平均redo量為(257-132-22)*1024*1024/550000=196 bytes。

commit操作是事務acid的基礎之一,合理運用commit可以幫我們構建健壯可靠的應用,而濫用它必將是另一場災難!

聯機重做日誌

兩點 1.利用重做日誌檔案,在資料庫發生故障時,可以重新處理事務。維護一致性 2.記錄資料所做的所有更改,提供恢復機制,可以劃分成組,至少需要兩個組,每個組至少乙個成員。規劃原則 分散放開到不同的磁碟,日誌所在盤io要足夠,io讀寫要快。分散到不同的磁碟的好處,解決io的衝突,解決因故障,日誌不可用...

MySQL重做日誌

用來實現事物的永續性,即事務acid中的d。重做日誌有兩部分組成 當事務commit時,必須將事務的全部日誌寫入重做日誌檔案進行持久化,待完成後事務commit的操作才算完成,即日誌前寫規則。為確保每次日誌都寫入到重做日誌檔案,在每次寫入後都進行一次fsync操作。因為重做日誌檔案沒有使用o dir...

mysql重做日誌

mysql預設情況下會有兩個檔案 ib logfile0和ib logfile1,這兩個檔案就是重做日誌檔案,或者事務日誌。重做日誌的目的 萬一例項或者介質失敗,重做日誌檔案就能派上用場。每個innodb儲存引擎至少有乙個重做日誌檔案組,每個檔案組下至少有2個重做日誌檔案,如預設的ib logfil...