Oracle概念問題假如數據沒有提交但是卻被dbwn進程寫入了數據文件會怎麼樣呢?
案例分析
首先說明的是dbwn寫髒數據跟commit提交沒有關系!
在一個transaction發生的過程中online redo log首先記錄transaction中修改的數據塊相關信息修改的數據塊會被緩存在database buffer cache中由於database buffer cache寫滿或者checkpoint等等條件觸發dbwn進程會導致這些緩存的數據塊寫入數據文件但此時可能該transaction仍然還沒有提交所以在數據文件中可能會有commited 和 uncommited 的數據塊而原有的數據塊鏡像會存放在undo segment
IXDBANET社區論壇
然而dbwn寫髒數據時不管這個要寫的transaction是否提交
也沒有必要去管
這樣就發生了所謂的已經提交的數據但是還沒有寫入數據文件的現象
還有一種情況數據沒有提交但是已經被寫入數據文件此時發生回退撤銷沒有提交的數據
那麼引發Oracle前滾與回退的根本原因就是什麼呢?
根本原因是commit後寫redo buffer和觸發lgwr寫 redo buffer的區別
事務在執行完畢後隨即會被寫入redo buffer和undo中同時在redo buffer和undo中對該事務都有一個是否提交的標記兩者的默認狀態都是active的即沒有提交時刻處於激活狀態
commit操作執行時刻把此前的所有事務操作全部寫入redo log filecommit成功後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 failuresga中的內存信息丟失了但是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回滾從數據文件中撤銷沒有提交卻被寫入數據文件的數據
From:http://tw.wingwit.com/Article/program/Oracle/201311/16619.html