redo與undo

redo(重做信息)是Oracle在在線(或歸檔)重做日誌文件中記錄的信息,萬一出現失敗時可以利用這些數據來“重放”(或重做)事務。
Oracle維護着兩類重做日誌文件:在線(online)重做日誌文件和歸檔(archived)重做日誌文件。
數據庫所在主機掉電,導致實例失敗,Oracle會使用在線重做日誌將系統恰好恢復到掉電之前的那個時間點。
如果磁盤驅動器出現故障(這是一個介質失敗),Oracle會使用歸檔重做日誌以及在線重做日誌將該驅動器上的數據備份恢復到適當的時間點。
歸檔重做日誌文件實際上就是已填滿的“舊”在線重做日誌文件的副本

undo(撤銷信息)是Oracle在undo段中記錄的信息,用於取消或回滾事務。


redo與undo協作:
insert,updata,delete語句都會生成redo和undo。

提交和回滾處理:

commit之前數據庫已經完成的工作:
1已經在SGA中生成了undo塊。
2已經在SGA中生成了已修改數據塊。
3已經在SGA中生成了對於前兩項的緩存redo。
4取決於前三項的大小,以及這些工作花費的時間,前面的每個數據(或某些數據)可能已經刷新輸出到磁盤。
5已經得到了所需的全部鎖。
commit的工作:
1爲事務生成一個SCN。SCN是Oracle使用的一種簡單的計時機制,用於保證事務的順序,並支持失敗恢復。SCN還用於保證數據庫中的讀一致性和檢查點。可以把SCN看作一個鐘擺,每次有人COMMIT時,SCN都會增1.
2LGWR將所有餘下的緩存重做日誌條目寫到磁盤,並把SCN記錄到在線重做日誌文件中。如果出現了這一步,即已經提交。事務條目會從V$TRANSACTION中“刪除”,這說明我們已經提交。
3V$LOCK中記錄這我們的會話持有的鎖,這些所都將被釋放,而排隊等待這些鎖的每一個人都會被喚醒,可以繼續完成他們的工作。
4如果事務修改的某些塊還在緩衝區緩存中,則會以一種快速的模式訪問並“清理”。
rollback的工作:
1撤銷已做的所有修改。其完成方式如下:從undo段讀回數據,然後實際上逆向執行前面所做的操作,並將undo條目標記爲已用。如果先前插入了一行,ROLLBACK會將其刪除。如果更新了一行,回滾就會取消更新。如果刪除了一行,回滾將把它再次插入。
2會話持有的所有鎖都將釋放,如果有人在排隊等待我們持有的鎖,就會被喚醒。

測量redo
mystat.sql統計初始值(如redo大小)保存在一個SQL*Plus變量中:
set verify off
column value new_val V
define S="&1"
set autotrace off
select a.name, b.value
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
and lower(a.name) like '%' || lower('&S')||'%'

mystat2.sql腳本只是打印出該統計的初始值和結束值之差:
set verify off
select a.name, b.value V, to_char(b.value-&V,'999,999,999,999') diff
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
and lower(a.name) like '%' || lower('&S')||'%'

執行:
@mystat "redo size"
@mystat2


關閉redo不是不生成日誌,而是減少生成日誌。
方法有:
1把NOLOGGING關鍵字潛在SQL命令中
2在段(索引或表)上設置NOLOGGING屬性,從而隱式地採用NOLOGGING模式來執行操作。例如,可以把一個索引或表修改爲默認採用NOLOGGING模式。這說明,以後重建這個索引不會生成日誌(其他索引和表本身可能還會生成redo,但是這個索引不會);

可以採用nologging模式執行的操作。
1索引的創建和ALTER(重建)。
2表的批量INSERT(通過/*+APPEND */提示使用“直接路徑插入“。或採用SQL*Loader直接路徑加載)。表數據不生成redo,但是所有索引修改會生成redo,但是所有索引修改會生成redo(儘管表不生成日誌,但這個表上的索引卻會生成redo!)。
3LOB操作(對大對象的更新不必生成日誌)。
4通過CREATE TABLE AS SELECT創建表。
5通過CREATE TABLE AS SELECT創建表。

臨時表和redo/undo:
修改臨時表中的一個塊時,不會將這個修改記錄到重做日誌文件中。不過,臨時表確實會生成undo,而且這個undo會計入日誌。因此,臨時表也會生成一些redo。

在臨時表上的DML操作:
1INSERT會生成很少甚至不生成undo/redo活動。
2DELETE在臨時表上生成的redo與正常表上生成的redo同樣多。
3臨時表的UPDATE會生成正常表UPDATE一半的redo。

undo生成的大小一般來講,
INSERT生成的undo最少,因爲Oracle爲此需記錄的只是要“刪除”的一個rowid(行ID)。
UPDATE一般排名第二(在大多數情況下)。對於UPDATE,只需記錄修改的字節。你可能只更新(UPDATE)了整個數據行中很少的一部分,這種情況最常見。因此,必須在undo中記錄行的一小部分。
與加索引列的更新相比,對一個未加索引的列進行更新不僅執行得更快,生成的undo也會好得多。
DELETE生成的undo最多。對於DELETE,Oracle必須把整行的前映像記錄到undo段中。
發佈了11 篇原創文章 · 獲贊 7 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章