oracle技术之检查点及SCN深入研究
生活随笔
收集整理的這篇文章主要介紹了
oracle技术之检查点及SCN深入研究
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、檢查點概述大多數(shù)關(guān)系型數(shù)據(jù)庫都采用“在提交時并不強迫針對數(shù)據(jù)塊的修改完成”而是“提交時保證修改記錄(以重做日志的形式)寫入日志文件”的機制,來獲得性能的優(yōu)勢。這句話的另外一種描述是:當(dāng)用戶提交事務(wù),寫數(shù)據(jù)文件是“異步”的,寫日志文件是“同步”的。這就可能導(dǎo)致數(shù)據(jù)庫實例崩潰時,內(nèi)存中的DB_Buffer中的修改過的數(shù)據(jù),可能沒有寫入到數(shù)據(jù)塊中。數(shù)據(jù)庫在重新打開時,需要進行恢復(fù),來恢復(fù)DB Buffer中的數(shù)據(jù)狀態(tài),并確保已經(jīng)提交的數(shù)據(jù)被寫入到數(shù)據(jù)塊中。檢查點是這個過程中的重要機制,通過它來確定,恢復(fù)時哪些重做日志應(yīng)該被掃描并應(yīng)用于恢復(fù)。
要了解這個檢查點,首先要知道checkpoint queu概念,檢查點發(fā)生后,觸發(fā)dbwn,CKPT獲取發(fā)生檢查點時對應(yīng)的SCN,通知DBWn要寫到這個SCN為止,dbwr寫dirty buffer是根據(jù)buffer在被首次modify的時候的時間的順序?qū)懗?#xff0c;也就是buffer被modify的時候會進入一個queue(checkpoint queue),dbwr就根據(jù)queue從其中批量地寫到數(shù)據(jù)文件。由于這里有一個順序的關(guān)系,所以dbwr的寫的進度就是可衡量的,寫到哪個buffer的時候該buffer的首次變化時候的scn就是當(dāng)前所有數(shù)據(jù)文件block的最新scn,但是由于無法適時的將dbwr的進度記錄下來,所以oracle選擇了一些策略。其中就包括ckpt進程的檢查點和心跳。
但oracle考慮到檢查點scn的間隔還是太大了,因為檢查點的觸發(fā)條件有限,周期可能比較長,有些情況下比如檢查點需要5分鐘才觸發(fā),那這個時候系統(tǒng)crash再重新啟動就意味著很可能系統(tǒng)需要5分鐘才能啟動。
于是oracle采用了一個心跳的概念,以3秒的頻率將dbwr寫的進度反應(yīng)到控制文件中,這樣系統(tǒng)crash重新啟動的時候?qū)母囊粋€時間點開始恢復(fù)。
再這里同樣需要說明的一點是dbwr并不是只有當(dāng)檢查點發(fā)生的時候才寫,它大約有10幾種條件觸發(fā)寫操作
所以這個問題,我們需要理解的是oracle為什么要這么做?oracle的目的就是縮短崩潰恢復(fù)時間!
oracle如何縮短恢復(fù)時間?1:檢查點機制2:心跳機制oracle為什么不適時的將dbwr寫進度反應(yīng)到文件中?適時反應(yīng)成本太高!3秒種是一個合適的值,可以接受,代價不高又能大大縮短崩潰后恢復(fù)時間。
檢查點發(fā)生以后,CKPT進程檢查checkpoint queue(也就是臟塊鏈表)是否過長,如果是,則觸發(fā)DBWn,將一部分臟塊寫入數(shù)據(jù)文件,從而縮短checkpoint queue。
checkpoint發(fā)生時,一方面通知dbwr進行下一批寫操作,(dbwr寫入的時候,一次寫的塊數(shù)是有一個批量寫的隱藏參數(shù)控制的。)另一方面,oracle采用了一個心跳的概念,以3秒的頻率將dbwr寫的進度反應(yīng)到控制文件中,也就是把dbwr當(dāng)前剛寫完的dirty buffer對應(yīng)的scn寫入數(shù)據(jù)文件頭和控制文件,這就是檢查點scn。
這個3秒和增量檢查點不是一個概念,3秒只是在控制文件中,ckpt進程去更新當(dāng)前dbwr寫到哪里了,這個對于ckpt進程來說叫heartbeat,heartbeat是3秒一次,3秒可以看作不停的檢查并記錄檢查點執(zhí)行情況(DBWR的寫進度)。
檢查點發(fā)生之后數(shù)據(jù)庫的數(shù)據(jù)文件、控制文件處于一致狀態(tài)的含義是不需要進行介質(zhì)恢復(fù),只表示數(shù)據(jù)文件頭一致,但是并不表示數(shù)據(jù)文件內(nèi)容一致,因為數(shù)據(jù)文件內(nèi)容可能在沒有發(fā)生檢查點的其他情況下的dbwr寫數(shù)據(jù)文件,這樣數(shù)據(jù)文件內(nèi)容就不一致,若掉電需要進行崩潰恢復(fù)。二、觸發(fā)的條件這里需要明白兩個概念“完全檢查點和增量檢查點”的區(qū)別。1、增量檢查點(incremental checkpoint)oracle8之前,那時候沒有chekpoint queue,也沒有增量的概念,dirty buffer的寫出是無順的,就是凍結(jié)所有dml等候所有dirty buffer被寫出。后來隨著數(shù)據(jù)庫規(guī)模的擴展和buffer cache的不斷增大,oracle意識到這個機制已經(jīng)滿足不了需要,所以提出增量檢查點的概念,建立了checkpoint queue,讓dirty buffer header根據(jù)首次變化時候的順序排列在queue里面。這樣dbwr只要順著queue的順序?qū)?#xff0c;而其他進程不必等候dbwr的寫操作完成就可以繼續(xù)。
自從有了checkpoint queue之后,檢查點就成為一個短暫的動作,就是通知dbwr你要繼續(xù)寫dirty buffer到當(dāng)前檢查點發(fā)生時候的scn,然后將當(dāng)前dbwr剛寫完的dirty buffer對應(yīng)的scn,寫進數(shù)據(jù)文件和控制文件【增量檢查點時不寫數(shù)據(jù)文件頭】(比如日志切換這種動作引起的檢查點動作等)。然后檢查點動作就結(jié)束了。剩下的工作就交給DBWn了,檢查點進程也不必等候dbwr的完成。
ckpt進程通知dbwr之后并不需要等待dbwr寫到當(dāng)前這個檢查點對應(yīng)的時間點。所以ckpt可以將已經(jīng)完成的最后一個檢查點scn寫到控制文件和數(shù)據(jù)文件(可能是上一個,也可能是上上個,總之dbwr完成了哪個算哪個)。這樣本次需要寫進數(shù)據(jù)文件的dirty buffer可能在下一次檢查點發(fā)生的時候已經(jīng)寫完了,這樣下一次檢查點發(fā)生的時候就把本次的檢查點scn更新到控制文件和數(shù)據(jù)文件。
在oracle 8之前,沒有ckpt queue,只有LRU list,而LRU list里面的Dirty Buffer是不按時間順序排列的,所以checkpoint時都會做一個full thread checkpoint,將LRU list中的所有buffer寫到數(shù)據(jù)文件。
在oracle8i以后,當(dāng)發(fā)生FULL CHECKPOINT時,oracle只是獲取系統(tǒng)當(dāng)前的SCN,然后將這個SCN之前的臟數(shù)據(jù)塊寫入磁盤,后續(xù)的DML臟數(shù)據(jù)塊繼續(xù)入隊,他并不是保證整個緩沖區(qū)沒有臟塊,只是保證此檢查點發(fā)生之前這段距離間沒有臟塊,而在checkpoint點之后的DML可以正常操作。
oracle8以后推出了incremental checkpoint的機制,在以前的版本里每checkpoint時都會做一個full thread checkpoint,這樣的話所有臟數(shù)據(jù)會被寫到磁盤,巨大的i/o對系統(tǒng)性能帶來很大影響。為了解決這個問題,oracle引入了checkpoint queue機制,每一個臟塊會被移到檢查點隊列里面去,按照low rdb(第一次對此塊修改對應(yīng)的redo block address)來排列,靠近檢查點隊列尾端的數(shù)據(jù)塊的low rba值是最小的,而且如果這些贓塊被再次修改后它在檢查點隊列里的順序也不會改變,這樣就保證了越早修改的塊越早寫入磁盤。每隔3秒鐘ckpt會去更新控制文件和數(shù)據(jù)文件,記錄checkpoint執(zhí)行的情況。
在運行的Oracle數(shù)據(jù)中,有很多事件、條件或者參數(shù)來觸發(fā)檢查點。比如(1)當(dāng)已通過正常事務(wù)處理或者立即選項關(guān)閉例程時;(shutdown immediate或者Shutdown normal;)(2)當(dāng)通過設(shè)置初始化參數(shù)LOG_CHECKPOINT_INTERVAL、LOG_CHECKPOINT_TIMEOUT和FAST_START_IO_TARGET強制時;(3)當(dāng)數(shù)據(jù)庫管理員手動請求時;(ALter system checkpoint)(4)alter tablespace ... offline;(5)每次日志切換時;(alter system switch logfile)需要說明的是,alter system switch logfile也將觸發(fā)完全檢查點的發(fā)生。alter database datafile ... offline不會觸發(fā)檢查點進程。
如果是單純的offline datafile,那么將不會觸發(fā)文件檢查點,只有針對offline tablespace的時候才會觸發(fā)文件檢查點,這也是為什么online datafile需要media recovery而online tablespace不需要。
對于表空間的offline后再online這種情況,最好做個強制的checkpoint比較好。上面幾種情況,將觸發(fā)完全檢查點,促使DBWR將檢查點時刻前所有的臟數(shù)據(jù)寫入數(shù)據(jù)文件。
另外,一般正常運行期間的數(shù)據(jù)庫不會產(chǎn)生完全檢查點,下面很多事件將導(dǎo)致增量檢查點,比如:在聯(lián)機熱備份數(shù)據(jù)文件前,要求該數(shù)據(jù)文件中被修改的塊從DB_Buffer寫入數(shù)據(jù)文件中。所以,發(fā)出這樣的命令:ALTER TABLESPACE tablespace_name BIGEN BACKUP & end backup;也將觸發(fā)和該表空間的數(shù)據(jù)文件有關(guān)的局部檢查點;另外,ALTER TABLESPACE tablespace_name READ ONLY;ALTER TABLESPACE tablespace_name OFFLINE NORMAL;等命令都會觸發(fā)增量檢查點。
注意:每隔三秒也會觸發(fā)檢查點,但是并沒有被oracle正式作為一種檢查點的觸發(fā)方式列入文檔,并且這個3秒是記錄dbwr進度而不是通知dbwr寫。這是三秒觸發(fā)的檢查點與其它條件觸發(fā)檢查點不同的地方。
三、關(guān)于low cache rba與on disk rba的理解:簡單說:low cache rba就是CKPT記錄的DBWR寫的進度。on disk rba就是LGWR的寫進度。
如果數(shù)據(jù)庫carsh,low cache rba是恢復(fù)的起點,on disk rba是恢復(fù)的終點。
闡述一下:dbwr成功寫完后并不把此刻scn信息寫到控制文件中,只有CKPT才更新控制文件和數(shù)據(jù)文件頭,dbwr只要成功將dirty data寫入數(shù)據(jù)文件就是成功,CKPT只要能將最新DBWR寫完的SCN更新到控制文件和數(shù)據(jù)文件頭就算成功。但是由于CKPT進程不是實時更新dbwr寫完的scn到控制文件中,而是采用每3妙更新一次的策略,因此最后有ckpt進程寫進控制文件的scn信息有可能不是當(dāng)前dbwr剛剛寫完的scn值。這點應(yīng)該注意,也就是說dbwr寫的進度與ckpt進程更新控制文件的進度是不同的。
關(guān)于檢查點的一點具體應(yīng)用討論:1、Commit成功后,數(shù)據(jù)還會丟失嗎?
對于Oracle來說,用戶所做的DML操作一旦被提交,則先是在database buffer cache中進行修改,同時在修改之前會將數(shù)據(jù)的前鏡像保存在回滾段中,然后將修改之前和修改之后的數(shù)據(jù)都寫入到redo log buffer中,當(dāng)接收到commit命令之后,則redo log buffer開始寫redo log file,并且記錄此時的scn,當(dāng)redo log file寫完了之后,表示這次事務(wù)提交操作已經(jīng)確認(rèn)被數(shù)據(jù)庫記錄了,只有當(dāng)redo log file寫成功了,才會給用戶Commit completed的成功字樣。而對于Database buffer cache中的dirty buffer則會等待觸發(fā)DBWn才寫入,但是如果此時斷電,則數(shù)據(jù)已經(jīng)被記錄到了redo log file中,系統(tǒng)在重新啟動的時候,會自動進行嵌滾和回滾來保證數(shù)據(jù)的一致。所以,只要是commit成功的了,數(shù)據(jù)不會丟失!
2、數(shù)據(jù)庫發(fā)生一次DBWn,是否將所有buffer cache中的dirty buffer都寫入,還是先將臟隊列中的數(shù)據(jù)寫入?這話看起來有道理,但實際上,dbwr在寫的時候又不斷地在產(chǎn)生dirty buffer ,所以說檢查點發(fā)生的時候是期望把該時間點之前的所有臟緩沖區(qū)寫入數(shù)據(jù)文件。所有的buffer,不在LRU list上就在dirty list上, dbwr寫入的時候,一次寫的塊數(shù)是有一個批量寫的隱藏參數(shù)控制的。所以說要是dbwr將dirty list也好,lru list上的也好,要實現(xiàn)全部寫入,都是一個現(xiàn)實系統(tǒng)中很難存在的現(xiàn)象。dirty總是在不斷的產(chǎn)生,dbwr總是在不斷地寫,增量檢查點發(fā)生的時候也并不意味著一定要更新數(shù)據(jù)文件頭,檢查點開始的時候只表示該次檢查點結(jié)束的時候要更新數(shù)據(jù)文件頭的話數(shù)據(jù)文件頭具有該時間點的一致性。
3、data block里面不是也有SCN嗎?和文件頭里面的SCN有什么關(guān)系?什么時候被更新?代表的是是什么含義?data block里面的SCN是當(dāng)block被更改的時候的SCN而數(shù)據(jù)文件有那么多block,自然不同的block有不同的SCNblock中存在block SCN和ITL中的commit SCNblock SCN又在塊頭和塊位都有,若不一致意味著block損壞(熱碑可能出現(xiàn)這個情況,需要從redo log中拷貝回來,若是正在修改的過程中由于進程死掉則pmon負(fù)責(zé)清理。若由于一些以外發(fā)生這樣的不一致的情況,則查詢的時候出現(xiàn)1578錯誤,當(dāng)然該錯誤號也可能是物理磁盤損壞,這里表示邏輯的損壞!)
這個頭和尾的SCN的檢查時機跟這兩個參數(shù)有關(guān):db_block_checking boolean FALSEdb_block_checksum boolean FALSE該兩參數(shù)信息請查閱http://tahiti.oracle.com而ITL中的commit SCN則跟consistent gets and delay block cleanout有關(guān)數(shù)據(jù)文件頭的SCN是檢查點發(fā)生時更新的,代表著當(dāng)恢復(fù)的時候從這個SCN點開始在log file中尋找redo開始做恢復(fù)。
4、怎么解釋這個現(xiàn)象?看下面的操作!___________________________________________________________sys@DBAP01>select max(ktuxescnw*power(2,32)+ktuxescnb)from x$ktuxe;MAX(KTUXESCNW*POWER(2,32)+KTUX------------------------------52211024已用時間: ?00:00:00.00sys@DBAP01>alter system checkpoint;系統(tǒng)已更改。已用時間: ?00:00:00.06sys@DBAP01>select CHECKPOINT_CHANGE# from v$database;CHECKPOINT_CHANGE#------------------52211055已用時間: ?00:00:00.00sys@DBAP01>select max(ktuxescnw*power(2,32)+ktuxescnb)from x$ktuxe;MAX(KTUXESCNW*POWER(2,32)+KTUX------------------------------52211053已用時間: ?00:00:00.00sys@DBAP01>解答:x$ktuxe計算出來的是已經(jīng)結(jié)束的最新的事務(wù)的commit scn,所以可小于當(dāng)前系統(tǒng)scn。檢查點scn自然也小于當(dāng)前系統(tǒng)scn。但是檢查點scn和x$ktuxe計算出來的大小卻倚賴于系統(tǒng)狀況了。current scn是系統(tǒng)當(dāng)前所產(chǎn)生的最大scn,可能是當(dāng)前未結(jié)束事務(wù)所產(chǎn)生的scn。在9i的dbms_flashback.get_system_number可以得到這個值,這個值應(yīng)該是大于等于x$ktuxe SCN (這個view記錄的是當(dāng)前數(shù)據(jù)庫結(jié)束事務(wù)的最大scn)
oracle視頻教程請關(guān)注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html
要了解這個檢查點,首先要知道checkpoint queu概念,檢查點發(fā)生后,觸發(fā)dbwn,CKPT獲取發(fā)生檢查點時對應(yīng)的SCN,通知DBWn要寫到這個SCN為止,dbwr寫dirty buffer是根據(jù)buffer在被首次modify的時候的時間的順序?qū)懗?#xff0c;也就是buffer被modify的時候會進入一個queue(checkpoint queue),dbwr就根據(jù)queue從其中批量地寫到數(shù)據(jù)文件。由于這里有一個順序的關(guān)系,所以dbwr的寫的進度就是可衡量的,寫到哪個buffer的時候該buffer的首次變化時候的scn就是當(dāng)前所有數(shù)據(jù)文件block的最新scn,但是由于無法適時的將dbwr的進度記錄下來,所以oracle選擇了一些策略。其中就包括ckpt進程的檢查點和心跳。
但oracle考慮到檢查點scn的間隔還是太大了,因為檢查點的觸發(fā)條件有限,周期可能比較長,有些情況下比如檢查點需要5分鐘才觸發(fā),那這個時候系統(tǒng)crash再重新啟動就意味著很可能系統(tǒng)需要5分鐘才能啟動。
于是oracle采用了一個心跳的概念,以3秒的頻率將dbwr寫的進度反應(yīng)到控制文件中,這樣系統(tǒng)crash重新啟動的時候?qū)母囊粋€時間點開始恢復(fù)。
再這里同樣需要說明的一點是dbwr并不是只有當(dāng)檢查點發(fā)生的時候才寫,它大約有10幾種條件觸發(fā)寫操作
所以這個問題,我們需要理解的是oracle為什么要這么做?oracle的目的就是縮短崩潰恢復(fù)時間!
oracle如何縮短恢復(fù)時間?1:檢查點機制2:心跳機制oracle為什么不適時的將dbwr寫進度反應(yīng)到文件中?適時反應(yīng)成本太高!3秒種是一個合適的值,可以接受,代價不高又能大大縮短崩潰后恢復(fù)時間。
檢查點發(fā)生以后,CKPT進程檢查checkpoint queue(也就是臟塊鏈表)是否過長,如果是,則觸發(fā)DBWn,將一部分臟塊寫入數(shù)據(jù)文件,從而縮短checkpoint queue。
checkpoint發(fā)生時,一方面通知dbwr進行下一批寫操作,(dbwr寫入的時候,一次寫的塊數(shù)是有一個批量寫的隱藏參數(shù)控制的。)另一方面,oracle采用了一個心跳的概念,以3秒的頻率將dbwr寫的進度反應(yīng)到控制文件中,也就是把dbwr當(dāng)前剛寫完的dirty buffer對應(yīng)的scn寫入數(shù)據(jù)文件頭和控制文件,這就是檢查點scn。
這個3秒和增量檢查點不是一個概念,3秒只是在控制文件中,ckpt進程去更新當(dāng)前dbwr寫到哪里了,這個對于ckpt進程來說叫heartbeat,heartbeat是3秒一次,3秒可以看作不停的檢查并記錄檢查點執(zhí)行情況(DBWR的寫進度)。
檢查點發(fā)生之后數(shù)據(jù)庫的數(shù)據(jù)文件、控制文件處于一致狀態(tài)的含義是不需要進行介質(zhì)恢復(fù),只表示數(shù)據(jù)文件頭一致,但是并不表示數(shù)據(jù)文件內(nèi)容一致,因為數(shù)據(jù)文件內(nèi)容可能在沒有發(fā)生檢查點的其他情況下的dbwr寫數(shù)據(jù)文件,這樣數(shù)據(jù)文件內(nèi)容就不一致,若掉電需要進行崩潰恢復(fù)。二、觸發(fā)的條件這里需要明白兩個概念“完全檢查點和增量檢查點”的區(qū)別。1、增量檢查點(incremental checkpoint)oracle8之前,那時候沒有chekpoint queue,也沒有增量的概念,dirty buffer的寫出是無順的,就是凍結(jié)所有dml等候所有dirty buffer被寫出。后來隨著數(shù)據(jù)庫規(guī)模的擴展和buffer cache的不斷增大,oracle意識到這個機制已經(jīng)滿足不了需要,所以提出增量檢查點的概念,建立了checkpoint queue,讓dirty buffer header根據(jù)首次變化時候的順序排列在queue里面。這樣dbwr只要順著queue的順序?qū)?#xff0c;而其他進程不必等候dbwr的寫操作完成就可以繼續(xù)。
自從有了checkpoint queue之后,檢查點就成為一個短暫的動作,就是通知dbwr你要繼續(xù)寫dirty buffer到當(dāng)前檢查點發(fā)生時候的scn,然后將當(dāng)前dbwr剛寫完的dirty buffer對應(yīng)的scn,寫進數(shù)據(jù)文件和控制文件【增量檢查點時不寫數(shù)據(jù)文件頭】(比如日志切換這種動作引起的檢查點動作等)。然后檢查點動作就結(jié)束了。剩下的工作就交給DBWn了,檢查點進程也不必等候dbwr的完成。
ckpt進程通知dbwr之后并不需要等待dbwr寫到當(dāng)前這個檢查點對應(yīng)的時間點。所以ckpt可以將已經(jīng)完成的最后一個檢查點scn寫到控制文件和數(shù)據(jù)文件(可能是上一個,也可能是上上個,總之dbwr完成了哪個算哪個)。這樣本次需要寫進數(shù)據(jù)文件的dirty buffer可能在下一次檢查點發(fā)生的時候已經(jīng)寫完了,這樣下一次檢查點發(fā)生的時候就把本次的檢查點scn更新到控制文件和數(shù)據(jù)文件。
在oracle 8之前,沒有ckpt queue,只有LRU list,而LRU list里面的Dirty Buffer是不按時間順序排列的,所以checkpoint時都會做一個full thread checkpoint,將LRU list中的所有buffer寫到數(shù)據(jù)文件。
在oracle8i以后,當(dāng)發(fā)生FULL CHECKPOINT時,oracle只是獲取系統(tǒng)當(dāng)前的SCN,然后將這個SCN之前的臟數(shù)據(jù)塊寫入磁盤,后續(xù)的DML臟數(shù)據(jù)塊繼續(xù)入隊,他并不是保證整個緩沖區(qū)沒有臟塊,只是保證此檢查點發(fā)生之前這段距離間沒有臟塊,而在checkpoint點之后的DML可以正常操作。
oracle8以后推出了incremental checkpoint的機制,在以前的版本里每checkpoint時都會做一個full thread checkpoint,這樣的話所有臟數(shù)據(jù)會被寫到磁盤,巨大的i/o對系統(tǒng)性能帶來很大影響。為了解決這個問題,oracle引入了checkpoint queue機制,每一個臟塊會被移到檢查點隊列里面去,按照low rdb(第一次對此塊修改對應(yīng)的redo block address)來排列,靠近檢查點隊列尾端的數(shù)據(jù)塊的low rba值是最小的,而且如果這些贓塊被再次修改后它在檢查點隊列里的順序也不會改變,這樣就保證了越早修改的塊越早寫入磁盤。每隔3秒鐘ckpt會去更新控制文件和數(shù)據(jù)文件,記錄checkpoint執(zhí)行的情況。
在運行的Oracle數(shù)據(jù)中,有很多事件、條件或者參數(shù)來觸發(fā)檢查點。比如(1)當(dāng)已通過正常事務(wù)處理或者立即選項關(guān)閉例程時;(shutdown immediate或者Shutdown normal;)(2)當(dāng)通過設(shè)置初始化參數(shù)LOG_CHECKPOINT_INTERVAL、LOG_CHECKPOINT_TIMEOUT和FAST_START_IO_TARGET強制時;(3)當(dāng)數(shù)據(jù)庫管理員手動請求時;(ALter system checkpoint)(4)alter tablespace ... offline;(5)每次日志切換時;(alter system switch logfile)需要說明的是,alter system switch logfile也將觸發(fā)完全檢查點的發(fā)生。alter database datafile ... offline不會觸發(fā)檢查點進程。
如果是單純的offline datafile,那么將不會觸發(fā)文件檢查點,只有針對offline tablespace的時候才會觸發(fā)文件檢查點,這也是為什么online datafile需要media recovery而online tablespace不需要。
對于表空間的offline后再online這種情況,最好做個強制的checkpoint比較好。上面幾種情況,將觸發(fā)完全檢查點,促使DBWR將檢查點時刻前所有的臟數(shù)據(jù)寫入數(shù)據(jù)文件。
另外,一般正常運行期間的數(shù)據(jù)庫不會產(chǎn)生完全檢查點,下面很多事件將導(dǎo)致增量檢查點,比如:在聯(lián)機熱備份數(shù)據(jù)文件前,要求該數(shù)據(jù)文件中被修改的塊從DB_Buffer寫入數(shù)據(jù)文件中。所以,發(fā)出這樣的命令:ALTER TABLESPACE tablespace_name BIGEN BACKUP & end backup;也將觸發(fā)和該表空間的數(shù)據(jù)文件有關(guān)的局部檢查點;另外,ALTER TABLESPACE tablespace_name READ ONLY;ALTER TABLESPACE tablespace_name OFFLINE NORMAL;等命令都會觸發(fā)增量檢查點。
注意:每隔三秒也會觸發(fā)檢查點,但是并沒有被oracle正式作為一種檢查點的觸發(fā)方式列入文檔,并且這個3秒是記錄dbwr進度而不是通知dbwr寫。這是三秒觸發(fā)的檢查點與其它條件觸發(fā)檢查點不同的地方。
三、關(guān)于low cache rba與on disk rba的理解:簡單說:low cache rba就是CKPT記錄的DBWR寫的進度。on disk rba就是LGWR的寫進度。
如果數(shù)據(jù)庫carsh,low cache rba是恢復(fù)的起點,on disk rba是恢復(fù)的終點。
闡述一下:dbwr成功寫完后并不把此刻scn信息寫到控制文件中,只有CKPT才更新控制文件和數(shù)據(jù)文件頭,dbwr只要成功將dirty data寫入數(shù)據(jù)文件就是成功,CKPT只要能將最新DBWR寫完的SCN更新到控制文件和數(shù)據(jù)文件頭就算成功。但是由于CKPT進程不是實時更新dbwr寫完的scn到控制文件中,而是采用每3妙更新一次的策略,因此最后有ckpt進程寫進控制文件的scn信息有可能不是當(dāng)前dbwr剛剛寫完的scn值。這點應(yīng)該注意,也就是說dbwr寫的進度與ckpt進程更新控制文件的進度是不同的。
關(guān)于檢查點的一點具體應(yīng)用討論:1、Commit成功后,數(shù)據(jù)還會丟失嗎?
對于Oracle來說,用戶所做的DML操作一旦被提交,則先是在database buffer cache中進行修改,同時在修改之前會將數(shù)據(jù)的前鏡像保存在回滾段中,然后將修改之前和修改之后的數(shù)據(jù)都寫入到redo log buffer中,當(dāng)接收到commit命令之后,則redo log buffer開始寫redo log file,并且記錄此時的scn,當(dāng)redo log file寫完了之后,表示這次事務(wù)提交操作已經(jīng)確認(rèn)被數(shù)據(jù)庫記錄了,只有當(dāng)redo log file寫成功了,才會給用戶Commit completed的成功字樣。而對于Database buffer cache中的dirty buffer則會等待觸發(fā)DBWn才寫入,但是如果此時斷電,則數(shù)據(jù)已經(jīng)被記錄到了redo log file中,系統(tǒng)在重新啟動的時候,會自動進行嵌滾和回滾來保證數(shù)據(jù)的一致。所以,只要是commit成功的了,數(shù)據(jù)不會丟失!
2、數(shù)據(jù)庫發(fā)生一次DBWn,是否將所有buffer cache中的dirty buffer都寫入,還是先將臟隊列中的數(shù)據(jù)寫入?這話看起來有道理,但實際上,dbwr在寫的時候又不斷地在產(chǎn)生dirty buffer ,所以說檢查點發(fā)生的時候是期望把該時間點之前的所有臟緩沖區(qū)寫入數(shù)據(jù)文件。所有的buffer,不在LRU list上就在dirty list上, dbwr寫入的時候,一次寫的塊數(shù)是有一個批量寫的隱藏參數(shù)控制的。所以說要是dbwr將dirty list也好,lru list上的也好,要實現(xiàn)全部寫入,都是一個現(xiàn)實系統(tǒng)中很難存在的現(xiàn)象。dirty總是在不斷的產(chǎn)生,dbwr總是在不斷地寫,增量檢查點發(fā)生的時候也并不意味著一定要更新數(shù)據(jù)文件頭,檢查點開始的時候只表示該次檢查點結(jié)束的時候要更新數(shù)據(jù)文件頭的話數(shù)據(jù)文件頭具有該時間點的一致性。
3、data block里面不是也有SCN嗎?和文件頭里面的SCN有什么關(guān)系?什么時候被更新?代表的是是什么含義?data block里面的SCN是當(dāng)block被更改的時候的SCN而數(shù)據(jù)文件有那么多block,自然不同的block有不同的SCNblock中存在block SCN和ITL中的commit SCNblock SCN又在塊頭和塊位都有,若不一致意味著block損壞(熱碑可能出現(xiàn)這個情況,需要從redo log中拷貝回來,若是正在修改的過程中由于進程死掉則pmon負(fù)責(zé)清理。若由于一些以外發(fā)生這樣的不一致的情況,則查詢的時候出現(xiàn)1578錯誤,當(dāng)然該錯誤號也可能是物理磁盤損壞,這里表示邏輯的損壞!)
這個頭和尾的SCN的檢查時機跟這兩個參數(shù)有關(guān):db_block_checking boolean FALSEdb_block_checksum boolean FALSE該兩參數(shù)信息請查閱http://tahiti.oracle.com而ITL中的commit SCN則跟consistent gets and delay block cleanout有關(guān)數(shù)據(jù)文件頭的SCN是檢查點發(fā)生時更新的,代表著當(dāng)恢復(fù)的時候從這個SCN點開始在log file中尋找redo開始做恢復(fù)。
4、怎么解釋這個現(xiàn)象?看下面的操作!___________________________________________________________sys@DBAP01>select max(ktuxescnw*power(2,32)+ktuxescnb)from x$ktuxe;MAX(KTUXESCNW*POWER(2,32)+KTUX------------------------------52211024已用時間: ?00:00:00.00sys@DBAP01>alter system checkpoint;系統(tǒng)已更改。已用時間: ?00:00:00.06sys@DBAP01>select CHECKPOINT_CHANGE# from v$database;CHECKPOINT_CHANGE#------------------52211055已用時間: ?00:00:00.00sys@DBAP01>select max(ktuxescnw*power(2,32)+ktuxescnb)from x$ktuxe;MAX(KTUXESCNW*POWER(2,32)+KTUX------------------------------52211053已用時間: ?00:00:00.00sys@DBAP01>解答:x$ktuxe計算出來的是已經(jīng)結(jié)束的最新的事務(wù)的commit scn,所以可小于當(dāng)前系統(tǒng)scn。檢查點scn自然也小于當(dāng)前系統(tǒng)scn。但是檢查點scn和x$ktuxe計算出來的大小卻倚賴于系統(tǒng)狀況了。current scn是系統(tǒng)當(dāng)前所產(chǎn)生的最大scn,可能是當(dāng)前未結(jié)束事務(wù)所產(chǎn)生的scn。在9i的dbms_flashback.get_system_number可以得到這個值,這個值應(yīng)該是大于等于x$ktuxe SCN (這個view記錄的是當(dāng)前數(shù)據(jù)庫結(jié)束事務(wù)的最大scn)
oracle視頻教程請關(guān)注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html
轉(zhuǎn)載于:https://blog.51cto.com/19880614/1194643
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的oracle技术之检查点及SCN深入研究的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法时间复杂度和空间复杂度表示
- 下一篇: ORA-01940,删除某用户的所有对象