溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ORACLE CheckpointQueue和增量檢查點

發布時間:2020-08-05 11:33:46 來源:ITPUB博客 閱讀:185 作者:Davis_itpub 欄目:關系型數據庫
<p style="margin:0in;font-size:20.0pt;"> ORACLE CheckpointQueue和增量檢查點 </p> <p style="margin:0in;font-size:10.0pt;color:gray;"> <br /> </p> <p style="margin:0in;line-height:15pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;檢查點的主要目的是以對數據庫的日常操作影響最小的方式刷新臟塊。臟塊不斷的產生,如何將臟塊刷新到磁盤中去呢?在8i之前,Oracle定期的鎖住所有的修改操作,將Buffer&nbsp;cache中的所有臟塊刷到磁盤,這種刷新臟塊的方式被稱為完全檢查點,這極大的影響了效率,從9i之后只有當關閉數據庫時才會發生完全檢查點。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;從8i開始,Oracle增加了增量檢查點的概念,增量檢查點的主要作用就是定期的刷新一部分臟塊。將臟塊一次刷新完是不合理的,因為臟塊不斷產生,沒有窮盡。像完全檢查點那樣停止用戶所有的修改操作,將臟塊刷新完再繼續,這絕對會極大的影響性能。所有增量檢查點的一次刷新部分塊是臟塊問題的最好解決辦法。那么,每次刷新時,都刷新那些塊呢?根據統計研究,根據塊變臟的順序,每次刷新那些最早臟的塊,這種方式最為合理。為了實現這一點,Oracle在Buffer&nbsp;cache中又建立了一個鏈表,就是檢查點隊列。每個塊在它變臟時,會被鏈接到檢查點隊列的末尾。就好像排隊一樣,9:00來的人站在第一位,9:05來的人排第二位,以后每來一個人都站在隊伍的末尾,這個隊伍就是按來到的時間順序排列的一個隊列。檢查點隊列就是這樣,塊在變臟時會被鏈到末尾。因此檢查點隊列是按塊變臟的時間順序,將塊排成了一個隊列。<br /> <img src="/attachment/201510/16/30208428_1444975767vwC5.png" width="492" height="419" alt="" /> </p> <p style="margin:0in;"> <br /> </p> <p style="margin:0in;font-family:Calibri;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;如上圖,檢查點隊列中的每一節點,都指向一個臟塊。檢查點隊列每個節點中的信息其實非常少,就是記錄對應塊在Buffer&nbsp;cache中的地址,臟塊對應的重做記錄在日志文件中的位置,另外還有前一個節點、后一個節點的地址。檢查點隊列還有LRU、臟LRU,這些都是雙向鏈表。雙向鏈表就是在節點中記錄前、后兩個節點的地址。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;檢查點隊列頭部的塊是最早變臟的,因此,Oracle會定期喚醒DBWn從檢查點隊列頭開始,沿著檢查點隊列的順序,刷新臟塊。在刷新臟塊的同時,仍可以不斷的有新的臟塊被鏈接到檢查點隊列的尾部。這個定期喚醒DBWn刷新臟塊的操作,Oracle就稱為增量檢查點。 </p> <p style="margin:0in;"> <img src="/attachment/201510/16/30208428_1444975767MqJO.png" width="566" height="482" alt="" style="font-family:微軟雅黑;font-size:14px;line-height:21px;white-space:normal;" /> </p> <p style="margin:0in;font-family:Calibri;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin:0in;font-family:Calibri;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;如上圖,1、2、3號節點所指向的臟塊已經被刷新為干凈塊。同時,又有兩個塊變臟,它們被鏈接到了檢查點隊列的末尾,它們是9號、10號節點。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;檢查點隊列的頭,又被稱為檢查點位置,Checkpoint&nbsp;postion,這些名稱我們不必從字面上去理解??傊?,檢查點位置就是檢查點隊列頭。檢查點隊列頭節點(也就是檢查點位置)的信息,Oracle會頻繁的將它記錄到控制文件中,而且會很頻繁的記錄。一般是每隔三秒,有一個專門的進程CKPT,會將檢查點位置記錄進控制文件。<br /> </p> <p style="margin:0in;"> <img src="/attachment/201510/16/30208428_1444975767KgK4.png" width="589" height="537" alt="" style="font-family:微軟雅黑;font-size:14px;line-height:21px;white-space:normal;" /> </p> <p style="margin:0in;font-family:Calibri;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;如上圖,當前的檢查點位置是檢查點隊列的1號節點。又一個三秒到了,CKPT進程啟動,將新的檢查點位置記入控制文件: </p> <p style="margin:0in;"> <img src="/attachment/201510/16/30208428_1444975768lqo9.png" width="582" height="510" alt="" style="font-family:微軟雅黑;font-size:14px;line-height:21px;white-space:normal;" /> </p> <p style="margin:0in;font-family:Calibri;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;新的檢查點位置是4號節點,它對應當前變臟時間最早的臟塊。1、2、3號節點已經從檢查點隊列中摘除了。因為它們對應的臟塊已經不臟了。一般來說,控制文件中的檢查點位置之后的塊都是臟塊。但是有時也例外,因檢查點位置每三秒才會更新一次,就像上圖,1、2、3號節點對應的臟塊已經被刷新過了,但是由于三秒間隔沒到,檢查點位置還是指向1號節點。只有當三秒到后,檢查點位置才會被更新到4號節點上。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;關于檢查點隊列、檢查點位置我們先說到這里,在全面的介紹什么是增量檢查點之前,我們先說一下檢查點隊列的一個重要作用。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;讓我們先來總結一下用戶修改塊時,Oracle內部都發生了什么: </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;1.如果塊不在Buffer&nbsp;cache,將塊讀入Buffer&nbsp;cache </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;2.先生成重做記錄,并記入日志緩存,在用戶提交時寫到日志文件中 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;3.在Buffer&nbsp;cache中修改塊 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;4.在Buffer&nbsp;cache中設置塊的臟標志位,標志塊變成臟塊,同時在檢查點隊列末尾增加一個新節點,記錄這個新臟塊的信息,信息包括:臟塊在Buffer&nbsp;cache中的位置,在步驟2時生成的與此臟塊對應的重做記錄位置。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;5.用戶提交后,將相應的重做記錄從重做緩存寫入日志文件。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;我現在將日志補充到上面的圖中: </p> <p style="margin:0in;"> <img src="/attachment/201510/16/30208428_1444975772w6Jb.png" width="585" height="400" alt="" style="font-family:微軟雅黑;font-size:14px;line-height:21px;white-space:normal;" /> </p> <p style="margin:0in;font-family:Calibri;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;就像上圖,檢查點隊列的每個節點,都保存有臟塊的地址和臟塊對應的重做記錄的編號。臟塊在Buffer&nbsp;cache中的位置是隨機的,用戶不一定修改那個塊。但重做記錄是順序生成的,就和檢查點隊列的排列順序一樣。因為,它們都是當塊被修改而變臟時產生的。塊A先被修改,塊A的重做記錄就排在前面,塊B后被修改,塊B對應的重做記錄會被排在塊A對應的重做記錄的后面。和它們在檢查點中的順序是一樣。每當數據庫因異外而當機,比如異常死機、斷電等等,Buffer&nbsp;cache中有許多臟塊沒來的及寫到磁盤上。以圖為例,比如說現在斷電了,現在磁盤上還有7個臟塊,它們里面有用戶修改過的數據,Oracle已經將反饋信息“你的修改完成”發送給用戶,用戶也以為他們的修改完成了,將為一直保存到數據庫中。但是,斷然的斷電,令這幾個臟塊中的數據丟失了,它們沒來得及寫到磁盤上。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp;&nbsp; &nbsp;&nbsp;Oracle如何解決這個問題呢?很簡單,當數據庫重新啟動時,Oracle只需從控制文件中讀出檢查點位置,檢查點位置中記錄有重做記錄編號,根據此編號,Oracle可以很快的定位到日志文件中的重做記錄n,它讀出重做記錄n中的重做數據,將用戶的修改操作重現到數據庫。接著,Oracle讀取重做記錄n+1中的重做數據,重現用戶修改,這個過程將沿著日志流的順序,一直進行下去,直擋最后一條重做記錄,在上圖的例子中,最后一條重做記錄是第n+6條。這個過程完成后,用戶所有的修改又都被重現了,一點都不會丟失。只要你的日志文件是完整,日志流是完整的,就一點信息都不會丟失。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;有人可能會有一個問題,重做記錄在生成后,也是先被送進重做緩存,再由重做緩存寫往日志文件。這樣的機制下,一定會有某些重做記錄在沒來的及寫到日志文件中時,數據庫突然當機,而造成這些重做記錄丟失。這樣,這些重做記錄所對應的臟塊,將得不到恢復。用戶還是會丟失一些數據。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;這種情況的確會發生,但丟失的都是沒用的信息。為什么這么說的。Oracle會在用戶每次發出提交命令時,將事務所修改臟塊對應的重做記錄寫進日志文件,只有當這個操作完成時,用戶才會收到“提交完成”,這樣的信息,對于一個完整的事務,當用戶看到提交完成后,也就意味著所對應的重做記錄一定被寫到了日志文件中,即使發生異常死機,它也是絕對可以恢復。而當用戶沒有提交,或沒來得及提交,數據庫就崩潰了,那么事務就是不完整的,這個事務必須被回滾,它根本用不著恢復。對于這樣不完整的事務,它對應的重做記錄有可能丟失,但這無所謂了,因為不完整的事務根本不需要恢復。也就是說,只有用戶的事務提交了,用戶的修改一定不會丟失。不過這還有一個前提,就是日志文件千萬不能損壞,DBA所要做的就是要保證日志文件不能損壞。DBA可以使用RAID1這樣的磁盤鏡像技術,或者多元備份日志文件,等等,這個我們在前面章節中已經講過了的。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;我們上面所講到的這種恢復,是自動進行的,并且不需要DBA參與,它被稱之為實例恢復。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;檢查點隊列與增量檢查點的作用我們已經說的差不多了,它們的主要目的就是讓DBWn沿檢查點隊列的順序刷新臟塊。還有,就是實例恢復。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;下面我們來討論一下增量檢查點的設置。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;這里所說的檢查點設置,主要指增量檢查點頻繁的設置。注意增量檢查點只是一個名詞,不必按字面的意義去理解它。增量檢查點發生時,Oracle會喚醒DBWn沿著檢查點隊列寫臟塊,這就是增量檢查點。那么到底多長時間一次發生一次增量檢查點呢?這個增量檢查點的頻率是非常重要的,它基本上控制著DBWn多長時間去刷新一次臟塊。DBWn活動的太頻繁,會影響數據庫的整體性能,如果DBWn活動太不頻繁,又會使臟塊擠壓太多,這同樣也會影響性能。而且,如果出現異常崩潰,需要實例恢復,臟塊越多,實例恢復越慢。。在9i之前DBA主要靠間隔時間等方式來設置增量檢查點的頻率,比如可以讓Oracle每10分鐘發生一次增量檢查點。如果這個數字設置不合適,對數據庫性能的影響是很大的。而且有可能造成實例恢復時間過長。在9i之后,特別是到了10g中,檢查點已經相當的智能化了,很少會成為I/O問題的原兇。9i中設置fast_start_mttr_target參數為你所期望的實例恢復時間,系統將自動控制增量檢查點的頻率。比如,你希望實例恢復可以在5分鐘內完成,你可以將此參數設置為300,也就是300稱。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;如果此參數設置的值超出了硬件實際的限制,比如你將它設置為60,你期望無論在任何情況下,數據庫都可以在1分鐘內完成實例恢復,但根據數據庫的臟塊生成速度、存儲設備的寫性能,1分鐘內根本無法完成實例恢復。這時候Oracle會自動設置合適的fast_start_mttr_target參數值,我們可以在參數文件中看到修正后的參數值,也可以在V$instance_recovery視圖中的Target_mttr列中看到實際的值。例如: </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;(舉個例子) </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;我們不能將這個值設置的太小,因為實例恢復必競只是偶然現象。如果為了讓實例恢復盡快完成,而設置fast_start_mttr_target為很小的值,那么DBWn將活動的很頻繁,這會造成性能問題的。為了避免用戶設置不合理的增量檢查點頻率,在10G中,如果將fast_start_mttr_target設置為0,Oracle將根據產生臟塊的速度、存貯硬件的性能自動調節檢查點的頻率,盡量使檢查點頻率不成為I/O問題的原兇。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;檢查點的主要任務就是催促DBWn刷新臟塊,如果DBWn刷新臟塊時的等待事件太多,就說明臟塊太多、存儲設備的寫速度太慢,或者就是增量檢查點的頻率太高了,或太低了。DBWn寫臟塊的等待事件是Db&nbsp;file&nbsp;parallel&nbsp;write。如果你的增量檢查點頻率很低,你發現了此事件,在排除了存儲設備寫性能的問題后,你應該將增量檢查點頻率設置的高一些。反之,如果你的增量檢查點頻率本身很高,出現了Db&nbsp;file&nbsp;parallel&nbsp;write事件,這說明檢查點頻率太高了。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;除它之外,還有一個和DBWn、增量檢查瞇有關的等待事件,它是Write&nbsp;complete&nbsp;waits事件,當前臺進程要修改DBWn正要成批寫的塊中的若干個塊時,就會有此等待事件,這個事件是前臺進程再等待DBWn寫完成。這個等待事太多,說明了存儲設備寫性能有問題,或者增量檢查點太頻率了。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;我們可以V$instance_recovery中看到有關檢查點的很多信息: </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:&quot;font-size:11.0pt;" lang="x-none"> &nbsp; </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;Estimated_mttr列如果太大,說明檢查點不夠頻繁,同時也說明臟塊產生的太多。同時在V$sysstat資料視圖中,還有兩個資料background&nbsp;checkpoints&nbsp;started、background&nbsp;checkpoints&nbsp;completed,前面的一個是后臺進程檢查點開始次數,后一個是后臺進程檢查點完成次數。后臺進程檢查點的意義,其實就是增量檢查點。只有增量檢查點是由后臺進程觸發的。如果你用Alter&nbsp;system&nbsp;checkpoing命令讓系統完成完全檢查點,這叫做前臺檢查點與增量檢查點無關,是不會被記入這兩個資料了。如果這兩個值經常相差一些,比如檢查點的開始次數比完成次數大的不至1,這說明有太多次檢查點開始,但沒有及時完成。這說明檢查點太頻繁或檢查點完成的太慢。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;(舉例,大量的產生臟塊、日志文件比較小5MB,日志文件頻率的切換而觸發檢查點,同時查看一下等待事件) </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;檢查點的問題大多數情況下其實都是DBWn寫I/O的問題,&nbsp;DBWn寫臟塊的等待事件是Db&nbsp;file&nbsp;parallel&nbsp;write,還有Write&nbsp;complete&nbsp;waits等待事件,是當前臺進程要修改DBWn正要成批寫的塊中的若干個塊時,就會有此等待事件,這個事件是前臺進程再等待DBWn寫完成。這個等待事太多,也說明了DBWn有問題。 </p> <p style="margin-top:3pt;margin-bottom:3pt;font-family:微軟雅黑;font-size:10.5pt;"> &nbsp; &nbsp; &nbsp;注意,對于數據文件的I/O問題,除了等待事件外,我們還可以用上幾節講過了V$filestat視圖幫助確定問題。) </p>
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女