Undo是幹嘛用的?
#為交易我們在進行一個事務的過程中需要申請許多資源,一個複雜的事務也需要很多步驟來完成。那麼一個複雜的事務就是只有兩個結果,要嘛成功,要嘛失敗(相當於從來沒發生過)。
一個很典型的列子,銀行轉賬,其實其需要兩步驟操作,第一步先將你帳戶上的錢減去,第二步把被轉帳戶的錢加上,這樣就是一個完整的交易。
如果執行了一半,你的錢減了,被轉帳戶的錢沒加上,這個時候事務就要回滾,回滾到原始狀態。也就是在轉帳之前,需要先記錄你和被轉帳戶上的金額。這就樣能保證,一旦事務失敗就回滾到事務的發生之前的狀態。
為那保證一個事務的原始性和完整性,就引這入undo 的概念。 Undo就是用來記錄保存事務操作過程中的數據,如果事務發生錯誤,可以先前的數據來填補。
Undo Segment 還原段:
#從來面的視圖,我們就可以很清楚的看出,我們要對錶(table)中的一個資料進行修改,在修改之前,先把舊的映像(old image)放到undo 上面。然後再在table中放入new image 。
假如過程失敗,我們還可以把undo 上的old image 再拿回來放在原先的位置,使這件事兒看起來像沒發生過一樣。
Undo segment 是保存在表空間上的。 Undo 大小是固定的,既然是固定的也就是有限的。如果保存的記錄非常多,那麼它就會被佔滿,新記錄的數據會覆蓋掉最早的數據。
所以用一個圓形的盤片能更有形象的表示。資料從一個位置開始寫入,當寫滿一圈後,最新的資料就會覆蓋最早寫入的資料。
undo可以做哪些事兒?
#Transaction rollback 事務反轉, Transaction recovery 事務恢復。事務反轉與事務恢復的效果是一樣的。事務反轉是人主動去做的,人在操作的過程中反悔了,相當於我在寫文件時按個ctrl z 。事務恢復是機器自動完成的,例如在事務進行過程中簡拼突然斷電了,下次重啟服務之後,系統自動回滾。
Read consistency 讀一執行。讀取一致性對於多用戶操作是非常重要的。如果你在多人開發中使用過版本控制工具(git\cvs\svn)的話,下面的概念你將會很容易理解。
Oracle 讀一致性概念
##為我知道數個作業記錄中所行的多個作業使用者時可以對多個作業進行資料時可以對每個資料庫執行的作業,這個過程可能需要幾分鐘。在這個過程中其它用戶對你查詢的資料時行了修改。這裡就要確保你查詢的結果是被修改之前的。 這裡明確一個概念,事務的開始,當我們執行一個(更新、修改、刪除)語句時;事務的結束,必須執行提交動作(執行commit 或 rollback 指令) #我們從上面的流程圖來理解oracle是如何保證讀取一致性的。 當我們執行一個交易的時候,oracle會分配一個SCN編號,這個編號是遞增的。下一個事務的編號一定比目前事務的編號大。 上圖中執行第一個事務分配的編號為10023,在這個事務執行的過程中,另一事務對SCN 編號為10008和10021的資料區塊進行了修改。用來替換的資料塊SCN編號為10024 ,而被替換掉的資料塊會被儲存到undo 上面。 當第一個交易執行到被修改過的資料區塊時,發現10024比10023大,這時候就會到undo segment上找比自己SCN號小的資料區塊進行讀,於是發找到了SCN號為10008和10021兩個區塊。這樣就有效的保證了讀一致性。當然,會有一種特殊情況,也就是undo segment 太小,最多放100條數據,可一下子來了120條數據,那麼最先寫入的20條數據被最後寫入的20條數據覆蓋。這時候就會報錯,這也是為什麼要調優資料據的原因。
Redo or Undo
什麼是Redo
Redo記錄transaction logs,分成online和archived。以恢復為目的。
例如,機器停電,那麼重起之後就需要online redo logs去恢復系統到失敗點。
例如,磁碟壞了,需要用archived redo logs和online redo logs區恢復資料。
什麼是Undo
Redo 是為了重新實現你的操作,而Undo相反,是為了撤銷你所做的操作。 Undo比較像是常用的ctrl z ,撤銷到上一步的狀態。而Redo 是也會記錄undo 的操作。
當我們插入一個資料時,首先這個動作會被記錄到redo log 中,操作也會被記錄到undo ,undo本身的動作也會被記錄到一筆數據被記錄到redo log ,插入一條數據,索引(indexes)會發生變化,索引的變化也會做一條數據被記錄到redo log 。 Redo 記錄著一個操作所有相關的訊息,這樣才能完整的保證場景的重現。
要說明的是在上面的圖表中,不管是undo 還是redo都是寫在記憶體裡的,一旦斷電,所有資訊將會消失。只有寫到磁碟上的資訊才不會因為斷電而消失。
是redo log 的資訊先寫到磁碟上的,因為它的資訊最全面,可以完整的保證場景重現。我們可以透過各種機制控制redo 寫磁碟,例如每隔3秒寫一次,或redo log檔案大於1MB寫一次。
如何設定使用undo ? 想使用undo 首先需要創建undo表空間。我們可以建立多個undo表空間,但只能有一個undo表空間是處於使用狀態。
檢視undo設定資訊:
SQL> show parameter undo NAME TYPE VALUE ------------------------------------ ---------------------------------------------------- undo_management string AUTO undo_retention integer 900 undo_tablespace string UNDOTBS1
Undo設定參數意義
-DNDO_MANAGEMENT undo的管理模式,分自動與手動
-UNDO_TABLESPACE 目前正在被 使用的undo表
-UNDO_RETENTION 規定多久內,資料不能被覆寫。
AUTO 表示undo 為自動管理模式。
900 表示在900秒內,undo上的資料無法被覆寫。
UNDOTBS1 是目前正在使用的undo表空間。
建立undo表空間,與建立一般的表空間類似,指令如下:
SQL> create undo tablespace myundotbs 2 datafile '/ora10/product/oradata/ora10/myundotbs1.dbf' size 10M; Tablespace created.
查看新建立的undo表空間
SQL> select tablespace_name,contents from dba_tablespaces; TABLESPACE_NAME CONTENTS ------------------------------------------------------------ ------------------ SYSTEM PERMANENT UNDOTBS1 UNDO //老的undo表空间 SYSAUX PERMANENT TEMP TEMPORARY USERS PERMANENT PAUL PERMANENT MYUNDOTBS UNDO // 新创建的undo表空间 SQL> show parameter undo 再次查看当前使用的表空间 NAME TYPE VALUE ------------------------------------ ---------------------------------------------------- undo_management string AUTO undo_retention integer 900 undo_tablespace string UNDOTBS1
切換undo表空間:
SQL> alter system set undo_tablespace=myundotbs; System altered. SQL> show parameter undo 再次查看当前使用的表空间 NAME TYPE VALUE ------------------------------------ ---------------------------------------------------- undo_management string AUTO undo_retention integer 900 undo_tablespace string MYUNDOTBS //已经切换的了undo表空间
刪除undo表空間:
SQL> drop tablespace myundotbs; Tablespace dropped.
Drop一個undo表空間後,在磁碟上還是存在的,我們需要透過作業系統層面用rm指令將檔案刪除。
思考:
表空間的切換、刪除指令非常簡單,但這裡我們需要思考一下實際切換場景。當我們執行一個事務時,事務執行了一半還沒有提交,這個時候進行切換undo表空間是否可以成功?
理論上undo表空間正在使用中,是不允許切換的。但實際上undo表空間在使用上是可以切換的,但切換之後立刻刪除,系統會提示錯誤。把交易提交後再刪除,系統依然提示錯誤。這裡只有將替換掉的undo表空間切換到使用狀態,再切換到廢棄狀態才能刪除。
Undo調優中使用如何設定undo更合理地為我們工作? Undo表空間的大小:
我們在創建一個undo表空間的使用,就指定了它的大小,這個大小一旦創建是不可變更的。設定過大,是一種浪費,設定太小,例如刪除100萬筆記錄,這些刪除的記錄都要暫時存放到undo表空間中,如果undo的大小不能儲存100萬筆記錄,那麼就會出問題。
Undo資料的存放時間:
也就是undo_retention 参数所对应的时间,undo上有数据存放时间与undo大小的密切关系。存放时间越长,需要的表空间越大。就像理发师的数量与理发师的效率的关系一样。理发师效率很高,一秒钟解决一个客户,那么就不需要太多的理发师傅。
Undo表空间的历史信息:
如何合理设置undo表空间的大小和存放时间呢?那么就需要参考历史记录
这个数据每隔10分钟采集一次,结束时间减去开始时间,在这段时间内使用了多少个undo数据块。
计算每秒钟使用数据块的多少?
求最大值: SQL> select max(undoblks / ((end_time-begin_time)*24*3600)) from v$undostat; MAX(UNDOBLKS/((END_TIME-BEGIN_TIME)*24*3600)) --------------------------------------------- 14.15833333 求平均值: SQL> select sum(undoblks)/sum((end_time - begin_time)*24*3600) from v$undostat; SUM(UNDOBLKS)/SUM((END_TIME-BEGIN_TIME)*24*3600) ------------------------------------------------ 4.122282389
以上是oracle撤銷分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!