標籤:redo undo oracle redo
《Oracle------redo》
重做記錄檔(redo log file)對資料庫來說至關重要,他們是資料庫的交易記錄;
Oracle資料庫維護著兩類重做記錄檔:線上重做記錄檔(redo)和 歸檔重做記錄檔(archive log),(歸檔重做記錄檔實際上就是已填滿的“舊”線上重做記錄檔的副本)
這兩類重做記錄檔都是用於恢複的:
①:如果資料庫所在主機掉電,導致執行個體失敗,Oracle會使用線上重做日誌將系統復原到恰好在掉電之前的那個提交點;
②:如果磁碟機出現故障(這是介質失敗),Oracle會使用歸檔重做日誌以及線上重做日誌,以及之前的一個備份,將原在此磁碟機上的資料恢複到某個時間點;
每個Oracle資料庫都至少有兩個線上重做日誌,每個組中至少有一個成員(重做記錄檔),線上重做日誌組會以迴圈的方式使用;
Redo log的日誌狀態分為4種:
current:指的是當前記錄檔,該記錄檔是活動的,當前正在被使用的,進行崩潰恢複時,Current記錄檔是必須的;
ACTIVE:是活動的非當前日誌,可以已經完成歸檔也可能沒有歸檔,在Crash恢複時會被用到;
inactive:非活動紀錄,在執行個體恢複時不再需要,但是在介質恢複時可能會用到,此狀態的日誌也可能沒有被歸檔。
unused:該日誌從未被寫入,這類日誌可能是剛被添加到資料庫或者在resetlogs之後被重設。
《Oracle----undo》
REDO是為了重新實現你的操作,而UNDO相反,是為了撤銷你做的操作,比如你得一個TRANSACTION執行失敗了或你自己後悔了,則需要用ROLLBACK命令回退到操作之前。復原是在邏輯層面實現而不是物理層面,因為在一個多使用者系統中,資料結構,blocks等都在時時變化,比如我們INSERT一個資料,表的空間不夠,擴充了一個新的EXTENT,我們的資料儲存在這新的EXTENT裡,其它使用者隨後也在這EXTENT裡插入了資料,而此時我想ROLLBACK,那麼顯然物理上講這EXTENT撤銷是不可能的,因為這麼做會影響其他使用者的操作。所以,ROLLBACK是邏輯上復原,比如對INSERT來說,那麼ROLLBACK就是DELETE了。
注意:redo是用於在失敗時恢複事務,undo則用來取消一條語句或一組語句的作用。與redo不同,undo是儲存在資料庫內部一組特殊的段中,稱為undo段
1、insert:
第一條insert into t 語句會同時產生redo和undo,它鎖產生的undo資訊足以使insert小時,而redo資訊則足以讓這個insert再次發生;我們可以看到,塊緩衝區裡面存放著修改完的undo塊、索引塊、和表資料區塊,所有的這些塊都被重做日誌緩衝區中相應條目所保護;
2、update
update 產生的undo量更大,比insert要大,這是因為由於update需要儲存資料修改前的映像;update語句還放在重做日誌緩衝區中;
3、delete:
delete會產生undo,塊被修改,並把redo發送到重做日誌緩衝區;
4、commit
當事務提交時,Oracle會把重做日誌緩衝區重新整理輸出到磁碟;
注意:
insert產生的undo最少;(因為Oracle只是記錄了一個rowid)
delete產生的undo最多;(因為Oracle必須把整行的刪除前映像記錄到undo段中)
(索引的維護也是很高的,比如要更新有索引的列 那麼會產生好幾倍的undo)
commit的開銷主要來自兩方面:
第一:用戶端與資料庫直接往返通訊量將會顯著增大
第二:每次提交,都必須等待redo寫至磁碟(在這種情況下,就會出現log file sync的等待事件)
執行commit時,剩下的工作:
1、為事務產生一個SCN號
2、LGWR將所有未寫入磁碟的重做日誌條目寫至磁碟,並把SCN記錄到線上重做記錄檔中;
3、v$lock中會記錄著我們的回話鎖,這些鎖都將被釋放,而排隊等待這些鎖的會話都會被喚醒,從而可以繼續完成他們的工作;
4、如果事務修改的某些塊還在緩衝區快取中,Oracle就會以一種快速的模式訪問並清理;
redo 與 undo 日誌的主要區別:
1、undo日誌:在恢複時取消未完成事務的影響,忽略已經提交的事務
2、redo日誌:忽略未完成的事務,重做已經提交事務的改變。
3、undo日誌:先將修改後的資料寫到磁碟——寫commit到磁碟
4、redo日誌:先寫commit到磁碟——將修改後的資料寫到磁碟
5、undo日誌:要求資料在事務結束後立即寫到磁碟,可能增加磁碟IO數
6、redo日誌:要求我們在事務提交和日誌記錄重新整理以前將所有修改過的塊保留在緩衝區,可能增加事務需要的平均緩衝區數
《暫存資料表和redo、undo》
在12C之前:
暫存資料表的資料區塊不會產生redo,因此,暫存資料表的操作不是可恢複的。不過暫存資料表會產生undo,而且這個undo會計入日誌,因此,暫存資料表也會產生一些redo;暫存資料表可以有約束,也可以這麼說:正常表有的一切暫存資料表都可以有;
暫存資料表的DML操作,有如下特點:
1、insert會產生很少甚至不產生undo redo
2、暫存資料表的update會產生永久表update大約一半的redo
3、delete在暫存資料表上產生的redo與永久表上產生的redo同樣多;
(暫存資料表delete會產生很多redo,所以要避免進行delete操作,可以truncate;可以使用暫存資料表進行insert和select操作)
在12C之後:
從Oracle12C起,我們可以通過設定temp_undo_enabled來將暫存資料表的undo放在暫存資料表空間中,由於暫存資料表空間的任何資料變更都不會產生redo,所以當這個參數設定為TRUE時,任何暫存資料表上的DML都會生產很少甚至不會產生redo;
(temp_undo_enabled的預設值是FALSE,如果將其改為TRUE的話,那暫存資料表產生的redo量與12C版本之前是一樣的)
ORA-01555: snapshot too old: -----這個錯誤是非常典型的錯誤:(它算的上是一個安全的錯誤,唯一的影響就是收到這個錯誤的查詢無法繼續處理)
產生這個錯誤的原因:
1、undo段太小,不足以支撐系統上執行的工作
2、程式誇commit擷取資料
3、塊清除
4、commit提交太頻繁
解決的方法參考:
1、適當的設定參數undo_retention(要大於已耗用時間最長的事務所需的時間),我們可以通過v$undostat 來確定長時查詢的期間,另外,請在磁碟上預留足夠的空間,因為為了確保undo_retention,undo段可能也會有所增長;
2、使用手動undo管理時加大或增加更多的undo段,(不建議採用這種方法,強烈建議採用自動undo管理方式)
3、減少查詢的已耗用時間(調優)。調優sql語句、
4、收集相關對象的統計資訊。
本文出自 “笨小孩的dba之路” 部落格,請務必保留此出處http://fengfeng688.blog.51cto.com/4896812/1934429
Oracle——redo+undo總結