您好,登錄后才能下訂單哦!
這篇文章主要介紹“ORACLE事務(wù)和實(shí)例的恢復(fù)過(guò)程講解”,在日常操作中,相信很多人在ORACLE事務(wù)和實(shí)例的恢復(fù)過(guò)程講解問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”O(jiān)RACLE事務(wù)和實(shí)例的恢復(fù)過(guò)程講解”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
從oracle 的一個(gè)事務(wù)說(shuō)起:
例如當(dāng)我們發(fā)起一個(gè)update 語(yǔ)句更改某一行數(shù)據(jù),例如更改zabbix.cwdtest 的 table_name='ICOL$' 為'aaxx'。該行記錄在14號(hào)文件,1835491塊
1.首先會(huì)經(jīng)過(guò)在share pool中的sql語(yǔ)句的解析過(guò)程,這一過(guò)程只要是針對(duì)sql語(yǔ)法,執(zhí)行計(jì)劃這些進(jìn)行處理,這一部分不細(xì)講。
2.接著,到了sql執(zhí)行后,數(shù)據(jù)庫(kù)從物理文件讀出數(shù)據(jù)行相應(yīng)的數(shù)據(jù)庫(kù)到 buffer cache中(假設(shè)此時(shí)內(nèi)存不存在相應(yīng)的數(shù)據(jù)塊同時(shí)不討論鎖的過(guò)程),這一過(guò)程也涉及到數(shù)據(jù)塊寫(xiě)到dirty list,并寫(xiě)臟塊,為新讀取的數(shù)據(jù)塊尋找空閑空間的過(guò)程。
3.同時(shí)會(huì)分配回滾段并在undo段再保留一份修改前的數(shù)據(jù)塊映像。
以下通過(guò)DUMP UNDO 相關(guān) 信息來(lái)查看。
看到index是0x09的事務(wù)槽的state 為10代表事務(wù)正在活動(dòng),而其他槽是9代表事務(wù)不活動(dòng),
scn 表示務(wù)事啟動(dòng)、提交、回滾的SCN,事務(wù)槽0x09的scn是 0x0009.01e25a30,轉(zhuǎn)換之后是38686317104。
dba 表示uba:第一部分的undo塊地址,這個(gè)DBA是(rollback)回滾的起始點(diǎn),也就是說(shuō)是記錄事務(wù)修改的最后一條記錄所在UNDO塊的地址。
事物表中0x19槽的dba為0x0a400495即41號(hào)文件的1173號(hào)塊塊號(hào)這與(與v$transaction視圖中一致)。
我們?cè)诳匆幌逻@個(gè)前鏡像到底是什么?
轉(zhuǎn)儲(chǔ)數(shù)據(jù)塊
這里scn表示 最近寫(xiě)入磁盤(pán)的SCN號(hào),此時(shí)數(shù)據(jù)塊中的scn是0x0009.01e25beb,轉(zhuǎn)化之后是38686317547。
對(duì)于DBWR,每次刷新臟塊后,會(huì)去維護(hù)這個(gè)block的SCN號(hào),代表這個(gè)block的數(shù)據(jù)版本。
接著往下看,有本UNDO塊中有51條記錄:
我們找到第51行記錄的對(duì)象號(hào)是130736,這個(gè)正是我們本次事務(wù)更改的表。
這里字段值是 49 43 4f 4c 24,通過(guò)轉(zhuǎn)換是ICOL$,這正是update前的值。
SQL> select utl_raw.cast_to_varchar2(replace('49 43 4f 4c 24',' ')) from dual;UTL_RAW.CAST_TO_VARCHAR2(REPLACE('49434F4C24',''))-------------------------------------------------------------------------------------ICOL$
而bdba: 0x039c01e3 是該記錄對(duì)應(yīng)的數(shù)據(jù)塊地址,該行記錄正是在14號(hào)文件,1835491塊
SQL> select to_number('039c01e3','xxxxxxxxxxx')from dual;TO_NUMBER('039C01E3','XXXXXXXXXXX')----------------------------------- 60555747SQL> select dbms_utility.data_block_address_file(60555747)file#, dbms_utility.data_block_address_block(60555747) block from dual; FILE# BLOCK------------- ------------- 14 1835491
整個(gè)與UNDO相關(guān)的有幾個(gè)SCN,我們重新整理下:
undo header 中的SCN: 表示務(wù)事啟動(dòng)、提交、回滾的SCN,事務(wù)槽0x09的scn是 0x0009.01e25a30,轉(zhuǎn)換之后是38686317104。
undo block中scn:表示 最近寫(xiě)入磁盤(pán)的SCN號(hào),此時(shí)數(shù)據(jù)塊中的scn是0x0009.01e25beb,轉(zhuǎn)化之后是38686317547
undo block修改記錄行的SCN:
ctl max scn: 0x0009.01e25b73 轉(zhuǎn)化之后是38686317427
prv tx scn: 0x0009.01e25b75 ,轉(zhuǎn)化之后是38686317429
txn start scn: scn: 0x0000.00000000 ,這里是0 。
而此時(shí)redo記錄的信息如下:
alter system dump logfile '/opt/app/oracle/oradata/tlvdb/redo1.log';
4..為事務(wù)修改數(shù)據(jù)塊,并在執(zhí)行更改完成后,針對(duì)此數(shù)據(jù)塊的修改也生成redo信息。這里是將該語(yǔ)句所影響的并被讀入db buffer中的這些行數(shù)據(jù)的rowid及要更新的原值和新值及scn等信息從PGA逐條的寫(xiě)入redo log buffer中,
以下分別UPDATE 前后執(zhí)行alter system dump datafile 14 block 1835491;來(lái)dump 出數(shù)據(jù)塊。
執(zhí)行UPDATE之前:
tab 0, row 0, @0x1e87tl: 249 fb: --H-FL-- lb: 0x0 cc: 55col 0: [ 3] 53 59 53col 1: [ 5] 49 43 4f 4c 24<<<<<< 轉(zhuǎn)換成字符后是'ICOL$'Block dump from disk:buffer tsn: 7 rdba: 0x039c01e3 (14/1835491)scn: 0x0009.01e25a2b seq: 0x02 flg: 0x04 tail: 0x5a2b0602frmt: 0x02 chkval: 0xf28b type: 0x06=trans dataHex dump of block: st=0, typ_found=1
這里scn: 0x0009.01e25a2b 轉(zhuǎn)換之后是38686317099
執(zhí)行UPDATE 之后:
tl: 248 fb: --H-FL-- lb: 0x2 cc: 55col 0: [ 3] 53 59 53col 1: [ 4] 61 61 78 78<<<<<<<<< 轉(zhuǎn)換成字符后是'aaxx'Block dump from disk:buffer tsn: 7 rdba: 0x039c01e3 (14/1835491)scn: 0x0009.01e25beb seq: 0x01 flg: 0x04 tail: 0x5beb0601frmt: 0x02 chkval: 0xad91 type: 0x06=trans dataHex dump of block: st=0, typ_found=1
這里scn: 0x0009.01e25beb 轉(zhuǎn)換之后是38686317547
這里說(shuō)明,當(dāng)事務(wù)中修改了數(shù)據(jù)塊,不管事務(wù)有無(wú)提交,數(shù)據(jù)臟塊會(huì)隨著 dbw進(jìn)程的機(jī)制寫(xiě)入數(shù)據(jù)文件中。
而在 REDO日志中會(huì)記錄操作的記錄,并記錄本次undo操作的信息,即修改前的信息:
REDO RECORD - Thread:1 RBA: 0x000412.00335b66.0010 LEN: 0x01a0 VLD: 0x0dSCN: 0x0009.01e25beb SUBSCN: 1 07/22/2019 17:53:43(LWN RBA: 0x000412.00335b66.0010 LEN: 0001 NST: 0001 SCN: 0x0009.01e25beb)CHANGE #1 TYP:0 CLS:1 AFN:14 DBA:0x039c01e3 OBJ:130736 SCN:0x0009.01e25a2b SEQ:2 OP:11.5 ENC:0 RBL:0KTB Redo op: 0x01 ver: 0x01 compat bit: 4 (post-11) padding: 1op: F xid: 0x000b.009.0001ba87 uba: 0x0a400495.639a.51KDO Op code: URP row dependencies Disabled xtype: XA flags: 0x00000000 bdba: 0x039c01e3 hdba: 0x039c01e2itli: 2 ispac: 0 maxfr: 4858tabn: 0 slot: 0(0x0) flag: 0x2c lock: 2 ckix: 0ncol: 55 nnew: 1 size: -1col 1: [ 4] 61 61 78 78CHANGE #2 TYP:0 CLS:37 AFN:3 DBA:0x00c00170 OBJ:4294967295 SCN:0x0009.01e25bb3 SEQ:1 OP:5.2 ENC:0 RBL:0ktudh redo: slt: 0x0009 sqn: 0x0001ba87 flg: 0x0012 siz: 140 fbi: 0 uba: 0x0a400495.639a.51 pxid: 0x0000.000.00000000CHANGE #3 TYP:0 CLS:38 AFN:41 DBA:0x0a400495 OBJ:4294967295 SCN:0x0009.01e25bb2 SEQ:1 OP:5.1 ENC:0 RBL:0ktudb redo: siz: 140 spc: 646 flg: 0x0012 seq: 0x639a rec: 0x51 xid: 0x000b.009.0001ba87 ktubl redo: slt: 9 rci: 0 opc: 11.1 [objn: 130736 objd: 130736 tsn: 7]Undo type: Regular undo Begin trans Last buffer split: No Temp Object: No Tablespace Undo: No 0x00000000 prev ctl uba: 0x0a400495.639a.50 prev ctl max cmt scn: 0x0009.01e25b73 prev tx cmt scn: 0x0009.01e25b75 txn start scn: 0x0000.00000000 logon user: 0 prev brb: 171967629 prev bcl: 0 BuExt idx: 0 flg2: 0KDO undo record:KTB Redo op: 0x03 ver: 0x01 compat bit: 4 (post-11) padding: 1op: ZKDO Op code: URP row dependencies Disabled xtype: XA flags: 0x00000000 bdba: 0x039c01e3 hdba: 0x039c01e2itli: 2 ispac: 0 maxfr: 4858tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 0ncol: 55 nnew: 1 size: 1col 1: [ 5] 49 43 4f 4c 24 《〈〈更改前鏡像數(shù)據(jù)
5.執(zhí)行commit命令,聲明redo log buffer 中的redo處于commit狀態(tài),然后修改事務(wù)表相應(yīng)slot,聲明事務(wù)已提交,最后通知lgwr進(jìn)程將redo log buffer中的數(shù)據(jù)寫(xiě)入redo log file。待lgwr進(jìn)程通知已經(jīng)寫(xiě)入完成后,向用戶發(fā)出commit完成的信息。
在事務(wù)的過(guò)程中涉及到三個(gè)進(jìn)程,CKPT,DBWn,LGWR進(jìn)程 :
CKPT:檢查點(diǎn)進(jìn)程(Checkpoint Process)只是更新數(shù)據(jù)文件的文件首部,以輔助建立檢查點(diǎn)的進(jìn)程
ckpt 觸發(fā)條件:
什么時(shí)候發(fā)生normal checkpoint
下面這些操作將會(huì)觸發(fā)checkpoint事件:
· 日志切換,通過(guò)ALTER SYSTEM SWITCH LOGFILE。
· DBA發(fā)出checkpoint命令,通過(guò)ALTER SYSTEM checkpoint。
· 對(duì)數(shù)據(jù)文件進(jìn)行熱備時(shí),針對(duì)該數(shù)據(jù)文件的checkpoint也會(huì)進(jìn)行,ALTER TABLESPACE TS_NAME BEGIN BACKUP/END BACKUP。
· 當(dāng)運(yùn)行ALTER TABLESPACE/DATAFILE READ ONLY的時(shí)候。
· SHUTDOWN命令發(fā)出時(shí)。
因?yàn)槊看瓮耆腸heckpoint都需要把buffer cache所有的臟塊都寫(xiě)入到數(shù)據(jù)文件中,這樣就是產(chǎn)生一個(gè)很大的IO消耗,頻繁的完全checkpoint操作很對(duì)系統(tǒng)的性能有很大的影響,為此Oracle引入的增量checkpoint的概念,buffer cache中的臟塊將會(huì)按照BCQ隊(duì)列的順序持續(xù)不斷的被寫(xiě)入到磁盤(pán)當(dāng)中,同時(shí)CKPT進(jìn)程將會(huì)每3秒中檢查DBWn的寫(xiě)入進(jìn)度并將相應(yīng)的RBA信息記錄到控制文件中。
有了增量checkpoint之后在進(jìn)行實(shí)例恢復(fù)的時(shí)候就不需要再?gòu)谋罎⑶暗哪莻€(gè)完全checkpoint開(kāi)始應(yīng)用重做日志了,只需要從控制文件中記錄的RBA開(kāi)始進(jìn)行恢復(fù)操作,這樣能節(jié)省恢復(fù)的時(shí)間。
發(fā)生增量checkpoint的先決條件
· 恢復(fù)需求設(shè)定 (FAST_START_IO_TARGET/FAST_START_MTTR_TARGET)
· LOG_checkpoint_INTERVAL參數(shù)值
· LOG_checkpoint_TIMEOUT參數(shù)值
· 最小的日志文件大小
· buffer cache中的臟塊的數(shù)量
DBWn:數(shù)據(jù)庫(kù)塊寫(xiě)入器(Database Block Writer)負(fù)責(zé)將臟塊寫(xiě)入磁盤(pán)的后臺(tái)進(jìn)程。
觸發(fā)DBWR進(jìn)程的條件有:
1.DBWR超時(shí),大約3秒
2.系統(tǒng)中沒(méi)有多余的空緩沖區(qū)來(lái)存放數(shù)據(jù)
3.CKPT 進(jìn)程觸發(fā)DBWR
4.free buffer waits 40% 觸發(fā) dbwr吧lruw臟塊寫(xiě)入磁盤(pán)
5.關(guān)機(jī)會(huì)觸發(fā)dbwr寫(xiě)
6.alter system checkpoint 觸發(fā)dbwr寫(xiě)
7.redo 日志切換 觸發(fā)dbwr寫(xiě)
8. 表空間 offline /online 觸發(fā)dbwr寫(xiě)
LGWR:日志寫(xiě)入器(Log Writer)負(fù)責(zé)將SGA中重做日志緩沖區(qū)的內(nèi)容刷新輸出到磁盤(pán)。
觸發(fā)LGWn工作的時(shí)點(diǎn)有幾個(gè):
1. 用戶提交 ,用戶提交時(shí)必須寫(xiě)LOGFILE.
2. 有1/3重做日志緩沖區(qū)未被寫(xiě)入磁盤(pán)
3. 有大于1M的重做日志緩沖區(qū)未被寫(xiě)入磁盤(pán)
4. 3秒超時(shí)
5. DBWR 需要寫(xiě)入的數(shù)據(jù)的SCN大于LGWR記錄的SCN,DBWR 觸發(fā)LGWR寫(xiě)入。
這三個(gè)進(jìn)程都是為了更好地完成一件事:安全高效地實(shí)現(xiàn)內(nèi)存數(shù)據(jù)塊寫(xiě)入數(shù)據(jù)文件,就是將內(nèi)存中修改的數(shù)據(jù)反映到硬盤(pán)的數(shù)據(jù)文件上。 我在事務(wù)未提交時(shí)做一個(gè)刷新buffer cache,此時(shí)發(fā)現(xiàn)數(shù)據(jù)塊已經(jīng)被刷新到磁盤(pán)文件中,通過(guò)以上三個(gè)進(jìn)程的觸發(fā)條件也可以看出刷新數(shù)據(jù)塊與事務(wù)是否提交關(guān)系不大。
首先,日志文件的寫(xiě)入是很頻繁的。LGWn會(huì)不斷將日志信息從Log Buffer中寫(xiě)入Online Redo Log;
其次,在日志文件上,可以有三個(gè)類型的事務(wù)事件。
1、事務(wù)結(jié)束,已經(jīng)被commit,之后打過(guò)checkpoint檢查點(diǎn)。
2、事務(wù)結(jié)束,已經(jīng)被commit,之后沒(méi)有打入checkpint檢查點(diǎn)。
3、事務(wù)未結(jié)束,沒(méi)有commit。
那么當(dāng)我有一個(gè)事務(wù)一直未提交,此時(shí)發(fā)生斷電,數(shù)據(jù)庫(kù)直接crash,在重啟后ORACLE是如何保證數(shù)據(jù)一致性呢?
啟動(dòng)數(shù)據(jù)庫(kù)時(shí),如果發(fā)現(xiàn)有datafile header的START SCN 不等于儲(chǔ)存于CONTROLFILE的DATAFILE SCN,表示需要進(jìn)行介質(zhì)恢復(fù)。
啟動(dòng)數(shù)據(jù)庫(kù)時(shí),如果發(fā)現(xiàn)STOP SCN = NULL,表示需要進(jìn)行crash recovery。
oracle 的實(shí)例恢復(fù)過(guò)程
實(shí)例恢復(fù)主要經(jīng)歷三個(gè)階段: cache recovery、open database、transaction recovery
1.首先oracle對(duì)比控制文件中檢查點(diǎn)scn與數(shù)據(jù)文件頭部scn,發(fā)現(xiàn)不一致
但我開(kāi)啟一個(gè)事務(wù),并不作提交時(shí),首先來(lái)看控制文件中記錄的 SCN情況:
最近一次完全檢查點(diǎn)checkpoint change scn:
DATABASE ENTRY***************************************************************************。。。。 Controlfile Creation Timestamp 08/21/2017 11:01:49 Incmplt recovery scn: 0x0000.00000000 Resetlogs scn: 0x0000.000e2006 Resetlogs Timestamp 08/21/2017 11:01:51 Prior resetlogs scn: 0x0000.00000001 Prior resetlogs Timestamp 08/24/2013 11:37:30 Redo Version: compatible=0xb200400 #Data files = 53, #Online files = 53 Database checkpoint: Thread=1 scn: 0x0009.01e35ecd Threads: #Enabled=1, #Open=1, Head=1, Tail=1
這里是 Database checkpoint: Thread=1 scn: 0x0009.01e35ecd,轉(zhuǎn)換之后是38686383821。
而增量檢查點(diǎn)SCN
CHECKPOINT PROGRESS RECORDS*************************************************************************** (size = 8180, compat size = 8180, section max = 11, section in-use = 0, last-recid= 0, old-recno = 0, last-recno = 0) (extent = 1, blkno = 2, numrecs = 11)THREAD #1 - status:0x2 flags:0x0 dirty:15low cache rba:(0x413.18481.0)〉〉〉起點(diǎn) on disk rba:(0x413.1849b.0)〉〉〉終點(diǎn)on disk scn: 0x0009.01e374ef 07/24/2019 10:23:54 resetlogs scn: 0x0000.000e2006 08/21/2017 11:01:51heartbeat: 996528373 mount id: 1186014334
low cache rba就是CKPT記錄的DBWR寫(xiě)臟塊的進(jìn)度是最近一次完全checkpoint scn 的位置, on disk rba就是LGWR的寫(xiě)進(jìn)度,是 lgwr 寫(xiě)日志文件的最末位置的地址low cache rba 以前的更新的臟塊已經(jīng)寫(xiě)入數(shù)據(jù)文件,不需要重做, on disk rba以后的日志還沒(méi)寫(xiě)入到online logfile.所以不需要恢復(fù).
而此時(shí)有15個(gè)臟塊。
on disk scn表示當(dāng)前系統(tǒng)最新的rba對(duì)應(yīng)的scn,由CKPT進(jìn)程每3秒跟新一次。如果數(shù)據(jù)庫(kù)異常宕機(jī),那么CRASH RECOVER時(shí)服務(wù)器至少要應(yīng)用到該SCN為止。
這里的增量檢查點(diǎn)SCN是38686389487,這個(gè)scn會(huì)比全量檢查點(diǎn)后的SCN大。
控制文件中記錄的數(shù)據(jù)文件 SCN:
DATA FILE #14: name #18: /opt/app/oracle/oradata/xxxx/xxxcreation size=2097152 block size=8192 status=0xe head=18 tail=18 dup=1 tablespace 7, index=7 krfil=14 prev_file=13 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00 Checkpoint cnt:1061 scn: 0x0009.01e35ecd 07/24/2019 07:30:51 Stop scn: 0xffff.ffffffff 09/27/2018 09:20:13 Creation Checkpointed at scn: 0x0000.000f4212 08/21/2017 12:03:57 thread:1 rba:(0x8.3f45.10)
這里記錄的數(shù)據(jù)文件的scn 也同樣是 38686383821,而Stop scn是無(wú)窮大,表示當(dāng)前數(shù)據(jù)庫(kù)是正常打開(kāi)狀態(tài),或者異常關(guān)閉狀態(tài)。
再看數(shù)據(jù)文件頭中SCN:
oradebug dump file_hdrs 1DATA FILE #14: name #18: /opt/app/oracle/oradata/xxxx/xxxcreation size=2097152 block size=8192 status=0xe head=18 tail=18 dup=1 tablespace 7, index=7 krfil=14 prev_file=13 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00 Checkpoint cnt:1061 scn: 0x0009.01e35ecd 07/24/2019 07:30:51
這里記錄的數(shù)據(jù)文件頭SCN 與控制文件中記錄的一致。
以上這種情況當(dāng)發(fā)現(xiàn)控制文件中數(shù)據(jù)文件的SCN與數(shù)據(jù)文件頭中記錄 的SCN一致,即不會(huì)發(fā)生介質(zhì)恢復(fù)。
當(dāng)啟動(dòng)時(shí)發(fā)現(xiàn)Stop scn是無(wú)窮大,則表示數(shù)據(jù)庫(kù)是異常關(guān)閉了,需要進(jìn)行crash recovery,即回滾。而其中增量檢查點(diǎn)的作用就是記錄了該從哪個(gè)地方回滾到那個(gè)地方。
此時(shí),我們 模式 數(shù)據(jù)庫(kù)crash ,然后重啟:
alter database openBeginning crash recovery of 1 threads parallel recovery started with 32 processesStarted redo scanCompleted redo scan read 16 KB redo, 14 data blocks need recoveryStarted redo application at Thread 1: logseq 1043, block 185196Recovery of Online Redo Log: Thread 1 Group 2 Seq 1043 Reading mem 0 Mem# 0: /opt/app/oracle/oradata/tlvdb/redo2.logCompleted redo application of 0.01MBCompleted crash recovery at Thread 1: logseq 1043, block 185228, scn 38686432573《〈〈〈〈〈〈〈〈 14 data blocks read, 14 data blocks written, 16 redo k-bytes readWed Jul 24 23:44:50 2019Thread 1 advanced to log sequence 1044 (thread open)Thread 1 opened at log sequence 1044 Current log# 3 seq# 1044 mem# 0: /opt/app/oracle/oradata/tlvdb/redo3.logSuccessful open of redo thread 1MTTR advisory is disabled because FAST_START_MTTR_TARGET is not setWed Jul 24 23:44:50 2019SMON: enabling cache recovery[39962] Successfully onlined Undo Tablespace 2.Undo initialization finished serial:0 start:193329648 end:193329738 diff:90 (0 seconds)Verifying file header compatibility for 11g tablespace encryption..Verifying 11g file header compatibility for tablespace encryption completedSMON: enabling tx recoveryDatabase Characterset is ZHS16GBK
2.從最后檢查點(diǎn)之后到日志文件尾部將被重新應(yīng)用到數(shù)據(jù)文件,同時(shí)產(chǎn)生undo信息(回滾),此階段也稱為cache recovery
當(dāng)數(shù)據(jù)庫(kù)中有已經(jīng)COMMIT但沒(méi)有寫(xiě)入磁盤(pán)的數(shù)據(jù)塊,當(dāng)數(shù)據(jù)庫(kù)CRASH后重啟,會(huì)從控制文件中最近一次完全檢查點(diǎn)位置到最后一次增量檢查點(diǎn)位置,例如上面從38686383821到38686389487。
然后到redo日志文件中找到該檢查點(diǎn)位置,然后從該檢查點(diǎn)位置開(kāi)始往下到增量檢查點(diǎn)位置,應(yīng)用所有的redo,而其尋找redo條目是從low cache rba到on disk rba,從而在buffer cache里又恢復(fù)了實(shí)例崩潰那個(gè)時(shí)間點(diǎn)的狀態(tài)。這個(gè)過(guò)程叫做前滾,前滾完畢以后,
buffer cache里既有崩潰時(shí)已經(jīng)提交還沒(méi)有寫(xiě)入數(shù)據(jù)文件的臟數(shù)據(jù)塊,也還有事務(wù)被突然終止,而導(dǎo)致的既沒(méi)有提交又沒(méi)有回滾的事務(wù)所弄臟的數(shù)據(jù)塊。
可以把這個(gè)過(guò)程的redo給dump出來(lái):
SQL> ALTER SYSTEM DUMP LOGFILE '/opt/app/oracle/oradata/tlvdb/redo1.log' SCN MIN 38686383821 SCN MAX 38686389487;System altered. Opcodes *.* RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff SCNs: scn: 0x0009.01e35ecd (38686383821) thru scn: 0x0009.01e374ef (38686389487) Times: creation thru eternity FILE HEADER:。。。。 Control Seq=459718=0x703c6, File size=4194304=0x400000 File Number=1, Blksiz=512, File Type=2 LOG descrip:"Thread 0001, Seq# 0000001042, SCN 0x000901d8f38d-0x000901e35ecd" thread: 1 nab: 0x384d91 seq: 0x00000412 hws: 0x3 eot: 0 dis: 0 resetlogs count: 0x38c7849f scn: 0x0000.000e2006 (925702) prev resetlogs count: 0x3121c97a scn: 0x0000.00000001 (1) Low scn: 0x0009.01d8f38d (38685701005) 07/08/2019 09:24:12 Next scn: 0x0009.01e35ecd (38686383821) 07/24/2019 07:30:51 Enabled scn: 0x0000.000e2006 (925702) 08/21/2017 11:01:51 Thread closed scn: 0x0009.01d8f38d (38685701005) 07/08/2019 09:24:12 Disk cksum: 0x56ca Calc cksum: 0x56ca Terminal recovery stop scn: 0x0000.00000000 Terminal recovery 01/01/1988 00:00:00 Most recent redo scn: 0x0000.00000000 Largest LWN: 2395 blocks
3.數(shù)據(jù)文件中包含已提交或未提交的數(shù)據(jù),盡管存在未提交的數(shù)據(jù),此時(shí)數(shù)據(jù)庫(kù)已經(jīng)被打開(kāi),允許用戶連接,此時(shí)針對(duì)未提交的事務(wù)被進(jìn)行回滾
前滾一旦完畢,SMON進(jìn)程立即打開(kāi)數(shù)據(jù)庫(kù)。但是,這時(shí)的數(shù)據(jù)庫(kù)中還含有那些中間狀態(tài)的、既沒(méi)有提交又沒(méi)有回滾的臟塊,這種臟塊是不能存在于數(shù)據(jù)庫(kù)中的,因?yàn)樗鼈儾](méi)有被提交,必須被回滾。打開(kāi)數(shù)據(jù)庫(kù)以后,SMON進(jìn)程會(huì)在后臺(tái)進(jìn)行回滾,此時(shí)會(huì)從Undo空間中尋找到舊版本SCN的數(shù)據(jù)塊信息,來(lái)進(jìn)行SGA中Buffer Cache數(shù)據(jù)塊恢復(fù)。
幾個(gè)疑問(wèn):
一,當(dāng)log buffer 中的數(shù)據(jù)還沒(méi)來(lái)得及寫(xiě)入redo file,此時(shí)數(shù)據(jù)庫(kù)crash掉,那這部分丟失redo怎么辦?
Oracle 采取在事務(wù)提交的時(shí)候?qū)⒑瓦@個(gè)事務(wù)相關(guān)的REDO LOG 數(shù)據(jù),包括COMMIT 記錄,都必須從LOG BUFFER 中寫(xiě)入REDO LOG 文件,此時(shí)事務(wù)提交成功的信號(hào)才能發(fā)送給用戶進(jìn)程。這樣便可以確保當(dāng)已經(jīng)提交的事務(wù)中的部分BUFFER CACHE 還沒(méi)有被寫(xiě)入數(shù)據(jù)文件時(shí)發(fā)生了實(shí)例故障,在重啟后做實(shí)例恢復(fù)的時(shí)候,也可以通過(guò)REDO LOG 的信息,將不一致的數(shù)據(jù)前滾。
如果某事務(wù)未提交,此時(shí)產(chǎn)生的REDO仍在LOG BUFFER中,當(dāng)數(shù)據(jù)庫(kù)突然CRASH,log buffer數(shù)據(jù)也丟失了,我們可以確認(rèn)這部分?jǐn)?shù)據(jù)是沒(méi)有提交的,將會(huì)被回滾,但是,redo信息沒(méi)有寫(xiě)入磁盤(pán),不存在了。也沒(méi)辦法通過(guò)redo 構(gòu)造數(shù)據(jù)塊,怎么辦?
其實(shí)這里是理解錯(cuò)了,未寫(xiě)入redo_file,也未寫(xiě)入db_file,那么發(fā)生數(shù)據(jù)庫(kù)失敗恢復(fù)時(shí),數(shù)據(jù)庫(kù)將直接丟棄該DML操作,反正該操作尚未commit,丟掉了也沒(méi)關(guān)系,并且因?yàn)槲磳?xiě)入數(shù)據(jù)文件,沒(méi)必要進(jìn)行構(gòu)造UNDO回滾。
二、UNDO有沒(méi)有寫(xiě)緩存情況,如果有UNDO丟失怎么辦?
undo 有undo buffer ,從以上可以看出,redo 日志會(huì)記錄了事務(wù)的 redo 和undo信息。所以不用擔(dān)心
三、實(shí)例恢復(fù)過(guò)程主要使用的四個(gè)SCN:
Control file三個(gè)地方為:
1、System checkpoint SCN
select checkpoint_change# from v$database;
這里應(yīng)該有完整檢查點(diǎn)的SCN,完整檢查點(diǎn)的SCN會(huì)更新數(shù)據(jù)文件及數(shù)據(jù)文件頭的SCN, 增量檢查點(diǎn)SCN只在控制文件中更新。
2、Datafile checkpoint SCN
set linesize 400
col name for a50
select name, checkpoint_change# from v$datafile where file#=14;
3、 Stop SCN
select name,last_change# from v$datafile where file#=14;
正常datafile在read-write mode運(yùn)作下,last_change#一定是null
還有一個(gè)SCN在datafile header內(nèi)
4、 Start SCN
select name,checkpoint_change# from v$datafile_header where file#=14;
到此,關(guān)于“ORACLE事務(wù)和實(shí)例的恢復(fù)過(guò)程講解”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。