程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle數據庫中為什麼會產生回滾與前退

Oracle數據庫中為什麼會產生回滾與前退

編輯:Oracle數據庫基礎
Oracle概念問題,假如數據沒有提交,但是卻被dbwn進程寫入了數據文件,會怎麼樣呢?

  案例分析:

  首先說明的是dbwn寫髒數據跟commit提交沒有關系!

  在一個transaction發生的過程中,online redo log首先記錄transaction中修改的數據塊相關信息,修改的數據塊會被緩存在database buffer cache中。由於database buffer cache寫滿或者checkpoint等等條件觸發dbwn進程,會導致這些緩存的數據塊寫入數據文件,但此時可能該transaction仍然還沒有提交。所以在數據文件中,可能會有commited 和 uncommited 的數據塊。而原有的數據塊鏡像會存放在undo segment。

  IXDBA.Net社區論壇

  然而,dbwn寫髒數據時不管這個要寫的transaction是否提交,

  也沒有必要去管。

  這樣就發生了所謂的已經提交的數據,但是還沒有寫入數據文件的現象。

  還有一種情況,數據沒有提交,但是已經被寫入數據文件,此時發生回退,撤銷沒有提交的數據。

  那麼,引發Oracle前滾與回退的根本原因就是什麼呢?

  根本原因是commit後寫redo buffer和觸發lgwr寫 redo buffer的區別。

  事務在執行完畢後,隨即會被寫入redo buffer和undo中,同時在redo buffer和undo中對該事務都有一個是否提交的標記。兩者的默認狀態都是active的,即沒有提交時刻處於激活狀態。

  commit操作執行時刻把此前的所有事務操作全部寫入redo log file,commit成功後,redo buffer信息全部寫入redo file,同時修改兩者中的事務提交標識為inactive,表示此前事務已經遞交。

  Oracle的前滾和回退根據就是依據事務是否提交而進行的。

  在觸發lgwr進程後,Oracle同樣把此前的redo buffer信息寫入redo file,但是與commit觸發寫日志不同的是,redo file本身對lgwr寫日志操作不記錄任何信息標識,lgwr寫到那裡就是那裡,就算此時掉電也無妨,redo file就記錄到掉電時刻的信息。

  lgwr是一個Oracle後台執行的進程,具體的日志寫操作都有oracle去控制,這對於Oracle來說是透明的,因此不用在redo file中寫入任何標記信息,這也是正常的。

  commit操作是唯一一個可以前台操作與oracle後台通信的指令,因此當加入這個操作以後,Oracle本身必須要了解各個事務的讀寫狀況,那麼怎麼了解整個狀況:在redo以及undo中加入是否遞交的標識,對於已經提交的操作,但是還沒有寫入數據文件,那麼就要前滾,相反,對於沒有提交,執行回退!

  於是,Oracle崩潰恢復步驟如下:

  首先rolling forward 前滾:由於oracle failure,sga中的內存信息丟失了,但是online redo log中還是存儲了transaction信息,包括commited or uncommited data。可能這些修改信息並沒有被Oracle正確的來處理,包含兩種情況:已經提交的還沒有寫入數據文件,或者沒有提交的卻被寫入了數據文件。針對已經提交的還沒有寫入數據文件就要發生前滾,在前滾過程中,smon會根據online redo log中的記錄來完成對datafile的修改。保證已經提交的數據已經寫入數據文件。

  接下來,前滾結束後,數據庫正常open,此時用戶可以正常連接,可以訪問已經recover的commited data,但是對於那些屬於unrecoverable transaction的uncommited data,會被Oracle 加鎖,是不可以訪問的。

  rolling back:假如有進程訪問這些加鎖的data,此時smon會對這些數據塊做rollback回滾,從數據文件中撤銷沒有提交卻被寫入數據文件的數據。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved