redo與undo
最後更新:2018-07-23
來源:互聯網
上載者:User
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段中。