溫馨提示×

溫馨提示×

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

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

Oracle檢查點是什么

發(fā)布時間:2021-11-10 10:30:00 來源:億速云 閱讀:136 作者:iii 欄目:關系型數(shù)據(jù)庫

本篇內(nèi)容主要講解“Oracle檢查點是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Oracle檢查點是什么”吧!

1.檢查點概念--chkpoint 

檢查點是一個數(shù)據(jù)庫事件,存在的意義在于減少崩潰恢復crash recovery時間.
檢查點事件由后臺進程CKPT觸發(fā),當檢查點發(fā)生時,CKPT通知DBWR進程將臟數(shù)據(jù)庫dirtybuffer寫出到數(shù)據(jù)文件上,更新數(shù)據(jù)文件頭及控制文件上的檢查點信息。
數(shù)據(jù)文件頭的SCN是CHECKPOINT SCN.

checkpoint相關概念術語

在說明checkpoint工作原理之前我們先了解一些相關的術語。

RBA(Redo Byte Address), Low RBA(LRBA), High RBA(HRBA)

RBA就是重做日志塊(redo log block)的地址,相當與數(shù)據(jù)文件中的ROWID,通過這個地址來定位重做日志塊。RBA由三個部分組成:

  1. 日志文件序列號(4字節(jié))——根據(jù)這個找到對應的日志文件地址。

  2. 日志文件塊編號(4字節(jié))——根據(jù)這個找到對應日志條目所在的日志文件塊。

  3. 重做日志記錄在日志塊中的起始偏移字節(jié)數(shù)(2字節(jié))——找到對應的日志條目。

通常使用RBA的形式有:

LRBA 數(shù)據(jù)緩存(buffer cache)中一個臟塊第一次被更新的時候產(chǎn)生的重做日志記錄在重做日志文件中所對應的位置就稱為LRBA。 HRBA 數(shù)據(jù)緩存(buffer cache)中一個臟塊最近一次被更新的時候產(chǎn)生的重做日志記錄在重做日志文件中所對應的位置就稱為HRBA。 checkpoint RBA 當一個checkpoint事件發(fā)生的時候,checkpoint進程會記錄下當時所寫的重做日志塊的地址即RBA,此時記錄的RBA被稱為checkpoint RBA。從上一個checkpoint RBA到當前的checkpoint RBA之間的日志所保護的buffer cache中的臟塊接下來將會被寫入到數(shù)據(jù)文件當中去。

1、關于checkpoint的概述

checkpoint是oracle在數(shù)據(jù)庫一致性關閉、實例恢復和oracle基本操作中不可缺少的機制,包含以下相關的含義:

                   A、檢查點的位置(checkpoint position)為一種數(shù)據(jù)結(jié)構(gòu),在redo流中記錄的SCN號是在進行數(shù)據(jù)庫實例恢復起始位置。

檢查點的位置由在數(shù)據(jù)緩沖池中存在的最老的臟數(shù)據(jù)位置決定,檢查點的位置相當于一個指向redo流的指針,并且檢查點的信息存儲在控制文件和數(shù)據(jù)文件的頭中。

   B、將數(shù)據(jù)緩沖區(qū)中修改后的臟數(shù)據(jù)寫入到磁盤中。

2、checkpoint的目的

A、當實例恢復或者介質(zhì)恢復時,減少恢復所需要的時間

B、確保在數(shù)據(jù)緩沖區(qū)中的臟數(shù)據(jù)已經(jīng)寫入到磁盤當中

C、確保在進行數(shù)據(jù)庫一致性關閉的時候所有提交的數(shù)據(jù)都寫入到磁盤當中

3、什么時候數(shù)據(jù)庫啟動checkpoint

CKPT進程負責將checkpoint的信息寫入到數(shù)據(jù)文件頭中和控制文件中,包括以下幾種類型的檢查點

A、thread checkpoint(線程檢查點或者數(shù)據(jù)庫檢查點)

數(shù)據(jù)庫將所有在數(shù)據(jù)緩沖區(qū)內(nèi)由redo修改過的數(shù)據(jù)寫入到磁盤中在某些動作之前,這個線程檢查點在所有的實例中的集合稱之為數(shù)據(jù)庫檢查點(database checkpoint),線程檢查點發(fā)生在下列情況下:

——數(shù)據(jù)庫一致性關閉的時候

——ALTER SYSTEM CHECKPOINT語句的時候

——在線日志切換的時候

——ALTER DATABASE BEGIN BACKUP語句的時候

B、tablespace and data file checkpoint(表和數(shù)據(jù)文件檢查點)

數(shù)據(jù)庫將所有在數(shù)據(jù)緩沖區(qū)內(nèi)由redo修改過的數(shù)據(jù)寫入到磁盤中在具體動作之前,表空間的檢查點是數(shù)據(jù)文件檢查點的集合,每個數(shù)據(jù)文件都在這個表空間之內(nèi),此種檢查點發(fā)生在以下情況:

——將一個表空間設置為只讀的方式

——將一個表空間設置為offline

——數(shù)據(jù)文件大小變化的時候

——執(zhí)行ALTER TABLESPACE BEGIN BACKUP的時候

C、incremental checkpoint(增量檢查點)

增量檢查點是線程檢查點的一種,是為了避免在線日志切換的時候需要寫入大量的臟數(shù)據(jù)到磁盤中,DBWn每三秒檢查一次看是否有數(shù)據(jù)是否要寫入到磁盤當中,當DBWn進程需要將臟數(shù)據(jù)寫入到磁盤中時,從而推進檢查點的位置,導致CKPT進程將檢查點位置信息寫入到控制文件中,但是不會寫入到數(shù)據(jù)頭文件中。

D、其他的檢查點包括實例和介質(zhì)恢復檢查點、檢查點當schema對象被dropped和truncated的時候

4、相關進程CKPT

CKPT進程的全稱為checkpoint process,負責:

A、更新控制文件和數(shù)據(jù)頭文件中的檢查點信息

B、通知DBWn進程將臟數(shù)據(jù)寫入磁盤中

檢查點信息包括:

A、檢查點位置

B、SCN

C、在線日志文件中開始恢復的位置

CKPT進程不負責將臟數(shù)據(jù)寫入到磁盤中,不負責將redo緩沖區(qū)的數(shù)據(jù)寫入到在線日志文件中

DBWn進程負責將臟數(shù)據(jù)存盤,LGWR進程負責將redo緩沖區(qū)中的書籍存盤



檢查點工作原理:
在數(shù)據(jù)庫中,進行數(shù)據(jù)修改時,需要先將數(shù)據(jù)讀和內(nèi)存中buffer cache,修改數(shù)據(jù)同時,ORACLE會記錄重做redo信息用于恢復,有了重做日志信息存在,ORACLE不需要在事務提交時commit立刻將變化的數(shù)據(jù)寫回磁盤,因為立刻寫效率會低。重做信息存在也為數(shù)據(jù)崩潰后,數(shù)據(jù)可以恢復。如斷電,內(nèi)存中修改過未寫入數(shù)據(jù)文件的數(shù)據(jù)丟失,下一次數(shù)據(jù)庫啟動時,可以通過重做日志進行事務重演(不管是否提交),即前滾。將數(shù)據(jù)庫恢復至崩潰前狀態(tài),然后數(shù)據(jù)庫可以打開提供使用,之后ORACLE將未提交的事務回滾。
檢查點存在是為了縮短上述數(shù)據(jù)恢復的時間。
當檢查點發(fā)生時,此時的SCN稱為checkpoint scn,ORACLE會通知DBWR,把修改過的數(shù)據(jù),即此checkpoint scn之前的臟數(shù)據(jù)dirty data從buffer cache寫入磁盤,寫入完成后,CKPT進程會相應更新控制文件和數(shù)據(jù)文件頭,記錄此檢查點信息,標識變更。
檢查點完成后,此檢查點之前修改過后 數(shù)據(jù)都已經(jīng)寫出到數(shù)據(jù)文件,重做日志中的相應重做記錄對于實例恢復已經(jīng)無用(物理恢復有用)。
######################################################################

2.增量檢查點概念 incremental checkpoint 及CKPTQ,FILEQ

檢查點隊列,checkpoint queue,CKPTQ;

在數(shù)據(jù)庫內(nèi)部,每個臟數(shù)據(jù)塊會被記錄到檢查點隊列,按LRBA(LOW RBA 第一次修改數(shù)據(jù)塊對應的redo block address,后面修改的RBA稱為HRBA)順序排列,如果一個數(shù)據(jù)塊多次修改,該數(shù)據(jù)塊在檢查點隊列上順序不變化。
非臟塊的buffer header中的CKPTQ信息為空。
執(zhí)行增量檢查點時,DBWR從檢查點隊列按照LOW RBA順序?qū)懗?,先修改的?shù)據(jù)可以被按優(yōu)先順序?qū)懗觯瑢嵗龣z查點因此可以不被增進。
同時CKPT進程階段性使用輕量級控制文件更新協(xié)議將當前最低RBA寫入控制文件,CKPT在進行輕量級更新時,不改寫控制文件中數(shù)據(jù)文件中檢查點信息以及數(shù)據(jù)文件頭信息,只記錄控制文件檢查點SCN,controlfile checkpointed at scn 并根據(jù)增量檢查點寫出增進RBA信息。
通過增量檢查點,數(shù)據(jù)庫可以將全部寫出改為增量漸進寫出,從而極大減少對于數(shù)據(jù)庫性能的影響,而檢查點隊列進一步將RBA和檢查點關聯(lián)起來,從而可以通過檢查點確定恢復的起點。

與CKPTQ相關的是:文件檢查點隊列 file queue  FILEQ與對象隊列Obj-Q 

文件檢查點提高了表空間檢查點TABLESPACE CHECKPOINT的性能,每個dirty buffer同時鏈接到CKPTQ和FILEQ,CKPTQ包含實例所有需要執(zhí)行檢查點的BUFFER,F(xiàn)ILEQ包含屬于特定文件需要執(zhí)行檢查點的BUFFER,每個文件都包含一個文件隊列,在執(zhí)行表空間檢查點請求時使用FILEQ。--表空間OFFLINE會觸發(fā)表空間檢查點。

3.CKPT進程在增量檢查點中的作用:

CKPT進程監(jiān)控著檢查點隊列的長度,當檢查點隊列長度達到一定限制時,CKPT會通知DBWR寫臟塊
CKPT會根據(jù)參數(shù)的設置和I/O的速度以及繁忙程度,計算出來一個Target rba(目標rba),DBWR會沿著檢查點隊列,將所有Target rba之前的臟塊刷新到磁盤.當CKPT通知完DBWR Target rba后,CKPT的任務就結(jié)束了.并不會等待DBWR寫完所有的Target rba之前的臟塊.

通知DBWR寫臟塊,這是CKPT的任務之一,CKPT另一個任務,就是每3秒,檢測一次DBWR的寫進度.
檢查點隊列最前面的塊被稱為檢查點位置.DBWR是沿著檢查點隊列寫臟塊的,CKPT每3秒鐘查看一下DBWR沿檢查點隊列寫到了哪里,并且將這個位置設置為檢查點位置.也就是說檢查點位置之前的塊,都是已被DBWR刷新到磁盤上的塊.
這個3秒一次檢查DBWR進度的工作,也是CKPT的一個重要的任務.CKPT每3秒一次將檢查點位置記錄進控制文件,當然同時被記錄進控制文件的還有'心跳'等其他信息.

CKPT每3秒一次的工作和CKPT定期觸發(fā)DBWR,這兩項操作合一起被稱為--增量檢查點.

4.dbwr 寫CKPTQ上臟塊的方式:

在檢查點隊列中,臟塊根據(jù)按LRBA順序排列,DBWR每到一定的時機,被觸發(fā)。
硬件能力、臟塊數(shù)、Redo數(shù)三個指標,是DBWR是否寫臟塊的依據(jù)。
DBWR什么時候(多久)判斷一次這三個值標:3s
也就是:DBWR 3秒醒來,依據(jù)三個指標判斷是否觸發(fā)------“增量檢查點寫”

5.fast_start_mttr_target與增量檢查點

一、關于FAST_START_MTTR_TARGET概念:  --此段百度哈哈

是一個加快實例恢復的參數(shù),我們可以根據(jù)服務級別來定義一個合理的、可接受的值,該值的單位為秒。比如設定為60s,即2分鐘。
假定該值處于合理的情況之下,則一旦實例崩潰,在60s以內(nèi)實例應當能夠被恢復。合理即是該值不能太大,也不能太小。太大則實例恢復所需的時間較長,太小則導致大量數(shù)據(jù)的及時寫入,增加了系統(tǒng)的I/O。
影響實例恢復時間長短的主要因素即是從最近檢查點位置到聯(lián)機重做日志尾部之間的距離。距離越長則所需要的cache recovery 和undo、redo的時間越長。所以如何有效的縮短最近檢查點位置與聯(lián)機重做日志尾部之間的距離,這正是FAST_START_MTTR_TARGET的目的。

關于檢查點的觸發(fā)條件有很多,比如日志切換、數(shù)據(jù)庫shutdown、開始結(jié)束備份表空間等。檢查點的分類也很多,比如完全檢查點、部分檢查點、增量檢查點等。
FAST_START_MTTR_TARGET的值實際上也是觸發(fā)檢查點的一個觸發(fā)條件。當內(nèi)存中產(chǎn)生的dirty buffer所需的恢復時間(estimated_mttr)如果到達FAST_START_MTTR_TARGET的指定時間,則檢查點進程被觸發(fā)。檢查點進程一旦被觸發(fā),將通知DBWn進程將按檢查點隊列順序?qū)⑴K數(shù)據(jù)寫入到數(shù)據(jù)文件,從而縮短了最后檢查點位置與聯(lián)機重做日志間的距離,減少了實例恢復所需的時間。

二、FAST_START_MTTR_TARGET參數(shù)的設置

9i之后(包括9i):fast_start_mttr_target:以實例恢復時間為單位(硬件能力、臟塊數(shù)、Redo數(shù))
10G之后,fast_start_mttr_target默認值為0,即開啟自調(diào)節(jié)檢查點:self tune checkpoint ,自調(diào)節(jié)檢查點的受影響因素有:硬件能力、臟塊數(shù)、Redo數(shù)
自調(diào)節(jié)檢查點對應隱含參數(shù):_disable_selftune_checkpointing:
_disable_selftune_checkpointing          Disable self-tune checkpointing             FALSE       
SYS@ bys3>show parameter statistics_level  --此參數(shù)為typical 或者all,再加上FAST_START_MTTR_TARGET 設置為非零值就啟用MTTR Advisory

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
statistics_level                     string      TYPICAL
SYS@ bys3>show parameter mttr
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
fast_start_mttr_target               integer     0
從alert日志中數(shù)據(jù)庫啟動時的信息可以發(fā)現(xiàn):
[oracle@bys3 ~]$ cat alert_bys3.log |grep MTTR
MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set

顯式的設置alter system set FAST_START_MTTR_TARGET=0會關閉自動調(diào)節(jié),重啟數(shù)據(jù)庫在alter日志中可以發(fā)現(xiàn):
MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set

當FAST_START_MTTR_TARGET顯示設為非零
SYS@ bys3>alter system set fast_start_mttr_target=25;
即: statistics_level參數(shù)為typical 或者all,再加上FAST_START_MTTR_TARGET 設置為非零值就啟用MTTR Advisory
此時alert日志中不會有MTTR信息--因為已經(jīng)正常啟動MTTR Advisory

三、關于啟動MTTR Advisory時v$instance_recovery;視圖的使用: --未開啟MTTR Advisory時此視圖內(nèi)容為空。

SYS@ bys3>select mttr_target_for_estimate ,dirty_limit,estd_cache_writes ,estd_cache_write_factor ,estd_total_writes ,estd_total_write_factor  from v$mttr_target_advice;
MTTR_TARGET_FOR_ESTIMATE DIRTY_LIMIT ESTD_CACHE_WRITES ESTD_CACHE_WRITE_FACTOR ESTD_TOTAL_WRITES ESTD_TOTAL_WRITE_FACTOR
------------------------ ----------- ----------------- ----------------------- ----------------- -----------------------
                      18        1067                57                       1               806                       1
                      17        1000                57                       1               806                       1
                      19        1268                57                       1               806                       1
                      20        1507                57                       1               806                       1
SYS@ bys3>select  target_mttr,estimated_mttr from v$instance_recovery; 
TARGET_MTTR ESTIMATED_MTTR
----------- --------------
         20             12
--mttr_target_for_estimate有一個值為的最接近設定的目標時間20,以及由系統(tǒng)計算出的的target_mttr時間20
--同時也給出了幾組不同的mttr_target值及dirty_limit,cache_write,io 等來供選擇,設定合適的mttr值




檢查點(Checkpoint)優(yōu)化及故障排除指南 (文檔 ID 1526118.1)

Oracle檢查點是什么類型:狀態(tài):上次主更新:上次更新:語言:BULLETINPUBLISHED2015-6-232016-12-7English簡體中文???

Oracle檢查點是什么

適用于:

Oracle Database - Enterprise Edition
本文檔所含信息適用于所有平臺

用途

本文檔旨在使數(shù)據(jù)庫管理員更好地了解增量檢查點(Checkpoint),并對檢查點(Checkpoint)優(yōu)化所用的下列四個初始化參數(shù)進行了描述:
           -  FAST_START_MTTR_TARGET 
           -  LOG_CHECKPOINT_INTERVAL 
           -  LOG_CHECKPOINT_TIMEOUT 
           -  LOG_CHECKPOINTS_TO_ALERT 
此外,本文檔還介紹了如何解釋和處理檢查點錯誤:ALERT.LOG 文件中報告的“Checkpoint not Complete(檢查點未完成)”和“Cannot Allocate New Log(無法分配新日志)”。

詳細信息

目錄:
 

1.  什么是檢查點?
2. 檢查點和性能
3. 與增量檢查點相關的參數(shù)
4. Redo(重做)日志和檢查點
5. 了解檢查點錯誤消息(“Cannot allocate new log”和“Checkpoint not complete”)
6. Oracle 版本信息
7. 使用 Statspack 確定檢查點問題
  
 

檢查點優(yōu)化和錯誤處理


1.  什么是檢查點?

檢查點是一種將內(nèi)存中的已修改數(shù)據(jù)塊與磁盤上的數(shù)據(jù)文件進行同步的數(shù)據(jù)庫事件。通過Checkpoint Oracle 確保了被 transaction 修改過數(shù)據(jù)可以被同步至磁盤。Oracle transaction 提交的時候不會將已修改數(shù)據(jù)塊同步寫入磁盤上。

檢查點有兩個用途:(1) 確保數(shù)據(jù)一致性,和 (2) 實現(xiàn)更快的數(shù)據(jù)庫恢復。如何更快地恢復?由于直至檢查點生成時所有的數(shù)據(jù)庫更改均已記錄在數(shù)據(jù)文件中,因此無需再應用先于檢查點的 redo 日志條目。檢查點必須確保高速緩存中所有已修改的緩沖數(shù)據(jù)均已切實寫入到相應的數(shù)據(jù)文件中,以避免在發(fā)生崩潰(實例或磁盤故障)時可能會出現(xiàn)的數(shù)據(jù)丟失。
 

Oracle 只有在特定條件下才會將臟緩存寫入磁盤:

  - shadow process 需要掃描的數(shù)據(jù)塊個數(shù)超過 db_block_buffers 參數(shù)的四分之一。
  - 每三秒鐘。
  - 生成一個檢查點時。

檢查點通過五種類型的事件來實現(xiàn):

  - 每次切換 redo 日志文件時。
  - 達到 LOG_CHECKPOINT_TIMEOUT 的延遲時。
  - 當前 redo 日志文件中已存在了大小為 (LOG_CHECKPOINT_INTERVAL* OS塊的大?。╞ytes))的數(shù)據(jù)。
  - 直接由 ALTER SYSTEM SWITCH LOGFILE 命令實現(xiàn)。
  - 直接使用 ALTER SYSTEM CHECKPOINT 命令實現(xiàn)。
 

在檢查點期間會發(fā)生以下操作:
 -  DBWR 將緩沖區(qū)緩存中所有已修改的數(shù)據(jù)庫塊寫回到數(shù)據(jù)文件中,
 -  檢查點進程 (ckpt) 更新所有數(shù)據(jù)文件的文件頭,以反映上一個檢查點發(fā)生的時間 (SCN)


2. 檢查點和性能

檢查點的優(yōu)化常常會使數(shù)據(jù)庫管理員左右為難。頻繁的檢查點會實現(xiàn)更快的數(shù)據(jù)庫恢復,但也會導致數(shù)據(jù)庫性能降低。那么,DBA 如何解決這一問題呢?

根據(jù)數(shù)據(jù)庫中的數(shù)據(jù)文件數(shù)量,檢查點將會是一種高度占用資源的操作,因為所有數(shù)據(jù)文件頭在檢查點期間都會被凍結(jié)。關于檢查點的頻率設置,需要對性能進行權(quán)衡。檢查點頻率越高,就能在數(shù)據(jù)庫崩潰后更快地實現(xiàn)恢復。這也是為什么一些不太能忍受意外系統(tǒng)停機的客戶現(xiàn)場常常會選擇此選項的原因。但是,在很多情況下,頻繁的檢查點可能會導致性能降低,這使得上述觀點并不能完全站穩(wěn)腳跟。 我們假設數(shù)據(jù)庫已啟動,且有 95% 的時間處于運行狀態(tài),剩下 5% 未運行時間是由于出現(xiàn)偶發(fā)的實例崩潰或硬件故障,需要進行數(shù)據(jù)庫恢復。對于大多數(shù)的客戶現(xiàn)場而言,優(yōu)化 95% 的性能相比于極少的 5% 停機時間要更具意義。

本文檔假設性能是您的首要考慮事項,并由此給出相應的建議。因此,您的目標是通過優(yōu)化盡量減少檢查點的頻率。

優(yōu)化檢查點涉及到下面四個關鍵初始化參數(shù):

           -  FAST_START_MTTR_TARGET 
           -  LOG_CHECKPOINT_INTERVAL 
           -  LOG_CHECKPOINT_TIMEOUT 
           -  LOG_CHECKPOINTS_TO_ALERT

下面將詳細討論這些參數(shù)。

同時,還針對alert日志中出現(xiàn)的“checkpoint not complete”消息給出了處理建議,這些消息說明redo 日志和檢查點需要優(yōu)化。


3. 與增量檢查點相關的參數(shù)
注意:日志文件切換將始終覆蓋由以下參數(shù)引起的檢查點。

  • FAST_START_MTTR_TARGET

自 Oracle 9i 以來,F(xiàn)AST_START_MTTR_TARGET 參數(shù)已成為優(yōu)化增量檢查點目標的首選方法。通過 FAST_START_MTTR_TARGET,您可以指定數(shù)據(jù)庫執(zhí)行單實例的崩潰恢復所要花費的秒數(shù)。基于內(nèi)部統(tǒng)計信息,增量檢查點會自動調(diào)整檢查點目標,以滿足 FAST_START_MTTR_TARGET 的要求。
V$INSTANCE_RECOVERY.ESTIMATED_MTTR 顯示當前預計的平均恢復時間 (MTTR)(以秒為單位)。即使未指定 FAST_START_MTTR_TARGET,也同樣會顯示此值。
V$INSTANCE_RECOVERY.TARGET_MTTR 顯示由系統(tǒng)強制執(zhí)行的有效 MTTR 目標(以秒為單位)。
V$MTTR_TARGET_ADVICE 顯示在當前的 MTTR 設置下由當前的工作負載產(chǎn)生的 I/O 數(shù)量,以及在其他 MTTR 設置下將由當前的工作負載產(chǎn)生的預計 I/O 數(shù)量。此視圖可幫助用戶在運行時性能和設置 FAST_START_MTTR_TARGET 以實現(xiàn)快速恢復之間進行權(quán)衡。

  • LOG_CHECKPOINT_INTERVAL

LOG_CHECKPOINT_INTERVAL 參數(shù)指定增量檢查點目標應滯后于當前日志尾的最大 redo 塊數(shù)量。
如果指定了 FAST_START_MTTR_TARGET,就不應設置 LOG_CHECKPOINT_INTERVAL 或?qū)⑵湓O置為 0。在大多數(shù) Unix 系統(tǒng)上,操作系統(tǒng)塊大小都是 512 字節(jié)。
也 就是說,將 LOG_CHECKPOINT_INTERVAL 的值設置為 10,000 就意味著增量檢查點目標相對于當前日志尾的滯后不得超過 5,120,000 (5M) 字節(jié)。以此計算,如果 redo 日志的大小為 20M,則會對每個日志產(chǎn)生 4 個檢查點。

LOG_CHECKPOINT_INTERVAL 會影響檢查點的發(fā)生時間,這意味著應特別注意此參數(shù)的設置,保持其隨 redo 日志文件的大小變化而更新。檢查點的頻率是影響數(shù)據(jù)庫從意外故障中恢復所需時間的因素之一。檢查點之間的間隔越長,則在發(fā)生系統(tǒng)崩潰時,數(shù)據(jù)庫恢復所需的 時間就越長。檢查點間隔越短意味著數(shù)據(jù)庫的恢復速度越快,但是代價是檢查點操作會消耗更多的資源。

此參數(shù)還會影響在恢復的前滾階段期間完成數(shù)據(jù)庫恢復操作所需的時間。實際的恢復時間取決于此時間,以及其他因素,例如故障類型(實例或系統(tǒng)崩潰、介質(zhì)故障等)以及需要應用的歸檔 redo 日志數(shù)量。

  • LOG_CHECKPOINT_TIMEOUT

LOG_CHECKPOINT_TIMEOUT 參數(shù)指定增量檢查點目標應滯后于當前日志尾的最長秒數(shù)。
換句話說,它指定緩沖區(qū)緩存中的臟緩存可以保持臟狀態(tài)的時間。
檢查點頻率影響數(shù)據(jù)庫從意外故障中恢復所需的時間。檢查點之間的間隔越長,數(shù)據(jù)庫恢復所需的時間就越多。

Oracle 建議使用 LOG_CHECKPOINT_INTERVAL 而不是 LOG_CHECKPOINT_TIMEOUT 來控制檢查點間隔,后者會每“n”秒啟動一次檢查點,而不管事務頻率。這可能會導致在事務量變化的情況下出現(xiàn)不必要的檢查點。只要可能,就必須避免不必要的檢查點,以實現(xiàn)最佳性能。

許多人會有這樣一種誤解:將 LOG_CHECKPOINT_TIMEOUT 設置為給定值之后,系統(tǒng)就會按該間隔啟動日志切換,從而啟用用于stand-by數(shù)據(jù)庫配置的恢復窗口。日志切換會引起檢查點,但檢查點并不會引起日志切換。引起日志切換的唯一方式是使用 ALTER SYSTEM SWITCH LOGFILE 進行手動操作或重新調(diào)節(jié) redo 日志大小,以引起更為頻繁的切換。這由操作系統(tǒng)塊而非時間間隔控制。
在線 redo 日志的大小對性能和恢復至關重要。
有關 redo 日志和檢查點的信息,請參考以下其他部分。

  • LOG_CHECKPOINTS_TO_ALERT

通過 LOG_CHECKPOINTS_TO_ALERT,您可以將檢查點記錄到alert日志中。

這樣做有助于確定檢查點是否按所需頻率發(fā)生。
在 Oracle9i 之前,此參數(shù)為靜態(tài)參數(shù)。
Oracle 通常建議將此參數(shù)設置為 TRUE,因為開銷很小,可以忽略不計,但alert日志中的信息可能會非常有用。

有關上述實例參數(shù)會如何影響檢查點的更多詳細信息,請參閱 Note:76713.1


4. Redo 日志和檢查點

每次切換日志時都會發(fā)生一次檢查點。如果上一個檢查點已在進行中,由日志切換引起的檢查點將覆蓋當前檢查點。

此時就需要大小合適的 redo 日志,以避免因頻繁的日志切換而引起不必要的檢查點。另外,增量檢查點目標和日志尾之間的間隔也會受“最小在線日志文件大小的 90%”設置所限制。這樣可確保在大多數(shù)情況下,日志切換不必等待檢查點。因此,日志文件大小應配置得足夠大。一個好的辦法是,最多每二十分鐘切換一次日志。日志文件過小會增加檢查點活動并降低性能。Oracle 建議用戶將所有在線日志文件設置為同一大小,且每個線程至少擁有兩個日志組。若要監(jiān)視日志切換發(fā)生的速度,以及隨后的檢查點發(fā)生的速度,alert日志是一個很有價值的工具。
  
以下是通過alert日志發(fā)現(xiàn)日志切換過于頻繁的示例:
 

Fri May 16 17:15:43 1997 
Thread 1 advanced to log sequence 1272 
  Current log# 3 seq# 1272 mem# 0: /prod1/oradata/logs/redologs03.log 
Thread 1 advanced to log sequence 1273 
  Current log# 1 seq# 1273 mem# 0: /prod1/oradata/logs/redologs01.log 
Fri May 16 17:17:25 1997 
Thread 1 advanced to log sequence 1274 
  Current log# 2 seq# 1274 mem# 0: /prod1/oradata/logs/redologs02.log 
Thread 1 advanced to log sequence 1275 
  Current log# 3 seq# 1275 mem# 0: /prod1/oradata/logs/redologs03.log 
Fri May 16 17:20:51 1997 
Thread 1 advanced to log sequence 1276 
  Current log# 1 seq# 1276 mem# 0: /prod1/oradata/logs/redologs01.log 
 

如果 redo 日志每 3 分鐘切換一次,您就會察覺到性能降低。這表明 redo 日志不夠大,不能有效地處理該事務負載。

有關如何估計 redo 日志文件的適當大小的詳細信息,請參閱 Note:1038851.6 。有關如何重新調(diào)節(jié)在線 redo 日志文件大小的示例,請參閱 Note:1035935.6 。


5. 了解檢查點錯誤消息(“Cannot allocate new log”和“Checkpoint not complete”)

有時,您可以在 alert.log 文件中看到以下相應消息:

  Thread 1 advanced to log sequence 248 
    Current log# 2 seq# 248 mem# 0: /prod1/oradata/logs/redologs02.log 
  Thread 1 cannot allocate new log, sequence 249 
  Checkpoint not complete 
 

此信息表明 Oracle 希望重新使用某個 redo 日志文件,但當前的檢查點位置仍位于該日志中。在這種情況下,Oracle 必須等到檢查點位置通過該日志。由于增量檢查點目標相對于當前日志尾的滯后絕不會超過最小日志文件大小的 90% 以上,因此,如果 DBWR 寫入速度過慢,或者在日志全滿之前發(fā)生日志切換,或者日志文件過小,就會遇到這種情況。在數(shù)據(jù)庫等待檢查點時,redo 生成過程會停止,直到完成日志切換。

6. Oracle 版本信息

在 Oracle8i 中,初始化參數(shù) FAST_START_IO_TARGET 會使增量檢查點自動調(diào)整其目標,從而使恢復所需的數(shù)據(jù)塊數(shù)量不多于 FAST_START_IO_TARGET 設置的值。自 Oracle 9i 開始,已棄用此參數(shù),取而代之的是參數(shù) FAST_START_MTTR_TARGET。

7. 使用 Statspack 確定檢查點問題

您可以每 15 分鐘左右收集一次 Statspack 快照,這些快照報告將收集有關在該時間段已開始的檢查點數(shù)量、已完成的檢查點數(shù)量及檢查點發(fā)生時寫入的數(shù)據(jù)庫緩沖數(shù)量的有用信息。此外,還包含關于 redo 活動的統(tǒng)計信息。通過收集和比較這些快照報告,您可以完整地了解不同時期的檢查點性能。

Statspack 報告中另一個值得關注的內(nèi)容是等待事件,下面的等待事件明確指出了 redo 日志吞吐量和檢查點的問題:

log file switch (checkpoint incomplete) 
log file switch (archiving needed) 
log file switch/archive 
log file switch (clearing log file) 
log file switch completion 
log switch/archive 
log file sync

 

如果上述等待事件中的一個或多個頻繁地出現(xiàn),且相關數(shù)值較大,那您就需要采取行動了,例如添加更多的在線 redo 日志文件,或增加其大小和/或修改檢查點參數(shù)。

參考

NOTE:76713.1 - 8i Parameters that Influence Checkpoints
NOTE:1038851.6 - How to Estimate Size of Redo Logs



11G中FAST_START_MTTR_TARGET參數(shù)

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> col name for a20
SQL> col value for a30
SQL> select name,value from v$spparameter where name like 'fast_start_mt%';

NAME                 VALUE
-------------------- ------------------------------
fast_start_mttr_targ
et

alert.log中信息 
Successful open of redo thread 2
MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set
Sat Jul 13 13:27:28 2013
SMON: enabling cache recovery
ARC3: Archival started
ARC0: STARTING ARCH PROCESSES COMPLETE

概念說明

一、關于FAST_START_MTTR_TARGET參數(shù)

        是一個加快實例恢復的參數(shù),我們可以根據(jù)服務級別來定義一個合理的、可接受的值,該值的單位為秒。比如設定為60s,即1分鐘。

    假定該值處于合理的情況之下,則一旦實例崩潰,在60s以內(nèi)實例應當能夠被恢復。合理即是該值不能太大,也不能太小。太大則實例恢

    復所需的時間較長,太小則導致大量數(shù)據(jù)的及時寫入,增加了系統(tǒng)的I/O。

        影響實例恢復時間長短的主要因素即是從最近檢查點位置到聯(lián)機重做日志尾部之間的距離。距離越長則所需要的cache recovery 和undo、

    redo的時間越長。所以如何有效的縮短最近檢查點位置與聯(lián)機重做日志尾部之間的距離,這正是FAST_START_MTTR_TARGET的目的。

        關于檢查點的觸發(fā)條件有很多,比如日志切換、數(shù)據(jù)庫shutdown、開始結(jié)束備份表空間等。檢查點的分類也很多,比如完全檢查點、部

    分檢查點、增量檢查點等。

        FAST_START_MTTR_TARGET的值實際上也是觸發(fā)檢查點的一個觸發(fā)條件。當內(nèi)存中產(chǎn)生的dirty buffer所需的恢復時間(estimated_mttr)

    如果到達FAST_START_MTTR_TARGET的指定時間,則檢查點進程被觸發(fā)。檢查點進程一旦被觸發(fā),將通知DBWn進程將按檢查點隊列順序?qū)⑴K數(shù)

    據(jù)寫入到數(shù)據(jù)文件,從而縮短了最后檢查點位置與聯(lián)機重做日志間的距離,減少了實例恢復所需的時間。

二、兩個重要的視圖

        v$instacne_recovery

        v$mttr_target_advice

三、設定FAST_START_MTTR_TARGET

        根據(jù)實際需要來設定FAST_START_MTTR_TARGET的值,這個值的設定需要考慮到可接受的實例的恢復時間、可承受的I/O吞吐量等等。

        假定我們將該值設定為

            SQL> alter system set fast_start_mttr_target = 30 ;

        在事務頻繁的時間段來考察視圖v$instacne_recovery提供的值

一、關于FAST_START_MTTR_TARGET參數(shù)

        是一個加快實例恢復的參數(shù),我們可以根據(jù)服務級別來定義一個合理的、可接受的值,該值的單位為秒。比如設定為60s,即1分鐘。

    假定該值處于合理的情況之下,則一旦實例崩潰,在60s以內(nèi)實例應當能夠被恢復。合理即是該值不能太大,也不能太小。太大則實例恢

    復所需的時間較長,太小則導致大量數(shù)據(jù)的及時寫入,增加了系統(tǒng)的I/O。

        影響實例恢復時間長短的主要因素即是從最近檢查點位置到聯(lián)機重做日志尾部之間的距離。距離越長則所需要的cache recovery 和undo、

    redo的時間越長。所以如何有效的縮短最近檢查點位置與聯(lián)機重做日志尾部之間的距離,這正是FAST_START_MTTR_TARGET的目的。

        關于檢查點的觸發(fā)條件有很多,比如日志切換、數(shù)據(jù)庫shutdown、開始結(jié)束備份表空間等。檢查點的分類也很多,比如完全檢查點、部

    分檢查點、增量檢查點等。

        FAST_START_MTTR_TARGET的值實際上也是觸發(fā)檢查點的一個觸發(fā)條件。當內(nèi)存中產(chǎn)生的dirty buffer所需的恢復時間(estimated_mttr)

    如果到達FAST_START_MTTR_TARGET的指定時間,則檢查點進程被觸發(fā)。檢查點進程一旦被觸發(fā),將通知DBWn進程將按檢查點隊列順序?qū)⑴K數(shù)

    據(jù)寫入到數(shù)據(jù)文件,從而縮短了最后檢查點位置與聯(lián)機重做日志間的距離,減少了實例恢復所需的時間。

        關于實例的恢復以及檢查的具體分類描述等,請參考:

             Oracle 實例恢復

             Oracle實例和Oracle數(shù)據(jù)庫(Oracle體系結(jié)構(gòu))            

二、FAST_START_MTTR_TARGET = 0的質(zhì)疑

        很多文章描述了FAST_START_MTTR_TARGET = 0,即為未設置,表示啟用自動檢查點功能,下面是來自Oracle的官方文檔中的一段,

    原文的鏈接為: Fast-Start Fault Recovery

        Fast-start checkpointing refers to the periodic writes by the database writer (DBWn) processes for the purpose of writing changed data blocks from the Oracle buffer cache to disk and advancing the thread-checkpoint. Setting the database parameter FAST_START_MTTR_TARGET to a value greater than zero enables the fast-start checkpointing feature. Fast-start checkpointing should always be enabled for the following reasons:

        It reduces the time required for cache recovery, and makes instance recovery time-bounded and predictable. This is accomplished by limiting the number of dirty buffers (data blocks which have changes in memory that still need to be written to disk) and the number of redo records (changes in the database) generated between the most recent redo record and the last checkpoint.

        Fast-Start checkpointing eliminates bulk writes and corresponding I/O spikes that occur traditionally with interval- based checkpoints, providing a smoother, more consistent I/O pattern that is more predictable and easier to manage. If the system is not  already near or at its maximum I/O capacity, fast-start checkpointing will have a negligible impact on performance. Although fast-start checkpointing results in increased write activity, there is little reduction in database throughout, provided the system has sufficient I/O capacity.

        從第一段中粗體標記的描述來看,當設定一個大于0的值給FAST_START_MTTR_TARGET,則自動調(diào)整檢查點功能別啟用。即fast-start

    checkpointing,更準確的說應該是快速啟動檢查點功能

        再看下面的這段描述,這段來自Oracle 10g OCP workshop I 14-17 英文版教程(Edition 3.1 December 2008)

        Explicit setting of the FAST_START_MTTR_TARGET parameter to 0 disables automatic checkpoint tuning.Explicit setting of the FAST_START_MTTR_TARGET parameter to a value other than 0 also enables the Redo Log Advisor.

        從上面的描述可以看出,如果將FAST_START_MTTR_TARGET設置為將關閉檢查點自動調(diào)整功能。

三、設定FAST_START_MTTR_TARGET

        根據(jù)實際需要來設定FAST_START_MTTR_TARGET的值,這個值的設定需要考慮到可接受的實例的恢復時間、可承受的I/O吞吐量等等。

        假定我們將該值設定為

            SQL> alter system set fast_start_mttr_target = 30 ;

        在事務頻繁的時間段來考察視圖v$instacne_recovery提供的值

        SQL> desc v$instance_recovery;   --查看v$instance_recovery視圖的結(jié)構(gòu)

         Name                                      Null?    Type

         ----------------------------------------- -------- ----------------------------

         RECOVERY_ESTIMATED_IOS                             NUMBER

         ACTUAL_REDO_BLKS                                   NUMBER

         TARGET_REDO_BLKS                                   NUMBER

         LOG_FILE_SIZE_REDO_BLKS                            NUMBER

         LOG_CHKPT_TIMEOUT_REDO_BLKS                        NUMBER

         LOG_CHKPT_INTERVAL_REDO_BLKS                       NUMBER

         FAST_START_IO_TARGET_REDO_BLKS                     NUMBER

         TARGET_MTTR                                        NUMBER

         ESTIMATED_MTTR                                     NUMBER

         CKPT_BLOCK_WRITES                                  NUMBER

         OPTIMAL_LOGFILE_SIZE                               NUMBER

         ESTD_CLUSTER_AVAILABLE_TIME                        NUMBER

         WRITES_MTTR                                        NUMBER

         WRITES_LOGFILE_SIZE                                NUMBER

         WRITES_LOG_CHECKPOINT_SETTINGS                     NUMBER

         WRITES_OTHER_SETTINGS                              NUMBER

         WRITES_AUTOTUNE                                    NUMBER

         WRITES_FULL_THREAD_CKPT                            NUMBER

        兩個字段:

            TARGET_MTTR         -->參照fast_start_mttr_target參數(shù)中設定的值計算出來的一個值

            ESTIMATED_MTTR      -->系統(tǒng)根據(jù)dirty buffer 中計算出來的值

        可能出現(xiàn)的情況

            1.TARGET_MTTR > ESTIMATED_MTTR  --大量的事務將導致這種情況的出現(xiàn)

            2.TARGET_MTTR < ESTIMATED_MTTR  --數(shù)據(jù)庫剛剛啟動時,幾乎沒有事務時會出現(xiàn)這種情況

SQL> select recovery_estimated_ios,actual_redo_blks ,target_redo_blks ,

  2  target_mttr,estimated_mttr

  3  from v$instance_recovery;

RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR

---------------------- ---------------- ---------------- ----------- --------------

                    55              147              707         33             27

        可以在負載的情況下根據(jù)TARGET_MTTR來值通過v$mttr_target_advice調(diào)整該參數(shù)

四、啟用MTTR Advisory

        需要設置兩個參數(shù)

            STATISTICS_LEVEL         -->置為typical 或者all

            FAST_START_MTTR_TARGET   -->置為非零值

        SQL> show parameter mttr;    --目標mttr_time設定為30 s

        NAME                                 TYPE        VALUE

        ------------------------------------ ----------- ------------------------------

        fast_start_mttr_target               integer     30

        SQL> select  target_mttr,estimated_mttr from v$instance_recovery;   --系統(tǒng)計算出來的mttr為33

        TARGET_MTTR ESTIMATED_MTTR

        ----------- --------------

                 33             27     

        SQL> select mttr_target_for_estimate tar_est,dirty_limit,estd_cache_writes est_c_w,

          2  estd_cache_write_factor est_c_w_f,estd_total_writes est_t_w,estd_total_write_factor est_t_w_f

          3  from v$mttr_target_advice;

           TAR_EST DIRTY_LIMIT    EST_C_W  EST_C_W_F    EST_T_W  EST_T_W_F

        ---------- ----------- ---------- ---------- ---------- ----------

                60        5028       3762      .7376       3762      .7376

                34        1000       5100          1       5100          1

                68        6248       3762      .7376       3762      .7376

                52        3808       3762      .7376       3762      .7376

                45        2735       3845      .7539       3845      .7539

        --mttr_target_for_estimate有一個值為的最接近設定的目標時間30,以及由系統(tǒng)計算出的的target_mttr時間33

        --同時也給出了幾組不同的mttr_target值及dirty_limit,cache_write,io 等來供DBA來選擇設定合適的mttr

五、兩個重要的視圖

        v$instacne_recovery

        v$mttr_target_advice



由于Oracle中LGWR和DBWR工作的不一致,Oracle引入了檢查點的概念,用于同步數(shù)據(jù)庫,保證數(shù)據(jù)庫的一致性。在Oracle里面,檢查點分為兩種:完全檢查點和增量檢查點。下面我們分別介紹這兩種檢查點的作用:

1、完全檢查點

在Oracle8i之前,數(shù)據(jù)庫的發(fā)生的檢查點都是完全檢查點。完全檢查點會將數(shù)據(jù)緩沖區(qū)里面所有的臟數(shù)據(jù)塊寫入相應的數(shù)據(jù)文件中,同時將最新的checkpoint scn更新到所有的數(shù)據(jù)文件頭部及控制文件。保證數(shù)據(jù)庫的處于一致的狀態(tài)。需要注意的是,完 全檢查點產(chǎn)生的時候,CKPT并不是把當前完全檢查點發(fā)生那一時刻的SCN更新到控制文件和數(shù)據(jù)文件頭,而是將這個觸發(fā)檢查點時刻DBWn當前剛寫完 dirty buffer對應的SCN更新到控制文件和數(shù)據(jù)文件頭,也就是說,更新控制文件和數(shù)據(jù)文件頭的SCN是滯后于完全檢查點的發(fā)生那一時刻的SCN的,這個從恢復的原理也很容易理解,因為檢查點發(fā)生的時候要寫入dirty buffer還沒有寫入,自然不能立即更新成當前的SCN了。需 要注意的是, 在oracle8之前,由于沒有chekpoint  queue,也沒有增量檢查點的概念,發(fā)生完全檢查點時,DBWn會以一種無序的方式將所有的 dirty buffer寫出到數(shù)據(jù)文件,這個時候Oracle會凍結(jié)所有DML操作等候所有dirty  buffer被寫出,巨大的IO往往會影響到數(shù)據(jù)庫的性 能。后來隨著Oracle數(shù)據(jù)庫的發(fā)展和buffer  cache的不斷增大,oracle 意識到這個單一的Full checkpoint機制已經(jīng)不能滿足需要,所以在Oracle 8i后提出增量檢查點的概念,建立了checkpoint queue ,讓dirty  buffer  header根據(jù)首次變化時候的順序(LRBA)排列在queue里面。 這樣DBWn只要順著queue的順序?qū)懀渌M程不必等候dbwr的寫完成就可以繼續(xù)。  因此增量檢查點的概念就由此產(chǎn)生了。

完全檢查點在8i之后只有在下列兩種情況下才會發(fā)生:

DBA手工執(zhí)行alter system checkpoint的命令;

數(shù)據(jù)庫正常shutdown (immediate,transcational,normal)。
2、增量檢查點

說白了,就是

CKPT每3秒一次的檢查DBWn寫進度并在控制文件中記錄檢查點位置(checkpoint position)和更新heartbeat信息

以及

CKPT定期觸發(fā)DBWn去寫checkpoint queue中的臟數(shù)據(jù)

這兩項操作合一起被稱為增量檢查點。 -->可能這塊描述的過于籠統(tǒng),大家繼續(xù)往下看:-)

我們都知道被修改過的數(shù)據(jù)塊,在oracle中都被統(tǒng)稱為臟數(shù)據(jù)塊(dirty buffer)。所有的臟塊被一個鏈表串起來,稱做檢查點隊列(checkpoint queue)。在buffer cache中,每一個塊都有一個buffer header簡稱BH, 在BH中有一個ckptq項, 此項目中記錄了指向檢查點隊列上一個塊和下一個塊的指針。 如果某一個塊不在檢查點隊列中,他的ckptq項為空.通過ckptq項oracle將所有的臟塊串成了一個雙向鏈表。這個雙向鏈表就是檢查點隊列了。

Oracle 從8i開始引入了檢查點隊列(checkpoint queue)的概念,用于記錄數(shù)據(jù)庫里面當前所有的dirty buffer的信息,這些dirty buffer的信息按被修改的時間先后存放在checkpoint queue里面(當塊首次被更改時,塊會立即被加進檢查點隊列),所涉及的條目主要包含RBA (Redo Block Address,重做日志里面用于標識事務期間數(shù)據(jù)塊在重做日志里面發(fā)生更改的編號)和數(shù)據(jù)塊的數(shù)據(jù)文件號和塊號。

不 論數(shù)據(jù)塊(buffer)更改幾次,它在checkpoint queue里面的位置始終保持不變,checkpoint queue也只會記錄它最早的RBA(這個最早的RBA其實就是Low RBA,也就是數(shù)據(jù)塊第一次被修改時所對應的RBA),從而保證最早更改的數(shù)據(jù)塊能夠盡快從內(nèi)存寫入數(shù)據(jù)文件。DBWR每到一定的時機,就會被觸發(fā) (DBWn并不是只有當檢查點發(fā)生的時候才寫,它大約有10幾種條件觸發(fā)寫操作),沿著檢查點隊列的順序刷新臟塊,同時CKPT進程,會監(jiān)控著檢查點隊列 的長度,當檢查點隊列的長度達到一定限制時(具體有幾個參數(shù)來確定checkpoing queue的長度,下面會提到比如log_checkpoint_timeout,fast_start_mttr_target等),CKPT會通知 DBWR寫臟塊。CKPT會根據(jù)幾個參數(shù)的設置和I/O的速度以及繁忙程度,計算出來一個Target rba(目標rba),DBWn會沿著檢查點隊列,按照dirty buffer的Low RBA順序?qū)⑺蠺arget rba之前對應的臟塊從內(nèi)存寫入數(shù)據(jù)磁盤文件。當CKPT通知完DBWn Target rba后,CKPT的任務就結(jié)束了。他并不會等待DBWn寫完所有的Target rba之前的臟塊。因此這里CKPT只是起到了一個通知DBWn進程寫入的作用。

完全檢查點發(fā) 生的時候,Oracle一方面通知DBWn進行下一批寫操作,另一方面是將這個觸發(fā)檢查點時刻DBWn當前剛寫完dirty buffer對應的SCN寫入數(shù)據(jù)文件頭和控制文件,這個SCN就是checkpoint scn。但Oracle考慮到檢查點SCN的間隔還是太大了,因為檢查點的觸發(fā)條件有限,周期可能比較長,有些情況下比如檢查點需要5分鐘左右才觸發(fā),那 這個時候系統(tǒng)crash再重新啟動就意味著很可能系統(tǒng)需要5分鐘左右才能啟動。于是Oracle采用了一個heartbeat的概念,以3秒的頻率將 DBWn寫的進度反應到控制文件中,這樣系統(tǒng)crash重新啟動的時候?qū)母囊粋€時間點開始恢復。Oracle這么做的目的就是要縮短崩潰恢復時間! 因此CKPT另外一個任務就是每3秒,檢測一次DBWn的寫進度。DBWn 是沿著檢查點隊列寫臟塊,由于這里有一個順序的關系,所以DBWn的寫的進度就是可衡量的,寫到哪個buffer的時候該buffer的首次變化時候的 scn(對應了LRba)就是當前所有數(shù)據(jù)文件block的上面最新scn,但是由于無法適時的將DBWn的進度記錄下來,所以Oracle選擇了一些策 略。 其中就包括CKPT進程的檢查點位置更新和心跳,所以說CKPT每3秒鐘查看一下DBWn沿檢查點隊列寫到了哪里,并且將這個位置設置為檢查點位置 (checkpont position)。也就是說檢查點位置之前的塊,都是已被DBWn刷新到磁盤上的塊。因此我們可以理解為,CKPT進程每3秒會根據(jù)DBWn寫的進度設置并記錄一個檢查點位置,也就是說這個檢查點位置就是由DBWn的在往Target RBA寫過程中的進度決定的(如果沒有dirty buffer產(chǎn)生,那么就不會更新檢查點位置信息)。因 此CKPT每3秒會將檢查點位置對應的數(shù)據(jù)塊的rba (low cache rba-表示Instance Recovery時開始恢復的日志條目)更新和記錄到控制文件的CHECKPOINT PROGRESS RECORDS區(qū)域,當然同時被記錄進控制文件的還有heartbeat等其他信息。DBWn將檢查點隊列里面的dirty buffer寫入到數(shù)據(jù)文件后,檢查點的位置也要相應地往后移。


檢 查點位置(checkpoint position)實際上就可以直接理解為是一個rba,他指向著重做日志文件中的某條重做記錄。在此檢查點位置前的重做記錄,其對應的buffer cache中的dirty buffer已經(jīng)被寫進了數(shù)據(jù)文件,在此位置后的重做記錄,所對應數(shù)據(jù)臟塊有可能還在內(nèi)存中。如果發(fā)生了實例崩潰,只需要在日志文件中找到檢查點位置 (low cache rba),從此處開始應用所有的重做日志文件,就完成了前滾操作。實例崩潰后,再次啟動數(shù)據(jù)庫,oracle會到控制文件中讀取low cache rba,這就是檢查點位置。從此處開始應用重做日志,應用到on disk rba的位置。on disk rba是磁盤中重做日志文件的最后一條重做記錄的rba。如 果某條重做記錄的rba高于on disk rba,那說明此重做記錄還沒有被寫進日志文件中,崩潰發(fā)生時,他是不可能被恢復的。on disk rba是oracle前滾操作的終點。比這個更高的rba,都應該還駐留在log buffer中。還沒有被LGWR寫入日志文件。所以是不能被用于恢復的。

在DBWn寫dirty buffer這個檢查點過程中,Oracle也可以繼續(xù)產(chǎn)生dirty buffer,DBWn也不是一次要把所有dirty buffer全部寫到磁盤(不同于完全檢查點的地方),這樣就提高了檢查點的效率,使得數(shù)據(jù)庫要做恢復的時候從這個最新位置開始做恢復,而不是從數(shù)據(jù)文件 中的checkpoint scn(上一個完全檢查點位置) 開始做恢復,這樣將縮短恢復時間。

Oracle 11g的 Concept里面提到:An incremental checkpoint is a type of thread checkpoint partly intended to avoid writing large numbers of blocks at online redo log switches. DBWn checks at least every three seconds to determine whether it has work to do. When DBWn writes dirty buffers, it advances the checkpoint position, causing CKPT to write the checkpoint position to the control file, but not to the data file headers.
因此我們需要注意的是:增量檢查點并不會去更新數(shù)據(jù)文件頭,以及控制文件中數(shù)據(jù)庫SCN以及數(shù)據(jù)文件條目的SCN信息,而只是每3秒由CKPT進程去更新控制文件中的low cache rba信息,也就是檢查點的位置。

檢查點位置發(fā)生變更后, Oracle主要通過4個參數(shù)和1個機制來控制檢查點位置和最后的重做日志條目之間的距離(檢查點隊列的長度)。

fast_start_io_target (Oracle 9i以后已經(jīng)廢棄)

該 參數(shù)用于表示數(shù)據(jù)庫發(fā)生Instance Recovery的時候需要產(chǎn)生的IO總數(shù),它通過v$filestat的AVGIOTIM來估算的。比如我們一個數(shù)據(jù)庫在發(fā)生Instance Crash后需要在10分鐘內(nèi)恢復完畢,假定OS的IO每秒為500個,那么這個數(shù)據(jù)庫發(fā)生Instance Recovery的時候大概將產(chǎn)生500*10*60=30,000次IO,也就是我們將可以把fast_start_io_target設置為 30000。

fast_start_mttr_target

我 們從上面可以看到fast_start_io_target來估算檢查點位置比較麻煩。Oracle為了簡化這個概念,從9i開始引入了 fast_start_mttr_target這么一個參數(shù),用于表示數(shù)據(jù)庫發(fā)生Instance Recovery的時間,以秒為單位。這個參數(shù)我們從字面上也比較好理解,其中的mttr是mean time to recovery的簡寫,如上例中的情況我們可以將fast_start_mttr_target設置為600。注意當設置了 fast_start_mttr_target后, fast_start_io_target這個參數(shù)將不再生效,從9i后 fast_start_io_target這個參數(shù)被Oracle廢除了。

log_checkpoint_timeout

該參數(shù)用于表示檢查點位置和重做日志文件末尾之間的時間間隔,以秒為單位,默認情況下是1800秒。相 比fast_start_mttr_target,它也是時間,但它的時間值表示完成恢復操作所需要的時間,即從最后的檢查點位置開始,應用所有日志直到 日志末尾所需要的時間。而本參數(shù)log_checkpoint_timeout表示從最后的檢查點位置開始,到日志末尾經(jīng)過的時間。

log_checkpoint_interval

該參數(shù)是表示檢查點位置和重做日志末尾的重做日志塊的數(shù)量,以OS塊表示。

90% OF SMALLEST REDO LOG


除了以上4個初始化參數(shù)外,Oracle內(nèi)部事實上還將重做日志文件末尾前面90%的位置設為檢查點位置。在每個重做日志中,這么幾個參數(shù)指定的位置可能不盡相同,Oracle將離日志文件末尾最近的那個位置確認為檢查點位置。

在Oracle 9i后,對檢查點頻率,建議只設置fast_start_mttr_target。根據(jù)需要,也可以通過設置 log_checkpoint_timeout,設置一個臟塊保持臟狀態(tài)的最大時間,而其他兩個參數(shù) fast_start_io_target,log_checkpoint_interval建議不再使用。



什么是增量檢查點?
最近對增量檢查點和全局檢查點有些疑惑,查看了很多的資料感覺都寫得非常復雜不容易理解。下面貼出一些自己的心得,如果有錯誤的地方希望得到指正。
                                    
1,什么是檢查點
   檢查點是數(shù)據(jù)庫事件,它是指當前數(shù)據(jù)庫dbwr進程將臟塊從db buffer寫到數(shù)據(jù)文件的進度,減少實例崩潰后,實例恢復的時間,是實例恢復的起點。
2,檢查點的分類
  全局檢查點:通常是dba手動生成 alter system checkpoint   或者正常關閉數(shù)據(jù)庫的時候會自動產(chǎn)生。

  增量檢查點:這個比較復雜可以從dbwr寫的條件說起
dbwr寫的條件
   1,檢查點發(fā)生的時候
   2,臟塊達到三分之一
   3,沒有空閑的塊
   4,timeout occurs
   5,rac ping request is made
   6,表空間的脫機,只讀,熱備份
   7,表的drop和truncate

一,  從上面可以看出,dbwr寫的時候并不只是檢查點發(fā)生的時候,也就是說即使檢查點沒有發(fā)生dbwr也可能在寫臟塊。 那么數(shù)據(jù)庫如果只是記錄了全局檢查點,實例崩潰后,很多dbwr已經(jīng)寫到數(shù)據(jù)文件中的臟塊也會被應用日志。增加了實例恢復的時間。                   

二,通過增量檢查點 :oracle在db buffer中有個檢查點隊列也叫臟隊列,ckpt進程會每三秒去讀去dbwr寫的進展,并把這個點記錄到控制文件中,但是不會記錄到數(shù)據(jù)文件頭,也就是說它記錄的是dbwr實時的寫入情況。這樣當實例崩潰后,需要進行實例恢復,數(shù)據(jù)庫就可以從控制文件中讀取這個增量檢查點作為實例恢復的起點,減少實例恢復的時間。
 
兩個概念 :
1,CKPT每3秒一次將檢查點位置記錄進控制文件,當然同時被記錄進控制文件的 還有'心跳'等其他信息.CKPT每3秒一次的工作和CKPT定期觸發(fā)DBWR,這兩項操作合一起被稱為--增量檢查
2,增量檢查點并不會去更新數(shù)據(jù)文件頭,以及控制文件中數(shù)據(jù)庫SCN以及數(shù)據(jù)文件條目的SCN信息,而只是每3秒由CKPT進程去更新控制文件中的low cache rba信息,也就是檢查點的位置。

   被修改過的塊,在oracle中都被統(tǒng)稱為臟塊.所有的臟塊被一個鏈表串起來,稱做檢查點隊列.在buffer  

cache中,每一個塊都有一個buffer header 簡稱BH,在BH中有一個ckptq項,此項目中記錄了指向檢查點隊

列上一個塊和下一個塊的指針.如果某一個塊不在檢查點隊列中,他的ckptq項為空.通過ckptq項oracle將

所有的臟塊串成了一個雙向鏈表.這個雙向鏈表就是檢查點隊列了.

1,只有臟塊才會在檢查點隊列中,非臟塊的ckptq為空.

2,當塊首次被更改時,塊會立即被加進檢查點隊列.如果檢查點隊列中的臟塊再次被修改,并不會改變其在

檢查點隊列中的位置.

3,檢查點隊列中臟塊的排列順序:根據(jù)第2點,所有臟塊按照首次被更改的時間的順序排列.更準確點說:按

照塊的lrba排列.

**什么是rba?lrba?hrba?

  rba就是重做塊地址,比如說,用戶發(fā)出了一條update命令,更新了塊A,塊A現(xiàn)在變成了臟塊,oracle會為他

生成一條重做記錄.這條重做記錄在重做日志文件中的位置就是rba(redo block address).過了一會兒,假

如:塊A依然還是臟塊,此時.用戶又發(fā)出一條更新塊A的命令,這又會生成一條重做記錄.第一條更新命令對

應的重做記錄的rba被稱為塊A的lrba(low rba),第二條更新命令對應的rba,被稱為hrba(high rba).

其實,按照lrba來排列,就是按照塊首次被修改的順序來排列.

  下面說說DBWR寫臟塊的方式,有了檢查點隊列之后,臟塊按照首次變臟的時間順序排列,DBWR每到一定的

時機,就會被觸發(fā),沿著檢查點隊列的順序刷新臟塊,具體在oracle中有幾個參數(shù)用來確定檢查點隊列的長

度.另有一個CKPT進程,會監(jiān)控著檢查點隊列的長度,當檢查點隊列的長度達到一定限制時,CKPT會通知DBWR

寫臟塊.CKPT會根據(jù)參數(shù)的設置和I/O的速度以及繁忙程度,計算出來一個Target rba(目標rba),DBWR會沿

著檢查點隊列,將所有Target rba之前的臟塊刷新到磁盤.當CKPT通知完DBWR Target rba后,CKPT的任務就

結(jié)束了.他并不會等待DBWR寫完所有的Target rba之前的臟塊.通知DBWR寫臟塊,這是CKPT的任務之一,CKPT

另有一個任務,就是每3秒,檢測一次DBWR的寫進度.檢查點隊列最前面的塊被稱為檢查點位置.DBWR是沿著

檢查點隊列寫臟塊的,CKPT每3秒鐘查看一下DBWR沿檢查點隊列寫到了哪里,并且將這個位置設置為檢查點

位置.也就是說檢查點位置之前的塊,都是已被DBWR刷新到磁盤上的塊.這個3秒一次檢查DBWR進度的工作,

也是CKPT的一個重要的任務.CKPT每3秒一次將檢查點位置記錄進控制文件,當然同時被記錄進控制文件的

還有'心跳'等其他信息.CKPT每3秒一次的工作和CKPT定期觸發(fā)DBWR,這兩項操作合一起被稱為--增量檢查

點.

畫思維導圖太費事,直接手打。
   

磁盤塊在buffer中對應的buffers被修改后稱為臟塊,修改為臟塊時不同步寫入數(shù)據(jù)文件,而同步寫到log buffer。

當buffer里有太多臟塊時或其他原因,會有多種方式觸發(fā)DBWR把臟塊寫到數(shù)據(jù)文件,騰出buffer空間,每種方式可能按不同的優(yōu)先順序?qū)懪K塊,也就是按不同的鏈來寫,其中一種是按lrba的順序?qū)憽?/p>

先靜態(tài)的解釋一些名詞,再討論增量檢查點的過程。

RBA(redo buffer address)臟塊指向的redo buffer內(nèi)存物理地址,lrba是指buffers第一次被修改時的rba,也就是這個buffers成為臟塊時的rba,以后再臟多少次,他成為臟塊的時候間不變,即lrba不會變。臟塊最近一次被臟的rba稱為hrba,兩個rba之間的rba沒有特定名稱,他們這個臟塊被事務修改的全部重做日志記錄。所有臟塊都有l(wèi)rba和hrba,如果只臟過一次,兩個rba相同。

CKPTQ。將所有臟塊的lrba鏈起來就是CKPTQ檢查點隊列。(不知道buffer真的有這個隊列的獨立物理結(jié)構(gòu),還是所有臟塊lrba信息在邏輯上向下指,在概念上形成CKPTQ。)

CKPT有多種詞性,指一個動作,如進行CKPT,這次檢查點;指一個進程,如CKPT進程;指邏輯上的一個時間點,檢查點位置。

LRBA。每個臟塊里有個LRBA信息,控制文件中也有個LRBA,準確的講叫 low cache rba,他是ckpt進程從某一個臟塊里讀取過來的。

On disk RBA。先記著他指向log file里最新的(最后的)一條重做日志條目,他也是ckpt進程從某一個臟塊里讀取過來的。

增量檢查點工作過程,和在實例恢復中的作用

只是串行化的圖出重做日志條目,不必區(qū)分這些條目是否是current logfile。

一個臟塊對應一個事務,但不一定對應一個重做日志條目,因為臟塊臟一次產(chǎn)生一條重做日志條目。

 Oracle檢查點是什么

1.CKPT進程發(fā)現(xiàn)CKPTQ太長(多長算長,oracle里有些參數(shù)可以控制),打算通知DBWR讓他刷出一些臟塊,縮短CKPTQ,從low cache rba到target rba是CKPT根據(jù)CKPTQ長度和系統(tǒng)I/0繁忙程序計算出來的值。通知后立即返回,不等DBWR寫完,即異步通知。

2.由于寫前協(xié)議,DBWR寫臟塊前都通知LGWR先把臟塊寫到重做日志文件。

3.DBWR按照CKPTQ從上到下的順序?qū)⑴K塊寫入數(shù)據(jù)文件(圖中從上到下是時間上越來越新)。

如果是完全檢查點,DBWR按照dirty list寫此時的checkpoint SCN之前的臟數(shù)據(jù)

4.在DBWR寫的過程中,CKPT會每隔3秒來檢查一次DBWR的寫進度,并把進度信息(就是哪一個臟塊)寫到控制文件中,叫做low cache rba,這每隔3秒一次的動作叫心跳,他與low cache rba配套,比如從控制文件中dump出這樣的信息,表示第793694908次檢查DBWR時,他寫到0x5.15119.0這個位置。

low cache rba:(0x5.15119.0) on disk rba:(0x5.15314.0)

on disk scn: 0x0000.0008ea68 10/20/2012 17:15:34

resetlogs scn: 0x0000.0006ce7b 03/30/2012 11:15:03

heartbeat: 793694908 mount id: 1363550103

可以這樣說,DBWR縮短了CKPTQ的長度,low cache rba是CKPT記錄的DBWR的寫進度。

每隔3秒具體寫的什么

為了減少頻繁增量檢查點的性能影響,CKPT進行的是輕量級更新,他并不會改寫控制文件中數(shù)據(jù)文件的檢查點信息,以及數(shù)據(jù)文件頭信息,而只是在控制文件中記錄這個檢查點的SCN(Controlfile Checkpointed at scn),以及DBWR此時寫到的臟塊的RBA信息。

5. 估計on disk rba是LGWR寫日志文件時值到控制文件中的。

6.當他寫完時(target rba的位置),target rba 和low cache rba相同,并把這一次檢查點的lrba記錄到控制文件中

7.控制文件中的 low cache rba指向的重做日志位置一定在on disk rba的下面(圖中是從下往上寫,越上面越新)。如果在他上面,就會出現(xiàn)臟塊寫入了數(shù)據(jù)文件而沒寫入重做日志文件,

這兩個rba之間的所有重做日志條目就是恢復時需要恢復的條目,稱為前滾。

8。提交過的事務,他的log buffer一定在log file里,但log file里也有沒提交過的條目。這一臟塊沒有提交,他被寫入了數(shù)據(jù)文件和重做日志文件,恢復時他也被恢復到buffer里,通過undo回滾可以去除這沒提交的數(shù)據(jù),這不在討論范圍內(nèi)。


Oracle 檢查點的類型

 CKPT負責把檢查點寫入控制文件和數(shù)據(jù)文件頭。檢查點有以下類型:Thread checkpoints其為 數(shù)據(jù)庫 檢查點,在以下情況下會出現(xiàn)這種檢查點: 一致性關閉數(shù)據(jù)庫;ALTER SYSTERM CHECKPOINT語句;online redo log file的切換;ALTER DATABASE BEGIN BACKUP語句;Tablespace and data file checkpoints 把某表空間內(nèi)所有數(shù)據(jù)文件的在SGA中的臟數(shù)據(jù)塊刷新到磁盤中,在一下情況下會出現(xiàn)這種檢查點:使得某表空間read-only或offline normal;收縮一個數(shù)據(jù)文件;ALTER DATABASE BEGIN BACKUP語句;Incremental checkpoints(增量備份) DBWn每三秒鐘就會刷新一次SGA中的臟數(shù)據(jù)塊到物理文件中,而CKPT每三秒中就會發(fā)出一個檢查點,把檢查點的信息寫入控制文件,但是不會更新數(shù)據(jù)文件頭的信息。其他的檢查點其他的檢查點包括,實例恢復的檢查點,刪除或truncate對象時觸發(fā)的檢查點。  




 OCP知識點講解 之 檢查點隊列與增量檢查點 

  檢查點的主要目的是以對數(shù)據(jù)庫的日常操作影響最小的方式刷新臟塊。臟塊不斷的產(chǎn)生,如何將臟塊刷新到磁盤中去呢?在8i之前,Oracle定期的鎖住所有的修改操作,刷新Buffer cache中的所有臟塊,這種刷新臟塊的方式被稱為完全檢查點,這極大的影響了效率,從9i之后只有當關閉數(shù)據(jù)庫時才會發(fā)生完全檢查點。

     從8i開始,Oracle增加了增量檢查點的概念,增量檢查點的主要宗旨就是定期的刷新一部分臟塊。將臟塊一次刷新完是不合理的,因為臟塊不斷產(chǎn)生,沒有窮盡。像完全檢查點那樣停止用戶所有的修改操作,將臟塊刷新完再繼續(xù),這絕對會極大的影響性能。所有增量檢查點的一次刷新部分塊是臟塊問題的最好解決辦法。那么,每次刷新時,都刷新那些塊呢?根據(jù)統(tǒng)計研究,根據(jù)塊變臟的順序,每次刷新那些最早臟的塊,這種方式最為合理。為了實現(xiàn)這一點,Oracle在Buffer cache中又建立了一個鏈表,就是檢查點隊列。每個塊在它變臟時,會被鏈接到檢查點隊列的末尾。就好像排隊一樣,9:00來的人站在第一位,9:05來的人排第二位,以后每來一個人都站在隊伍的末尾,這個隊伍就是按來到的時間順序排列的一個隊列。檢查點隊列就是這樣,塊在變臟時會被鏈到末尾。因此檢查點隊列是按塊變臟的時間順序,將塊排成了一個隊列。

Oracle檢查點是什么

     如上圖,檢查點隊列中的每一節(jié)點,都指向一個臟塊。檢查點隊列每個節(jié)點中的信息其實非常少,就是記錄對應塊在Buffer cache中的地址,臟塊對應的重做記錄在日志文件中的位置,另外還有前一個節(jié)點、后一個節(jié)點的地址。檢查點隊列還有LRU、臟LRU,這些都是雙向鏈表。雙向鏈表就是在節(jié)點中記錄前、后兩個節(jié)點的地址。

     檢查點隊列頭部的塊是最早變臟的,因此,Oracle會定期喚醒DBWn從檢查點隊列頭開始,沿著檢查點隊列的順序,刷新臟塊。在刷新臟塊的同時,仍可以不斷的有新的臟塊被鏈接到檢查點隊列的尾部。這個定期喚醒DBWn刷新臟塊的操作,Oracle就稱為增量檢查點。

Oracle檢查點是什么

     如上圖,1、2、3號節(jié)點所指向的臟塊已經(jīng)被刷新為干凈塊。同時,又有兩個塊變臟,它們被鏈接到了檢查點隊列的末尾,它們是9號、10號節(jié)點。

     檢查點隊列的頭,又被稱為檢查點位置,Checkpoint postion,這些名稱我們不必從字面上去理解??傊?,檢查點位置就是檢查點隊列頭。檢查點隊列頭節(jié)點(也就是檢查點位置)的信息,Oracle會頻繁的將它記錄到控制文件中,而且會很頻繁的記錄。一般是每隔三秒,有一個專門的進程CKPT,會將檢查點位置記錄進控制文件。

Oracle檢查點是什么

     如上圖,當前的檢查點位置是檢查點隊列的1號節(jié)點。又一個三秒到了,CKPT進程啟動,將新的檢查點位置記入控制文件:

Oracle檢查點是什么

     新的檢查點位置是4號節(jié)點,它對應當前變臟時間最早的臟塊。1、2、3號節(jié)點已經(jīng)從檢查點隊列中摘除了。因為它們對應的臟塊已經(jīng)不臟了。一般來說,控制文件中的檢查點位置之后的塊都是臟塊。但是有時也例外,因檢查點位置每三秒才會更新一次,就像上圖,1、2、3號節(jié)點對應的臟塊已經(jīng)被刷新過了,但是由于三秒間隔沒到,檢查點位置還是指向1號節(jié)點。只有當三秒到后,檢查點位置才會被更新到4號節(jié)點上。

     關于檢查點隊列、檢查點位置我們先說到這里,在全面的介紹什么是增量檢查點之前,我們先說一下檢查點隊列的一個重要作用。

     讓我們先來總結(jié)一下用戶修改塊時,Oracle內(nèi)部都發(fā)生了什么:

     1.如果塊不在Buffer cache,將塊讀入Buffer cache

     2.先生成重做記錄,并記入日志緩存,在用戶提交時寫到日志文件中

     3.在Buffer cache中修改塊

     4.在Buffer cache中設置塊的臟標志位,標志塊變成臟塊,同時在檢查點隊列末尾增加一個新節(jié)點,記錄這個新臟塊的信息,信息包括:臟塊在Buffer cache中的位置,在步驟2時生成的與此臟塊對應的重做記錄位置。

     5.用戶提交后,將相應的重做記錄從重做緩存寫入日志文件。

     我現(xiàn)在將日志補充到上面的圖中:

Oracle檢查點是什么

     就像上圖,檢查點隊列的每個節(jié)點,都保存有臟塊的地址和臟塊對應的重做記錄的編號。臟塊在Buffer cache中的位置是隨機的,用戶不一定修改那個塊。但重做記錄是順序生成的,就和檢查點隊列的排列順序一樣。因為,它們都是當塊被修改而變臟時產(chǎn)生的。塊A先被修改,塊A的重做記錄就排在前面,塊B后被修改,塊B對應的重做記錄會被排在塊A對應的重做記錄的后面。和它們在檢查點中的順序是一樣。每當數(shù)據(jù)庫因異外而當機,比如異常死機、斷電等等,Buffer cache中有許多臟塊沒來的及寫到磁盤上。以圖為例,比如說現(xiàn)在斷電了,現(xiàn)在磁盤上還有7個臟塊,它們里面有用戶修改過的數(shù)據(jù),Oracle已經(jīng)將反饋信息“你的修改完成”發(fā)送給用戶,用戶也以為他們的修改完成了,將為一直保存到數(shù)據(jù)庫中。但是,斷然的斷電,令這幾個臟塊中的數(shù)據(jù)丟失了,它們沒來得及寫到磁盤上。

     Oracle如何解決這個問題呢?很簡單,當數(shù)據(jù)庫重新啟動時,Oracle只需從控制文件中讀出檢查點位置,檢查點位置中記錄有重做記錄編號,根據(jù)此編號,Oracle可以很快的定位到日志文件中的重做記錄n,它讀出重做記錄n中的重做數(shù)據(jù),將用戶的修改操作重現(xiàn)到數(shù)據(jù)庫。接著,Oracle讀取重做記錄n+1中的重做數(shù)據(jù),重現(xiàn)用戶修改,這個過程將沿著日志流的順序,一直進行下去,直擋最后一條重做記錄,在上圖的例子中,最后一條重做記錄是第n+6條。這個過程完成后,用戶所有的修改又都被重現(xiàn)了,一點都不會丟失。只要你的日志文件是完整,日志流是完整的,就一點信息都不會丟失。

     有人可能會有一個問題,重做記錄在生成后,也是先被送進重做緩存,再由重做緩存寫往日志文件。這樣的機制下,一定會有某些重做記錄在沒來的及寫到日志文件中時,數(shù)據(jù)庫突然當機,而造成這些重做記錄丟失。這樣,這些重做記錄所對應的臟塊,將得不到恢復。用戶還是會丟失一些數(shù)據(jù)。

     這種情況的確會發(fā)生,但丟失的都是沒用的信息。為什么這么說的。Oracle會在用戶每次發(fā)出提交命令時,將事務所修改臟塊對應的重做記錄寫進日志文件,只有當這個操作完成時,用戶才會收到“提交完成”,這樣的信息,對于一個完整的事務,當用戶看到提交完成后,也就意味著所對應的重做記錄一定被寫到了日志文件中,即使發(fā)生異常死機,它也是絕對可以恢復。而當用戶沒有提交,或沒來得及提交,數(shù)據(jù)庫就崩潰了,那么事務就是不完整的,這個事務必須被回滾,它根本用不著恢復。對于這樣不完整的事務,它對應的重做記錄有可能丟失,但這無所謂了,因為不完整的事務根本不需要恢復。也就是說,只有用戶的事務提交了,用戶的修改一定不會丟失。不過這還有一個前提,就是日志文件千萬不能損壞,DBA所要做的就是要保證日志文件不能損壞。DBA可以使用RAID1這樣的磁盤鏡像技術,或者多元備份日志文件,等等,這個我們在前面章節(jié)中已經(jīng)講過了的。

     我們上面所講到的這種恢復,是自動進行的,并且不需要DBA參與,它被稱之為實例恢復。

     檢查點隊列與增量檢查點的作用我們已經(jīng)說的差不多了,它們的主要目的就是讓DBWn沿檢查點隊列的順序刷新臟塊。還有,就是實例恢復。

     下面我們來討論一下增量檢查點的設置。

     這里所說的檢查點設置,主要指增量檢查點頻繁的設置。注意增量檢查點只是一個名詞,不必按字面的意義去理解它。增量檢查點發(fā)生時,Oracle會喚醒DBWn沿著檢查點隊列寫臟塊,這就是增量檢查點。那么到底多長時間一次發(fā)生一次增量檢查點呢?這個增量檢查點的頻率是非常重要的,它基本上控制著DBWn多長時間去刷新一次臟塊。DBWn活動的太頻繁,會影響數(shù)據(jù)庫的整體性能,如果DBWn活動太不頻繁,又會使臟塊擠壓太多,這同樣也會影響性能。而且,如果出現(xiàn)異常崩潰,需要實例恢復,臟塊越多,實例恢復越慢。。在9i之前DBA主要靠間隔時間等方式來設置增量檢查點的頻率,比如可以讓Oracle每10分鐘發(fā)生一次增量檢查點。如果這個數(shù)字設置不合適,對數(shù)據(jù)庫性能的影響是很大的。而且有可能造成實例恢復時間過長。在9i之后,特別是到了10g中,檢查點已經(jīng)相當?shù)闹悄芑?,很少會成為I/O問題的原兇。9i中設置fast_start_mttr_target參數(shù)為你所期望的實例恢復時間,系統(tǒng)將自動控制增量檢查點的頻率。比如,你希望實例恢復可以在5分鐘內(nèi)完成,你可以將此參數(shù)設置為300,也就是300稱。

     如果此參數(shù)設置的值超出了硬件實際的限制,比如你將它設置為60,你期望無論在任何情況下,數(shù)據(jù)庫都可以在1分鐘內(nèi)完成實例恢復,但根據(jù)數(shù)據(jù)庫的臟塊生成速度、存儲設備的寫性能,1分鐘內(nèi)根本無法完成實例恢復。這時候Oracle會自動設置合適的fast_start_mttr_target參數(shù)值,我們可以在參數(shù)文件中看到修正后的參數(shù)值,也可以在V$instance_recovery視圖中的Target_mttr列中看到實際的值。例如:

     (舉個例子)

     我們不能將這個值設置的太小,因為實例恢復必競只是偶然現(xiàn)象。如果為了讓實例恢復盡快完成,而設置fast_start_mttr_target為很小的值,那么DBWn將活動的很頻繁,這會造成性能問題的。 為了避免用戶設置不合理的增量檢查點頻率,在10G中,如果將fast_start_mttr_target設置為0,Oracle將根據(jù)產(chǎn)生臟塊的速度、存貯硬件的性能自動調(diào)節(jié)檢查點的頻率,盡量使檢查點頻率不成為I/O問題的原兇。

     檢查點的主要任務就是催促DBWn刷新臟塊,如果DBWn刷新臟塊時的等待事件太多,就說明臟塊太多、存儲設備的寫速度太慢,或者就是增量檢查點的頻率太高了,或太低了。DBWn寫臟塊的等待事件是Db file parallel write。如果你的增量檢查點頻率很低,你發(fā)現(xiàn)了此事件,在排除了存儲設備寫性能的問題后,你應該將增量檢查點頻率設置的高一些。反之,如果你的增量檢查點頻率本身很高,出現(xiàn)了Db file parallel write事件,這說明檢查點頻率太高了。

     除它之外,還有一個和DBWn、增量檢查瞇有關的等待事件,它是Write complete waits事件,當前臺進程要修改DBWn正要成批寫的塊中的若干個塊時,就會有此等待事件,這個事件是前臺進程再等待DBWn寫完成。這個等待事太多,說明了存儲設備寫性能有問題,或者增量檢查點太頻率了。

     我們可以V$instance_recovery中看到有關檢查點的很多信息:

     Estimated_mttr列如果太大,說明檢查點不夠頻繁,同時也說明臟塊產(chǎn)生的太多。同時在V$sysstat資料視圖中,還有兩個資料background checkpoints started、background checkpoints completed,前面的一個是后臺進程檢查點開始次數(shù),后一個是后臺進程檢查點完成次數(shù)。后臺進程檢查點的意義,其實就是增量檢查點。只有增量檢查點是由后臺進程觸發(fā)的。如果你用Alter system checkpoing命令讓系統(tǒng)完成完全檢查點,這叫做前臺檢查點與增量檢查點無關,是不會被記入這兩個資料了。如果這兩個值經(jīng)常相差一些,比如檢查點的開始次數(shù)比完成次數(shù)大的不至1,這說明有太多次檢查點開始,但沒有及時完成。這說明檢查點太頻繁或檢查點完成的太慢。

     (舉例,大量的產(chǎn)生臟塊、日志文件比較小5MB,日志文件頻率的切換而觸發(fā)檢查點,同時查看一下等待事件)

     檢查點的問題大多數(shù)情況下其實都是DBWn寫I/O的問題, DBWn寫臟塊的等待事件是Db file parallel write,還有Write complete waits等待事件,是當前臺進程要修改DBWn正要成批寫的塊中的若干個塊時,就會有此等待事件,這個事件是前臺進程再等待DBWn寫完成。這個等待事太多,也說明了DBWn有問題。

     注意,對于數(shù)據(jù)文件的I/O問題,除了等待事件外,我們還可以用上幾節(jié)講過了V$filestat視圖幫助確定問題。)



在 Oracle 的官方文檔中介紹 Oracle 的 Checkpoint 有:
(1)Thread Checkpoint;
(2)Tablespace and datafile checkpoint;
(3)Incremental checkpoint。
對 于后兩種 checkpoint,大家都有一個比較清晰的認識。 但是對于 Thread checkpoint 和 database checkpoint 之間的關系以及他們在單節(jié)點和RAC數(shù)據(jù)庫之間的不同可能存在一些誤區(qū)。 下面將通過一些例子來講解一下 Thread checkpoint,以及在單節(jié)點和 RAC 中 Thread checkpoint 的不同。

一 單節(jié)點數(shù)據(jù)庫(或者是RAC database中,只保留一個節(jié)點):

*為了便于觀察checkpoint的,設置log_checkpoints_to_alert,讓checkpoint的信息打印到alert log中:

SQL> show parameter log_checkpoints_to_alert

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_checkpoints_to_alert             boolean     TRUE


1) 對數(shù)據(jù)庫做"alter system switch logfile":sys@R11203> select file#, CHECKPOINT_CHANGE# from v$datafile;

    FILE#         CHECKPOINT_CHANGE#
---------- --------------------------
        1             12717430780764
        2             12717430780764
        3             12717430780764
        4             12717430780764   <<<<<<<<<< 未switch之前

sys@R11203> alter system switch logfile;

System altered.

sys@R11203> select file#, CHECKPOINT_CHANGE# from v$datafile;

    FILE#         CHECKPOINT_CHANGE#
---------- --------------------------
        1             12717430780764
        2             12717430780764
        3             12717430780764
        4             12717430780764  <<<<<<<<<<<<< switch之后立即查看,v$datafile對應的checkpoint_change#并沒有變化。


2)檢查一下數(shù)據(jù)庫的alert log:

Tue Jan 19 16:01:02 2016  
Beginning log switch checkpoint up to RBA [0x5a.2.10], SCN: 12717430780990    <<<<<<<<<<<<<<<  開始做log switch的checkpoint 到SCN12717430780990,但是并沒有看到checkpoint結(jié)束。

3) 過了大約幾分鐘后,再次檢查 alert log 以及 V$datafile

Tue Jan 19 16:05:58 2016   <<<<<<<<<<<<<<<<<< 16:05 已經(jīng)結(jié)束checkpoint
Completed checkpoint up to RBA [0x5a.2.10], SCN: 12717430780990   sys@R11203> select file#, CHECKPOINT_CHANGE# from v$datafile;

    FILE#         CHECKPOINT_CHANGE#
---------- --------------------------
        1             12717430780990
        2             12717430780990
        3             12717430780990
        4             12717430780990 <<<<<<<< v$datafile 中的checkpoint check# 已經(jīng)更改到新的SCN:12717430780990

二 RAC數(shù)據(jù)庫:

1) 對數(shù)據(jù)庫做"alter system switch logfile":

SQL> select INST_ID,INSTANCE_NAME,STATUS from gv$instance;

  INST_ID INSTANCE_NAME    STATUS
---------- ---------------- ------------
        1 ora11g1          OPEN
        2 ora11g2          OPEN

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11583337
        2           11583337
        3           11583337
        4           11583337
        5           11583337
        6           11583337

6 rows selected.

SQL> alter system switch logfile;

System altered.

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11583337
        2           11583337
        3           11583337
        4           11583337
        5           11583337
        6           11583337  <<<<<<<<<<  checkpoint_change# 并沒有改變。

6 rows selected.

2) 觀察此節(jié)點的alert log:

Wed Jan 20 07:10:16 2016
Beginning log switch checkpoint up to RBA [0x22f.2.10], SCN: 11583841 <<<<<<<<< 開始 log switch的checkpoint。
Thread 1 advanced to log sequence 559 (LGWR switch)
 Current log# 1 seq# 559 mem# 0: +DATA1/ora11g/onlinelog/group_1.257.827893181
Wed Jan 20 07:10:16 2016
Completed checkpoint up to RBA [0x22f.2.10], SCN: 11583841   <<<<<<<<<<  log switch的checkpoint已經(jīng)完成。

3) 重新觀察一下v$datafile:

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11583337
        2           11583337
        3           11583337
        4           11583337
        5           11583337
        6           11583337  <<<<<<<<<<<< checkpoint_change# 還是沒有改變。

6 rows selected.

4) 執(zhí)行"alter system checkpoint"

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11583337
        2           11583337
        3           11583337
        4           11583337
        5           11583337
        6           11583337

6 rows selected.

SQL> alter system checkpoint;

System altered.

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11583983
        2           11583983
        3           11583983
        4           11583983
        5           11583983
        6           11583983 <<<<<<<<<< 變成: 11583983

6 rows selected.

5) 觀察此節(jié)點的alert log:

Wed Jan 20 07:14:21 2016
Beginning global checkpoint up to RBA [0x231.3.10], SCN: 11583983   <<<<<<<<<<  Global checkpoint到 11583983。
Completed checkpoint up to RBA [0x231.3.10], SCN: 11583983

6) 那么如果在RAC中做log switch,每次thread checkpoint的記錄在哪里可以查詢到呢?

SQL> select INSTANCE_NUMBER,INSTANCE_NAME,THREAD#,STATUS from gv$instance;

INSTANCE_NUMBER INSTANCE_NAME       THREAD# STATUS
--------------- ---------------- ---------- ------------
             1 ora11g1                   1 OPEN     <<<<<<<<<<<<<<<<<<<<   節(jié)點1的thead號為: 1
             2 ora11g2                   2 OPEN

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11616270
        2           11616270
        3           11616270
        4           11616270
        5           11616270
        6           11616270

6 rows selected.

SQL> alter system switch logfile;

System altered.

7)在alert log中:

Thu Jan 21 02:22:52 2016
Beginning log switch checkpoint up to RBA [0x23a.2.10], SCN: 11621392
Thread 1 advanced to log sequence 570 (LGWR switch)
 Current log# 2 seq# 570 mem# 0: +DATA1/ora11g/onlinelog/group_2.258.827893183
Thu Jan 21 02:22:53 2016
Archived Log entry 358 added for thread 1 sequence 569 ID 0xfbc6d574 dest 1:
Thu Jan 21 02:22:55 2016
Completed checkpoint up to RBA [0x23a.2.10], SCN: 11621392   <<<<<<<<<<<<<  Thread checkpoint 到 11621392已經(jīng)完成。

SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile;

    FILE# CHECKPOINT_CHANGE#
---------- ------------------
        1           11616270
        2           11616270
        3           11616270
        4           11616270
        5           11616270
        6           11616270 <<<<<<<<<< v$datafile中的checkpoint change#照例沒有改變。

6 rows selected.

8) 查看v$thread:

SQL> select THREAD#,CHECKPOINT_CHANGE# from v$thread;

  THREAD# CHECKPOINT_CHANGE#
---------- ------------------
        1           11621392   <<<<<<<<<<<<<<<<  Thread 1 checkpoint 到 11621392 (和alert log中的描述一致)
        2           11619485

總結(jié)一下:

1. 對于單節(jié)點數(shù)據(jù)庫,由于只有一個thread,所以由log switch發(fā)起的對當前thread的checkpoint,實質(zhì)上就是整個數(shù)據(jù)庫的checkpoint,所以log switch會導致v$datafile (v$datafile_header)中的checkpoint_change#改變。 但是必須要等checkpoint完成以后才會變成最新的值。

2. 對于RAC(2個節(jié)點以上)的數(shù)據(jù)庫,由于至少存在2個或者以上的thread,所以對單一thread的 log switch并不會觸發(fā)v$datafile (v$datafile_header)的checkpoint_change#的修改。原因是:只對其中一個thread(log)cover塊的checkpoint,只會觸發(fā)在此節(jié)點上臟塊的寫回. 但是由于多于2個節(jié)點,所以其他的節(jié)點可能存在在此checkpoint SCN之前的臟塊,所以對于數(shù)據(jù)文件(或者是數(shù)據(jù)庫)來說,這并不是一個完整的database級的checkpoint。 在RAC中,只有所有節(jié)點間的全局檢查點(global checkpoint)會導致v$datafile中的checkpoint_change#的變化,比如"alter system checkpoint"。

 3. 在RAC中,對于thread的checkpoint_change#,可以通過v$thread來查詢。



什么是checkpoint

在數(shù)據(jù)庫系統(tǒng)中,寫日志和寫數(shù)據(jù)文件是數(shù)據(jù)庫中IO消耗最大的兩種操作,在這兩種操作中寫數(shù)據(jù)文件屬于分散寫,寫日志文件是順序?qū)?,因此為了保證數(shù)據(jù)庫的性能,通常數(shù)據(jù)庫都是保證在提交(commit)完成之前要先保證日志都被寫入到日志文件中,而臟數(shù)據(jù)塊著保存在數(shù)據(jù)緩存(buffer cache)中再不定期的分批寫入到數(shù)據(jù)文件中。也就是說日志寫入和提交操作是同步的,而數(shù)據(jù)寫入和提交操作是不同步的。這樣就存在一個問題,當一個數(shù)據(jù)庫崩潰的時候并不能保證緩存里面的臟數(shù)據(jù)全部寫入到數(shù)據(jù)文件中,這樣在實例啟動的時候就要使用日志文件進行恢復操作,將數(shù)據(jù)庫恢復到崩潰之前的狀態(tài),保證數(shù)據(jù)的一致性。檢查點是這個過程中的重要機制,通過它來確定,恢復時哪些重做日志應該被掃描并應用于恢復。

一般所說的checkpoint是一個數(shù)據(jù)庫事件(event),checkpoint事件由checkpoint進程(LGWR/CKPT進程)發(fā)出,當checkpoint事件發(fā)生時DBWn會將臟塊寫入到磁盤中,同時數(shù)據(jù)文件和控制文件的文件頭也會被更新以記錄checkpoint信息。


checkpoint的作用

checkpoint主要2個作用:

  1. 保證數(shù)據(jù)庫的一致性,這是指將臟數(shù)據(jù)寫入到硬盤,保證內(nèi)存和硬盤上的數(shù)據(jù)是一樣的;

  2. 縮短實例恢復的時間,實例恢復要把實例異常關閉前沒有寫出到硬盤的臟數(shù)據(jù)通過日志進行恢復。如果臟塊過多,實例恢復的時間也會很長,檢查點的發(fā)生可以減少臟塊的數(shù)量,從而提高實例恢復的時間。

通俗的說checkpoint就像word的自動保存一樣。


檢查點分類

  • 完全檢查點(Normal checkpoint)

  • 增量檢查點(Incremental checkpoint)


checkpoint相關概念術語

在說明checkpoint工作原理之前我們先了解一些相關的術語。


RBA(Redo Byte Address), Low RBA(LRBA), High RBA(HRBA)

RBA就是重做日志塊(redo log block)的地址,相當與數(shù)據(jù)文件中的ROWID,通過這個地址來定位重做日志塊。RBA由三個部分組成:

  1. 日志文件序列號(4字節(jié))——根據(jù)這個找到對應的日志文件地址。

  2. 日志文件塊編號(4字節(jié))——根據(jù)這個找到對應日志條目所在的日志文件塊。

  3. 重做日志記錄在日志塊中的起始偏移字節(jié)數(shù)(2字節(jié))——找到對應的日志條目。

通常使用RBA的形式有:

LRBA 數(shù)據(jù)緩存(buffer cache)中一個臟塊第一次被更新的時候產(chǎn)生的重做日志記錄在重做日志文件中所對應的位置就稱為LRBA。 HRBA 數(shù)據(jù)緩存(buffer cache)中一個臟塊最近一次被更新的時候產(chǎn)生的重做日志記錄在重做日志文件中所對應的位置就稱為HRBA。 checkpoint RBA 當一個checkpoint事件發(fā)生的時候,checkpoint進程會記錄下當時所寫的重做日志塊的地址即RBA,此時記錄的RBA被稱為checkpoint RBA。從上一個checkpoint RBA到當前的checkpoint RBA之間的日志所保護的buffer cache中的臟塊接下來將會被寫入到數(shù)據(jù)文件當中去。


Buffer checkpoint Queues (BCQ)

Oracle將所有在數(shù)據(jù)緩存中被修改的臟塊按照LRBA順序的組成一個checkpoint隊列,這個隊列主要記錄了buffer cache第一次發(fā)生變化的時間順序,然后有DBWn進程根據(jù)checkpoint隊列順序?qū)⑴K塊寫入到數(shù)據(jù)文件中,這樣保證了先發(fā)生變更的buffer能先被寫入到數(shù)據(jù)文件中。BCQ的引入是為了支持增量checkpoint的。


Active checkpoint Queue (ACQ)

ACQ中包含了所有活動的checkpoint請求。每次有新checkpoint請求是都會在ACQ中增加一條記錄,ACQ記錄中包含了相應的checkpoint RBA。checkpoint完成以后相應的記錄將被移出隊列。


完全檢查點 (normal checkpoint)


完全檢查點工作過程

一個checkpoint操作可以分成三個不同的階段:

  • 第一階段,checkpoint進程開始一個checkpoint事件,并記錄下checkpoint RBA,這個通常是當前的RBA。

  • 第二階段,checkpoint進程通知DBWn進程將所有checkpoint RBA之前的buffer cache里面的臟塊寫入磁盤。

  • 確定臟塊都被寫入磁盤以后進入到第三階段,checkpoint進程將checkpoint信息(SCN)寫入/更新數(shù)據(jù)文件和控制文件中。

更新SCN的操作由CKPT進程完成,在Oracle 8.0之后CKPT進程默認是被啟用的,如果CKPT進程沒有啟用的話那相應的操作將由LGWR進程完成。


什么時候發(fā)生normal checkpoint

下面這些操作將會觸發(fā)checkpoint事件:

  • 日志切換,通過ALTER SYSTEM SWITCH LOGFILE。

  • DBA發(fā)出checkpoint命令,通過ALTER SYSTEM checkpoint。

  • 對數(shù)據(jù)文件進行熱備時,針對該數(shù)據(jù)文件的checkpoint也會進行,ALTER TABLESPACE TS_NAME BEGIN BACKUP/END BACKUP。

  • 當運行ALTER TABLESPACE/DATAFILE READ ONLY的時候。

  • SHUTDOWN命令發(fā)出時。

特別注意:

  1. 日志切換會導致checkpoint事件發(fā)生,但是checkpoint發(fā)生卻不會導致日志切換。

  2. 日志切換觸發(fā)的是normal checkpoint,而不是大家所說的增量checkpoint,只不過log switch checkpoint的優(yōu)先級非常低,當一個log switch checkpoint發(fā)生的時候它并不會立即的通知DBWn進程去寫數(shù)據(jù)文件,但是當有其它原因?qū)е耤heckpoint或者是寫入數(shù)據(jù)文件的RBA超過log switch checkpoint的checkpoint RBA的時候,這次的log switch checkpoint將會被標記成完成狀態(tài),同時更新控制文件和數(shù)據(jù)文件頭。我們隨后可以做個實驗驗證這個說法。


checkpoint和SCN有什么關系?

在Oracle中SCN相當于它的時鐘,在現(xiàn)實生活中我們用時鐘來記錄和衡量我們的時間,而Oracle就是用SCN來記錄和衡量整個Oracle系統(tǒng)的更改。

Oracle中checkpoint是在一個特定的“時間點”發(fā)生的,衡量這個“時間點”用的就是SCN,因此當一個checkpoint發(fā)生時SCN會被寫入文件頭中以記錄這個checkpoint。


增量checkpoint


增量checkpoint工作過程

因為每次完全的checkpoint都需要把buffer cache所有的臟塊都寫入到數(shù)據(jù)文件中,這樣就是產(chǎn)生一個很大的IO消耗,頻繁的完全checkpoint操作很對系統(tǒng)的性能有很大的影響,為此Oracle引入的增量checkpoint的概念,buffer cache中的臟塊將會按照BCQ隊列的順序持續(xù)不斷的被寫入到磁盤當中,同時CKPT進程將會每3秒中檢查DBWn的寫入進度并將相應的RBA信息記錄到控制文件中。(關于CKPT進程每3秒進行修改控制文件的測試: http://blog.csdn.net/changyanmanman/article/details/7362528 )

有了增量checkpoint之后在進行實例恢復的時候就不需要再從崩潰前的那個完全checkpoint開始應用重做日志了,只需要從控制文件中記錄的RBA開始進行恢復操作,這樣能節(jié)省恢復的時間。


發(fā)生增量checkpoint的先決條件

  • 恢復需求設定 (FAST_START_IO_TARGET/FAST_START_MTTR_TARGET)

  • LOG_checkpoint_INTERVAL參數(shù)值

  • LOG_checkpoint_TIMEOUT參數(shù)值

  • 最小的日志文件大小

  • buffer cache中的臟塊的數(shù)量


增量checkpoint的特點

  • 增量checkpoint是一個持續(xù)活動的checkpoint。

  • 沒有checkpoint RBA,因為這個checkpoint是一直都在進行的,所以不存在normal checkpoint里面涉及的checkpoint RBA的概念。

  • checkpoint advanced in memory only

  • 增量checkpoint所完成的RBA信息被記錄在控制文件中。

  • 增量checkpoint可以減少實例恢復時間。


增量checkpoint相關參數(shù)設置

log_checkpoint_interval 設定兩次checkpoint之間重做日志塊(重做日志塊和系統(tǒng)數(shù)據(jù)塊是一樣的)數(shù),當重做日志塊數(shù)量達到設定值的時候?qū)⒂|發(fā)checkpoint。 log_checkpoint_timeout 設定兩次checkpoint之間的間隔時間,當超時值達到時增量checkpoint將被觸發(fā)。Oracle建議不用這個參數(shù)來控制,因為事務(transaction)大小不是按時間等量分布的。將此值設置成0時將禁用此項設置。 fast_start_io_target 因為log_checkpoint_interval主要看的時候重做日志塊的數(shù)量,并不能反應buffer cache中臟數(shù)據(jù)塊的修改,因此Oracle又引入了這個參數(shù)來實現(xiàn)當臟數(shù)據(jù)塊達到一定數(shù)量的時候觸發(fā)checkpoint,不過此參數(shù)實際上控制的是恢復時所需IO的數(shù)量。 fast_start_mttr_target

  • 此參數(shù)是在9i中引入用來代替前面的三個參數(shù)的,它定義了數(shù)據(jù)塊崩潰后所需要的實例恢復的時間,Oracle在實際上內(nèi)在的解釋成兩個參數(shù):fast_start_io_target和log_checkpoint_interval.如果這兩個參數(shù)沒有顯式的指定,計算值將生效.。

  • fast_start_mttr_target可以設定的最大值是3600,即一個小時。它的最小值沒有設限,但是并不是說可以設置一個任意小的值,這個值會受最小dirty buffer(最小為1000)的限制,同時還會受初始化時間以及文件打開時間的限制。

  • 在設置此參數(shù)的時候要綜合考慮系統(tǒng)的IO,容量以及CPU等信息,要在系統(tǒng)性能和故障恢復時間之間做好平衡。

  • 將此參數(shù)設置成0時將禁用 fast-start checkpointing,這樣能見效系統(tǒng)負載但同時會增加系統(tǒng)的恢復時間。

  • 如果fast_start_io_target or log_checkpoint_interval被指定,他們會自動覆蓋由fast_start_mttr_target參數(shù)計算出來的值。

在10g中,數(shù)據(jù)庫能根據(jù)各種系統(tǒng)參數(shù)的設置值來自動調(diào)整檢查點的執(zhí)行頻率,以獲得最好的恢復時間以及系統(tǒng)的正常運行影響最小。通過自動checkpoint調(diào)整,Orach能在系統(tǒng)低IO操作的時候?qū)⑴K塊寫入到數(shù)據(jù)文件中,因此即時DBA沒有設置checkpoint相關的參數(shù)值或是設置了一個不合理的值的時候系統(tǒng)還是能獲得一個很合理的系統(tǒng)恢復時間。

10g中的增量checkpoint更能體現(xiàn)它持續(xù)活動的特點,在10g中,增量checkpoint不是在某一個特定的條件下觸發(fā),而是由數(shù)據(jù)庫根據(jù)系統(tǒng)參數(shù)設置自動觸發(fā)。


與完全checkpoint的區(qū)別

  • 完全checkpoint會將checkpoint的信息寫入到控制文件以及數(shù)據(jù)文件頭中

  • 增量checkpoint只會將RBA信息寫入到控制文件中。


查看系統(tǒng)的checkpoint動作

我們可以通過將LOG_checkpointS_TO_ALERT設置成TRUE來打開checkpoint的trace,這樣就可以跟蹤checkpoint的操作了。

ALTER SYSTEM SET LOG_checkpointS_TO_ALERT=TRUE;

這設置以后系統(tǒng)的checkpoint將會被記錄alert_$SID.log文件中。

在V$DATAFILE_HEADER里面也保存了發(fā)生完全checkpoint的時候一些相關信息,包括checkpoint發(fā)生時間、對應SCN已經(jīng)checkpoint的次數(shù)。

select file# NO, status, tablespace_name, name, dbms_flashback.get_system_change_number CUR_SCN,
  to_char(resetlogs_time, 'YYYY-MM-DD HH24:MI:SS') RST_DT,resetlogs_change# RST_SCN,
  to_char(checkpoint_time, 'YYYY-MM-DD HH24:MI:SS') CKPT_DT,checkpoint_change# CKPT_SCN, checkpoint_count CKPT_CNT
from v$datafile_header;
 
/**
NO  STATUS  TABLESPACE_NAME  CUR_SCN  RST_DT              RST_SCN  CKPT_DT             CKPT_SCN  CKPT_CNT
--- ------- ---------------- -------- ------------------- -------- ------------------- --------- ---------
1   ONLINE  SYSTEM           533541   2008-01-12 16:51:53 446075   2008-08-04 22:03:58 532354    65
2   ONLINE  UNDOTBS1         533541   2008-01-12 16:51:53 446075   2008-08-04 22:03:58 532354    28
3   ONLINE  SYSAUX           533541   2008-01-12 16:51:53 446075   2008-08-04 22:03:58 532354    65
4   ONLINE  USERS            533541   2008-01-12 16:51:53 446075   2008-08-04 22:03:58 532354    64
5   ONLINE  EXAMPLE          533541   2008-01-12 16:51:53 446075   2008-08-04 22:03:58 532354    24
*/


完全檢查點

-- 我們先執(zhí)行一個
ALTER SYSTEM checkpoint;
 
-- 下面是alert文件中的數(shù)據(jù)結(jié)果
Mon Aug  4 22:22:08 2008
Beginning global checkpoint up to RBA [x8.c9d4.10], SCN: 533714
Completed checkpoint up to RBA [x8.c9d4.10], SCN: 533714
-- 我們能看到完全checkpoint發(fā)生的SCN 533714
 
-- 下面我們再對照下V$DATAFILE_HEADER中的結(jié)果
NO  STATUS  TABLESPACE_NAME  CUR_SCN  RST_DT              RST_SCN CKPT_DT             CKPT_SCN  CKPT_CNT
--- ------- ---------------- -------- ------------------- -------- ------------------- --------- ---------
1   ONLINE  SYSTEM           533790   2008-01-12 16:51:53 446075   2008-08-04 22:22:08 533714    66
2   ONLINE  UNDOTBS1         533790   2008-01-12 16:51:53 446075   2008-08-04 22:22:08 533714    29
3   ONLINE  SYSAUX           533790   2008-01-12 16:51:53 446075   2008-08-04 22:22:08 533714    66
4   ONLINE  USERS            533790   2008-01-12 16:51:53 446075   2008-08-04 22:22:08 533714    65
5   ONLINE  EXAMPLE          533790   2008-01-12 16:51:53 446075   2008-08-04 22:22:08 533714    25
 
-- 看到了么,checkpoint時間和checkpoint的SCN已經(jīng)被記錄到數(shù)據(jù)文件頭中了。


日志切換時的檢查點

-- 我們先做一次日志切換
ALTER SYSTEM SWITCH LOGFILE;
 
-- 然后看看alert里面的記錄
Mon Aug  4 22:31:39 2008
Beginning log switch checkpoint up to RBA [x9.2.10], SCN: 534450
Thread 1 advanced to log sequence 9
  Current log# 2 seq# 9 mem# 0: /u/app/oracle/oradata/orcl/redo02.log
Mon Aug  4 22:35:58 2008
Completed checkpoint up to RBA [x9.2.10], SCN: 534450
 
-- 我們能看到checkpoint是在過了一段時間(這里是4分鐘)之后才完成的
 
-- 接著我們來看下V$DATAFILE_HEADER中的結(jié)果
NO  STATUS  TABLESPACE_NAME  CUR_SCN  RST_DT              RST_SCN CKPT_DT             CKPT_SCN  CKPT_CNT
--- ------- ---------------- -------- ------------------- -------- ------------------- --------- ---------
1   ONLINE  SYSTEM           534770   2008-01-12 16:51:53 446075   2008-08-04 22:31:44 534450    67
2   ONLINE  UNDOTBS1         534770   2008-01-12 16:51:53 446075   2008-08-04 22:31:44 534450    30
3   ONLINE  SYSAUX           534770   2008-01-12 16:51:53 446075   2008-08-04 22:31:44 534450    67
4   ONLINE  USERS            534770   2008-01-12 16:51:53 446075   2008-08-04 22:31:44 534450    66
5   ONLINE  EXAMPLE          534770   2008-01-12 16:51:53 446075   2008-08-04 22:31:44 534450    26
 
-- 在這里我們能發(fā)現(xiàn)下V$DATAFILE_HEADER里面記錄的SCN和日志切換發(fā)生的checkpoint的SCN是一樣的,
-- 這就證明了日志切換是會更新數(shù)據(jù)文件頭的,同時日志切換的checkpoint是一個級別比較低的操作,
-- 它不會立即完成,這也是出于性能上考慮的。


增量checkpoint查看

當前所知只有在LOG_checkpoint_TIMEOUT設置了非0值之后觸發(fā)的增量checkpoint會在alert文件中有記錄,其他條件觸發(fā)的增量checkpoint都不會記錄在alert文件中。

-- 下面是當LOG_checkpoint_TIMEOUT設置為1800s的時候所產(chǎn)生的增量checkpoint記錄
Sun Aug  3 19:08:56 2008
Incremental checkpoint up to RBA [0x8.e17.0], current log tail at RBA [0x8.1056.0]
Sun Aug  3 19:39:00 2008
Incremental checkpoint up to RBA [0x8.1be0.0], current log tail at RBA [0x8.1c6e.0]
Sun Aug  3 20:09:04 2008
Incremental checkpoint up to RBA [0x8.2af5.0], current log tail at RBA [0x8.2b6a.0]
Sun Aug  3 20:39:07 2008
Incremental checkpoint up to RBA [0x8.3798.0], current log tail at RBA [0x8.3851.0]
Sun Aug  3 21:09:10 2008
Incremental checkpoint up to RBA [0x8.47b9.0], current log tail at RBA [0x8.48bb.0]
Sun Aug  3 21:39:14 2008
Incremental checkpoint up to RBA [0x8.548d.0], current log tail at RBA [0x8.5522.0]
Mon Aug  4 21:05:18 2008


查看fast_start_mttr_target

通過查看V$INSTANCE_RECOVERY動態(tài)性能視圖可以查看一些MTTR相關的信息。

SELECT TARGET_MTTR,ESTIMATED_MTTR,CKPT_BLOCK_WRITES,CKPT_BLOCK_WRITES FROM V$INSTANCE_RECOVERY

TARGET_MTTR 用戶設置的參數(shù)FAST_START_MTTR_TARGET的值. ESTIMATED_MTTR 根據(jù)目前臟塊數(shù)目和日志塊數(shù)目,評估的現(xiàn)在進行恢復所需要的時間. CKPT_BLOCK_WRITES 檢查點寫完的塊數(shù)目. CKPT_BLOCK_WRITES 額外的因為檢查點引起的數(shù)據(jù)庫寫入操作 (因為不必要的檢查點的產(chǎn)生,設置一個非常小的系統(tǒng)恢復時間將會對性能產(chǎn)生負面影響,為了幫助管理員監(jiān)測這個參數(shù)設置較小時對數(shù)據(jù)庫的影響,這個視圖顯示了這個列)


相關視圖


V$視圖

V$DATAFILE_HEADER 查看數(shù)據(jù)文件的完全checkpoint信息。 V$INSTANCE_RECOVERY 查看fast_start_mttr_target設置以及系統(tǒng)MTTR相關信息。


X$視圖

X$BH 用于查看臟塊的LRBA和HRBA(There is also a recovery RBA which is used to record the progress of partial block recovery by PMON.) 。 X$TARGETRBA 查看增量checkpoint RBA,target RBA和on-disk RBA。 X$KCCCP 這里面也有增量checkpoint RBA,target RBA的信息。 X$KCCRT 完全checkpoint(full thread checkpoint)RBA信息。


補充說明

寫完這篇文章之后又看了寫在itpub上的討論,更新下觀點。( http://www.itpub.net/viewthread.php?tid=1053847 )

關于增量checkpoint和完全的checkpoint的區(qū)別這方面的爭論里來不少,特別是對于日志切換到底是增量還是完全的爭論更是如此,但是其實翻遍Oracle的文檔就沒有發(fā)現(xiàn)有提到增量checkpoint(incremental checkpoint)或是完全checkpoint(full checkpoint)這兩個概念。

我的觀點是根本就沒有必要可以的區(qū)分是增量還是完全,真正要理解的是不同情況下的checkpoint都會有些什么樣的行為,然后根據(jù)這些行為來對數(shù)據(jù)庫進行配置,設置相應的參數(shù),制定相應的備份/恢復策略,就此而已。
下面列出寫常見的checkpoint行為:

  1. 類似于alter system checkpoint這樣的語句所產(chǎn)生的,先記錄下當前的scn,然后推動DBWn進程去寫臟數(shù)據(jù),當寫到所記錄的scn時候檢查點結(jié)束,然后ckpt進程將記錄的scn寫入到控制文件和數(shù)據(jù)文件頭。

  2. 設置參數(shù)log_checkpoint_timeout之后產(chǎn)生的,在超時值達到的時候,ckpt進程記錄當時DBWn寫臟數(shù)據(jù)的進度,也就是寫到那個scn了,此時檢查點信息只記錄到控制文件中,同時如果設置了LOG_checkpointS_TO_ALERT的話我們會在alert中得到這樣的信息:Sun Aug  3 19:08:56 2008
    Incremental checkpoint up to RBA [0x8.e17.0], current log tail at RBA [0x8.1056.0]

  3. ckpt進程每3s起來一次記錄checkpoint的進度到控制文件中,這種情況跟上面的類似,只不過在alert里面是看不到的,而且也不是每次喚醒都會寫控制文件的,而是有就記,沒有就拉倒。

  4. 類似于alter system switch logfile所產(chǎn)生的,先記錄下發(fā)出命令時刻的scn,ckpt進程不會推動DBWn去寫臟數(shù)據(jù),而是讓DBWn按照自己的狀態(tài)去寫臟數(shù)據(jù),等到寫到記錄的scn時,chpt進程再去更新控制文件和數(shù)據(jù)文件頭。這種情況在alert也能看到信息:Mon Aug  4 22:31:39 2008
    Beginning log switch checkpoint up to RBA [0x9.2.10], SCN: 534450
    Thread 1 advanced to log sequence 9
      Current log# 2 seq# 9 mem# 0: /u/app/oracle/oradata/orcl/redo02.log
    Mon Aug  4 22:35:58 2008
    Completed checkpoint up to RBA [0x9.2.10], SCN: 534450


參考文檔

  • Metalink: Automatic checkpoint Tuning

  • Metalink: checkpoint Tuning and Troubleshooting Guide

  • Metalink: 8i Parameters that Influence checkpoints

  • 《Oracle 9i&10G編程藝術》

  • 《checkpointing in Oracle》
    /files/Checkpointing_in_Oracle.pdf

  • Redo Byte Address (RBA)
    http://www.ixora.com.au/notes/rba.htm ]

  • 關于fast_start_io_target,log_checkpoint_interval,log_checkpoint_time的一點看法
    http://www.itpub.net/148219.html

  • Oracle 9i新特性研究系列之七
    http://oracle.chinaitlab.com/serial/18638.html

  • checkpoint說明
    http://airlgc.blog.51cto.com/161810/26175

  • Oracle checkpoint
    http://www.adp-gmbh.ch/ora/concepts/checkpoint.html


由于Oracle中LGWR和DBWR工作的不一致,Oracle引入了檢查點的概念,用于同步數(shù)據(jù)庫,保證數(shù)據(jù)庫的一致性。在Oracle里面,檢查點分為兩種:完全檢查點和增量檢查點。下面我們分別介紹這兩種檢查點的作用:


1、 完全檢查點

在Oracle8i之前,數(shù)據(jù)庫的發(fā)生的檢查點都是完全檢查點,完全檢查點會將數(shù)據(jù)緩沖區(qū)里面所有的臟數(shù)據(jù)塊寫入相應的數(shù)據(jù)文件中,并且同步數(shù)據(jù)文件頭和控制文件,保證數(shù)據(jù)庫的一致。完全檢查點在8i之后只有在下列兩種情況下才會發(fā)生:

(1、)DBA手工執(zhí)行alter system checkpoint的命令;

(2、)數(shù)據(jù)庫正常shutdown(immediate,transcational,normal)。

由于完全檢查點會將所有的臟數(shù)據(jù)庫塊寫入,巨大的IO往往會影響到數(shù)據(jù)庫的性能。因此Oracle從8i開始引入了增量檢查點的概念。


2、 增量檢查點
Oracle從8i開始引入了檢查點隊列這么一種概念,用于記錄數(shù)據(jù)庫里面當前所有的臟數(shù)據(jù)塊的信息,DBWR 根據(jù)這個隊列而將臟數(shù)據(jù)塊寫入到數(shù)據(jù)文件中。檢查點隊列按時間先后記錄著數(shù)據(jù)庫里面臟數(shù)據(jù)塊的信息,里面的條目包含RBA(Redo Block Address,重做日志里面用于標識檢查點期間數(shù)據(jù)塊在重做日志里面第一次發(fā)生更改的編號)和數(shù)據(jù)塊的數(shù)據(jù)文件號和塊號。在檢查點期間不論數(shù)據(jù)塊更改幾次,它在檢查點隊列里面的位置始終保持不變,檢查點隊列也只會記錄它最早的RBA,從而保證最早更改的數(shù)據(jù)塊能夠盡快寫入。當DBWR將檢查點隊列里面的臟數(shù)據(jù)塊寫入到數(shù)據(jù)文件后,檢查點的位置也要相應地往后移。

先看一下checkpoint queue(檢查點隊列)的概念,檢查點發(fā)生后,觸發(fā)DBWn進程,ckpt獲取發(fā)生檢查點時對應的scn,通知DBWn要寫到這個scn為止,DBWR與dirty buffer(臟數(shù)據(jù)緩沖區(qū))是根據(jù)數(shù)據(jù)塊被首次更改的時間順序?qū)懗龅?,也就是說,數(shù)據(jù)塊被更改后會進入一個檢查點隊列,DBWR進程就根據(jù)隊列的順序批量的寫入到數(shù)據(jù)文件中,寫到哪個數(shù)據(jù)塊時,那個數(shù)據(jù)塊的首次變化的scn就是當前所有數(shù)據(jù)文件block的最新scn,但是由于無法適時地的將dbwr進度記錄下來,所以oracle選擇了一些策略,其中就包括ckpt進程的檢查點和心跳。

  檢查點發(fā)生后,ckpt進程檢查checkpoint queue是否過長,如果是,則觸發(fā)dbwr,將一部分臟塊寫入數(shù)據(jù)文件,從而縮短checkpoint queue。

  checkpoint發(fā)生時,一方面通知dbwr進行下一批次的寫操作,另一方面,oracle采用了一個心跳的概念,以3秒的頻率將dbwr寫的進度反應到控制文件中,也就是把dbwr剛寫完的對應的數(shù)據(jù)塊的scn寫入數(shù)據(jù)文件頭和控制文件,這就是檢查點scn。這個3秒和增量檢查點不是一個概念,3秒只是在控制文件中,ckpt進程去更新dbwr寫到哪里了。這個對于ckpt進程來說叫做heartbeat(心跳)我們可以理解為每間隔3秒不停的檢查并記錄dbwr的進度。

檢查點發(fā)生之后數(shù)據(jù)庫的文件、控制處于一致狀態(tài)含義 是不需要 進行介質(zhì)恢復,只表示數(shù)據(jù)文件頭一致但是并不表示數(shù)據(jù)文件內(nèi)容一致,因為 數(shù)據(jù)文件內(nèi)容可能在沒有發(fā)生檢查點的 其它情況下dbwr 寫數(shù) 據(jù)文件,這樣數(shù)據(jù)文件內(nèi)容就不一致,若掉電需要進行崩潰恢復。

CKPT進程每三秒會在控制文件中記錄檢查點的位置,以表示Instance Recovery時開始恢復的日志條目,這個概念稱為檢查點的“心跳”(heartbeat)。檢查點位置發(fā)生變更后,Oracle里面通過4個參數(shù)用于控制檢查點位置和最后的重做日志條目之間的距離。在這里面需要指出的是,多數(shù)人會將這4個參數(shù)看作控制增量檢查點發(fā)生的時間。事實上這是錯誤的,這4個參數(shù)是用于控制檢查點隊列里面的條目數(shù)量,而不是控制檢查點的發(fā)生。

(1)、fast_start_io_target
該參數(shù)用于表示數(shù)據(jù)庫發(fā)生Instance Recovery的時候需要產(chǎn)生的IO總數(shù),它通過v$filestat的AVGIOTIM來估算的。比如我們一個數(shù)據(jù)庫在發(fā)生Instance Crash后需要在10分鐘內(nèi)恢復完畢,假定OS的IO每秒為500個,那么這個數(shù)據(jù)庫發(fā)生Instance Recovery的時候大概將產(chǎn)生500*10*60=30,000次IO,也就是我們將可以把fast_start_io_target設置為 30000。

(2)、fast_start_mttr_target
我們從上面可以看到fast_start_io_target來估算檢查點位置比較麻煩。Oracle為了簡化這個概念,從9i開始引入了 fast_start_mttr_target這么一個參數(shù),用于表示數(shù)據(jù)庫發(fā)生Instance Recovery的時間,以秒為單位。這個參數(shù)我們從字面上也比較好理解,其中的mttr是mean time to recovery的簡寫,如上例中的情況我們可以將fast_start_mttr_target設置為600。當設置了 fast_start_mttr_target后,fast_start_io_target這個參數(shù)將不再生效,從9i后 fast_start_io_target這個參數(shù)被Oracle廢除了。

v$instance_recovery.estimated_mttr 顯示當前估計需要恢復的秒數(shù)。這個值會 顯示即使 FAST_START_MTTR_TARGET 沒有被指定。 

v$instance_recovery.target_mttr 表明在短時間內(nèi) MTTR 的目標。 

v$mttr_target_advice顯示這個當前 顯示這個當前 MTTR 設置的 工作量產(chǎn)生I/O 數(shù)量和其他 I/O 。 這個視圖幫助用戶評定在優(yōu)化和恢復之前的平衡

(3)、log_checkpoint_timeout
該參數(shù)用于表示檢查點位置和重做日志文件末尾之間的時間間隔,以秒為單位,默認情況下是1800秒。

(4)、log_checkpoint_interval
該參數(shù)是表示檢查點位置和重做日志末尾的重做日志塊的數(shù)量,以OS塊表示。

(5)、90% OF SMALLEST REDO LOG
除了以上4個初始化參數(shù)外,Oracle內(nèi)部事實上還將重做日志文件末尾前面90%的位置設為檢查點位置。在每個重做日志中,這么幾個參數(shù)指定的位置可能不盡相同,Oracle將離日志文件末尾最近的那個位置確認為檢查點位置。

oracle 9i instance recovery
1. 增量檢查點
在checkpoint queue的基礎上實現(xiàn)了增量檢查點,每3秒發(fā)生一次checkpoint heartbeat,記錄dbwr上次寫成功的最大RBA(redo block address)。這樣的話做instance recovery的時候就從這個rba開始,而不是從上次checkpoint scn開始,大大節(jié)省了恢復時間。
 
2. twice scan of redo log
在應用redo之前,redo將會被操作兩次,第一次去掃描哪些redo record需要被應用,因為9i在redo里添加了dbwr寫數(shù)據(jù)塊的信息,所以dbwr發(fā)生前的日志將不會被應用。第二步就是選出需要被應用的日志然后開始rollforward。
 
3. rollforward
在做instance recovery時必須先定位到redo log 然后應用所有日志到datafile,這時候包括了committed和uncommitted的數(shù)據(jù)。當做完rollward,數(shù)據(jù)庫就可以open了。
 
4. rollback
因 為rollforward產(chǎn)生了uncommitted數(shù)據(jù),所以必須回滾這些數(shù)據(jù)。這將由smon和on-demand rollback來實現(xiàn)。smon將會掃描undo segment header去標志所有活動事務為dead,然后會逐漸去回滾這些事務。另外on-demand rollback提供了前臺進程進行rollback,當前臺進程企圖獲得被dead事務占用row lock,這時候前臺進程將會去undo segment取得before image去回滾這個塊,至于其他被這個dead事務lock的塊就等待smon去回滾。
 
另外,如果 在數(shù)據(jù)庫打開的過程中process crash導致transaction dead,resource不能被釋放的情況,這時候如果另一個進程需要這些resource,那么這個進程將會等待直到pmon清理dead process釋放出resource。

如果數(shù)據(jù)庫Crash,重新啟動,很久遠以前的未提交事務并不在Redo的恢復序列中。
但是未提交事務一定在回滾段事務表上存在,并且State=10,為活動事務。這就夠了。

數(shù)據(jù)庫啟動之后,這些事務會被SMON逐個標記為Dead(不可能再活過來了),然后由SMON慢慢去回滾這些事務;也存在另外一種情況,后來的進程會去讀這些未提交數(shù)據(jù),發(fā)現(xiàn)Dead事務未提交,則主動進行回滾。

1. 一個數(shù)據(jù)塊發(fā)生更新,必然寫回滾
2. 回滾段的block變化也記錄在redo中

一份未提交的數(shù)據(jù)必定在回滾中有相應的前鏡像,任何正常的恢復都一定會把這些變化重新構(gòu)建出來。


想像一下

1. update事務1更新了block 1
2. 回滾段1記錄了block1的前鏡像
3. checkpoint
4. update事務2更新了block2
5. 回滾段2記錄了block2的前鏡像
6. instance crash

現(xiàn)在重啟數(shù)據(jù)庫

1. 根據(jù)redo重新構(gòu)建block2
2. 根據(jù)redo重新構(gòu)建回滾段2
3. database open
4. SMON用回滾段2的數(shù)據(jù)回滾block2,SMON用回滾段1的數(shù)據(jù)回滾block1

最后一步也可能是
在另外一個select檢索到block1或者block2的時候,發(fā)現(xiàn)這兩個block的數(shù)據(jù)都是未提交的,此時再回滾block1和block2。

所以,只要有相應的回滾數(shù)據(jù)存在,無論什么時候oracle都可以找到一致的數(shù)據(jù),oracle只需要知道這個事務是提交了的還是沒提交了的,而這點在block header ITL中有記錄。

  http://spaces.msn.com/roujiaweize/blog/cns!9745F14B4AEB3B72!328.entry




oracle之檢查點(Checkpoint)

檢查點是一個數(shù)據(jù)庫事件,它把修改的數(shù)據(jù)從高速緩存寫入磁盤,并更新控制文件和數(shù)據(jù)文件。


檢查點分為三類
1)局部檢查點:單個實例執(zhí)行數(shù)據(jù)庫所有數(shù)據(jù)文件的一個檢查點操作,屬于此實例的全部臟緩存區(qū)寫入數(shù)據(jù)文件。
觸發(fā)命令:
svmrgrl>alter system checkpoint local;
這條命令顯示的觸發(fā)一個局部檢查點。


2)全局檢查點:所有實例(對應并行數(shù)據(jù)服務器)執(zhí)行數(shù)據(jù)庫所有數(shù)據(jù)文件的一個檢查點操作,屬于此實例的全部臟緩存區(qū)寫入數(shù)據(jù)文件。
觸發(fā)命令
svrmgrl>alter system checkpoint global;
這條命令顯示的觸發(fā)一個全局檢查點。


3)文件檢查點:所有實例需要執(zhí)行數(shù)據(jù)文件集的一個檢查點操作,如使用熱備份命令alter tablespace USERS begin backup,或表空間脫機命令alter tablespace USERS offline,將執(zhí)行屬于USERS表空間的所有數(shù)據(jù)文件的一個檢查點操作。


檢查點處理步驟:
1)獲取實例狀態(tài)隊列:實例狀態(tài)隊列是在實例狀態(tài)轉(zhuǎn)變時獲得,ORACLE獲得此隊列以保證檢查點執(zhí)行期間,數(shù)據(jù)庫處于打開狀態(tài);
2)獲取當前檢查點信息:獲取檢查點記錄信息的結(jié)構(gòu),此結(jié)構(gòu)包括當前檢查點時間、活動線程、進行檢查點處理的當前線程、日志文件中恢復截止點的地址信息;
3)緩存區(qū)標識:標識所有臟緩存區(qū),當檢查點找到一個臟緩存區(qū)就將其標識為需進行刷新,標識的臟緩存區(qū)由系統(tǒng)進程DBWR進行寫操作,將臟緩存區(qū)的內(nèi)容寫入數(shù)據(jù)文件;
4)臟緩存區(qū)刷新:DBWR進程將所有臟緩存區(qū)寫入磁盤后,設置一標志,標識已完成臟緩存區(qū)至磁盤的寫入操作。系統(tǒng)進程LGWR與CKPT進程將繼續(xù)進行檢查,直至DBWR進程結(jié)束為止;
5)更新控制文件與數(shù)據(jù)文件。
注:控制文件與數(shù)據(jù)文件頭包含檢查點結(jié)構(gòu)信息。
在兩種情況下,文件頭中的檢查點信息(獲取當前檢查點信息時)將不做更新:
1)數(shù)據(jù)文件不處于熱備份方式,此時ORACLE將不知道操作系統(tǒng)將何時讀文件頭,而備份拷貝在拷貝開始時必須具有檢查點SCN;
ORACLE在數(shù)據(jù)文件頭中保留一個檢查點的記數(shù)器,在正常操作中保證使用數(shù)據(jù)文件的當前版本,在恢復時防止恢復數(shù)據(jù)文件的錯誤版本;即使在熱備份方式下,計數(shù)器依然是遞增的;每個數(shù)據(jù)文件的檢查點計數(shù)器,也保留在控制文件相對應數(shù)據(jù)文件項中。
2)檢查SCN小于文件頭中的檢查點SCN的時候,這表明由檢查點產(chǎn)生的改動已經(jīng)寫到磁盤上,在執(zhí)行全局檢查點的處理過程中,如果一個熱備份快速檢查點在更新文件頭時,則可能發(fā)生此種情況。應該注意的是,ORACLE是在實際進行檢查點處理的大量工作之前捕獲檢查SCN的,并且很有可能被一條象熱備份命令alter tablespace USERS begin backup進行快速檢查點處理時的命令打斷。
ORACLE在進行數(shù)據(jù)文件更新之前,將驗證其數(shù)據(jù)一致性,當驗證完成,即更新數(shù)據(jù)文件頭以反映當前檢查點的情況;未經(jīng)驗證的數(shù)據(jù)文件與寫入時出現(xiàn)錯誤的數(shù)據(jù)文件都被忽略;如果日志文件被覆蓋,則這個文件可能需要進行介質(zhì)恢復,在這種情況下,ORACLE系統(tǒng)進程DBWR將此數(shù)據(jù)文件脫機。
檢 查點算法描述:
臟緩存區(qū)用一個新隊列鏈接,稱為檢查點隊列。對緩存區(qū)的每一個改動,都有一個與其相關的重做值。檢查點隊列包含臟的日志緩存區(qū),這些緩存區(qū)按照它們在日志文件中的位置排序,即在檢查點隊列中,緩存區(qū)按照它們的低重做值進行排序。需要注意的是,由于緩存區(qū)是依照第一次變臟的次序鏈接到隊列中的,所以,如果在緩存區(qū)寫出之前對它有另外的改動,鏈接不能進行相應變更,緩存區(qū)一旦被鏈接到檢查點隊列,它就停留在此位置,直到將它被寫出為止。
ORACLE系統(tǒng)進程DBWR在響應檢查點請求時,按照這個隊列的低重做值的升序?qū)懗鼍彺鎱^(qū)。每個檢查點請求指定一個重做值,一旦DBWR寫出的緩存區(qū)重做值等于或大雨檢查點的重做值,檢查點處理即完成,并將記錄到控制文件與數(shù)據(jù)文件。
由于檢查點隊列上的緩存區(qū)按照低重做值進行排序,而DBWR也按照低重做值順序?qū)懗鰴z查點緩存區(qū),故可能有多個檢查點請求處于活動狀態(tài),當DBWR寫出緩存區(qū)時,檢查位于檢查點隊列前端的緩存區(qū)重做值與檢查點重做值的一致性,如果重做值小于檢查點隊列前緩存區(qū)的低重做值的所有檢查點請求,即可表示處理完成。當存在未完成的活動檢查點請求時,DBWR繼續(xù)寫出檢查點緩存區(qū)。
算法特點:
1)DBWR能確切的知道為滿足檢查點請求需要寫那些緩存區(qū);
2)在每次進行檢查點寫時保證指向完成最早的(具有最低重做值的)檢查點;
3)根據(jù)檢查點重做值可以區(qū)別多個檢查點請求,然后按照它們的順序完成處理。

1.檢查點(Checkpoint)的本質(zhì)

許多文檔把Checkpint描述得非常復雜,為我們正確理解檢查點帶來了障礙,結(jié)果現(xiàn)在檢查點變成了一個非常復雜的問題。實際上,檢查點只是一個數(shù)據(jù)庫事件,它存在的根本意義在于減少崩潰恢復(Crash Recovery)時間。

當修改數(shù)據(jù)時,需要首先將數(shù)據(jù)讀入內(nèi)存中(Buffer Cache),修改數(shù)據(jù)的同時,Oracle會記錄重做信息(Redo)用于恢復。因為有了重做信息的存在,Oracle不需要在提交時立即將變化的數(shù)據(jù)寫回磁盤(立即寫的效率會很低),重做(Redo)的存在也正是為了在數(shù)據(jù)庫崩潰之后,數(shù)據(jù)就可以恢復。

最常見的情況,數(shù)據(jù)庫可以因為斷電而Crash,那么內(nèi)存中修改過的、尚未寫入文件的數(shù)據(jù)將會丟失。在下一次數(shù)據(jù)庫啟動之后,Oracle可以通過重做日志(Redo)進行事務重演,也就是進行前滾,將數(shù)據(jù)庫恢復到崩潰之前的狀態(tài),然后數(shù)據(jù)庫可以打開提供使用,之后Oracle可以將未提交的數(shù)據(jù)進行回滾。

在這個過程中,通常大家最關心的是數(shù)據(jù)庫要經(jīng)歷多久才能打開。也就是需要讀取多少重做日志才能完成前滾。當然用戶希望這個時間越短越好,Oracle也正是通過各種手段在不斷優(yōu)化這個過程,縮短恢復時間。

檢查點的存在就是為了縮短這個恢復時間。

當檢查點發(fā)生時(此時的SCN被稱為CheckPoint SCN),Oracle會通知DBWR進程,把修改過的數(shù)據(jù),也就是Checkpoint SCN之前的臟數(shù)據(jù)(Dirty Data)從Buffer Cache寫入磁盤,當寫入完成之后,CKPT進程更新控制文件和數(shù)據(jù)文件頭,記錄檢查點信息,標識變更。

Oracle SCN的相關知識可以參考我的另外一篇文章: DBA入門之認識Oracle SCN(System Change Number)

Checkpoint SCN可以從數(shù)據(jù)庫中查詢得到:

SQL> select file#,CHECKPOINT_CHANGE#,to_char(CHECKPOINT_TIME,'yyyy-mm-dd hh34:mi:ss') cpt from v$datafile;

FILE# CHECKPOINT_CHANGE# CPT

---------- ------------------ -------------------
1 913306 2011-11-16 16:06:06

2 913306 2011-11-16 16:06:06

3 913306 2011-11-16 16:06:06

4 913306 2011-11-16 16:06:06

SQL> select dbid,CHECKPOINT_CHANGE# from v$database;

DBID CHECKPOINT_CHANGE#

---------- ------------------
1294662348 913306

在檢查點完成之后,此檢查點之前修改過的數(shù)據(jù)都已經(jīng)寫回磁盤,重做日志文件中的相應重做記錄對于崩潰/實例恢復不再有用。

下圖標記了3個日志組,假定在T1時間點,數(shù)據(jù)庫完成并記錄了最后一次檢查點,在T2時刻數(shù)據(jù)庫Crash。那么在下次數(shù)據(jù)庫啟動時,T1時間點之前的Redo不再需要進行恢復,Oracle需要重新應用的就是時間點T1至T2之間數(shù)據(jù)庫生成的重做日志(Redo)。

上圖可以很輕易地看出來,檢查點的頻率對于數(shù)據(jù)庫的恢復時間具有極大的影響,如果檢查點的頻率高,那么恢復時需要應用的重做日志就相對得少,檢查時間就可以縮短。然而,需要注意的是,數(shù)據(jù)庫內(nèi)部操作的相對性極強,國語平凡的檢查點同樣會帶來性能問題,尤其是更新頻繁的數(shù)據(jù)庫。所以數(shù)據(jù)庫的優(yōu)化是一個系統(tǒng)工程,不能草率。

更進一步可以知道,如果Oracle可以在性能允許的情況下,使得檢查點的SCN主鍵逼近Redo的最新更新,那么最終可以獲得一個最佳平衡點,使得Oracle可以最大化地減少恢復時間。

為了實現(xiàn)這個目標,Oracle在不同版本中一直在改進檢查點的算法。

2.常規(guī)檢查點與增量檢查點

為了區(qū)分,在Oracle8之前,Oracle實時的檢查點通常被稱為常規(guī)檢查點(Conventional Checkpoint),這類檢查點按一定的條件出發(fā)(log_checkpoint_interval、log_checkpoint_timeout參數(shù)設置及l(fā)og switch等條件出發(fā))。

從Oracle 8開始,Oracle引入了增量檢查點(Inctrmental Checkpoint)的概念。

和以前的版本相比,在新版本中,Oracle主要引入了檢查點隊列(Checkpoinnt Queue)機制,在數(shù)據(jù)庫內(nèi)部,每一個臟數(shù)據(jù)塊都會被移動到檢查點隊列,按照Low RBA的順序(第一次對比數(shù)據(jù)塊修改對應的Redo Byte Address)來排列,如果一個數(shù)據(jù)塊進行過多次修改,該數(shù)據(jù)庫在檢查點隊列上的順序并不會發(fā)生變化。

當執(zhí)行檢查點時,DBWR從檢查點隊列按照Low RBA的順序?qū)懗?,實例檢查點因此可以不斷增進、階段性的,CKPT進程使用非常輕量級的控制文件更新協(xié)議,將當前的最低RBA寫入控制文件。

因為增量檢查點可以連續(xù)地進行,因此檢查點RBA可以比常規(guī)檢查點更接近數(shù)據(jù)庫的最后狀態(tài),從而在數(shù)據(jù)庫的實例恢復中可以極大地減少恢復時間。

而且,通過增量檢查點,DBWR可以持續(xù)進行寫出,從而避免了常規(guī)檢查點出發(fā)的峰值寫入對于I/O的國度征用,通過下圖可以清楚地看到這一改進的意義。

在數(shù)據(jù)庫中,增量檢查點是通過Fast-Start Checkpointing特性來實現(xiàn)的,從Oracle 8i開始,這一特性包含了Oracle企業(yè)版的Fast-Start Fault Recovery組件之中,通過查詢v$option視圖,了解這一特性:

SQL>select*from v$version where rownum<2;

BANNER

----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4. – Prod

SQL> col parameter for a30

SQL> col value for a20

SQL>select*from V$optionwhere Parameter='Fast-Start Fault Recovery';

PARAMETER VALUE

------------------------------ --------------------
Fast-Start Fault Recovery TRUE

該組件包含3個主要特性,可以加快系統(tǒng)在故障后的恢復,提高系統(tǒng)的可用性。

Fast-Start Checkpointing;

Fast-Start On-Demand Rollback;

Fast-Start Parallel Rollback;

Fast-Start Checkpointing 特性在Oracle 8i中主要通過參數(shù)FAST_START_IO_TARGET來實現(xiàn),在Oracle 9i中,F(xiàn)ast-Start Checkpointing主要通過參數(shù)FAST_START_MTTR_TARGET來實現(xiàn)。

3.FAST_START_MTTR_TARGET

FAST_START_MTTR_TARGET參數(shù)從Oracle 9i開始被引入,該參數(shù)定義數(shù)據(jù)庫進行Crash恢復的時間,單位是秒,取值范圍是在0~3600秒之間。

在Oracle 9i中,Oracle推薦設置這個參數(shù)代替FAST_START_IO_TARGE、LOG_CHECKPOINT_TIMEROUT及LOG_CHECKPOINT_INSTERVAL參數(shù)。

缺省情況下,在Oracle 9i中,F(xiàn)AST_START_IO_TARGET和LOG_CHECKPOINT_INTERVAL參數(shù)已經(jīng)被設置為0.

SQL> show parameter fast_start_io

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------
fast_start_io_target integer 

SQL> show parameter interval

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------
log_checkpoint_interval integer 

在Oracle 9i R2開始,Oracle引入了一個新的視圖提供MTTR建議:

SQL> select * from v$mttr_target_advice;

MTTR_TARGET_FOR_ESTIMATE ADVICE_STATUS DIRTY_LIMIT ESTD_CACHE_WRITES ESTD_CACHE_WRITE_FACTOR ESTD_TOTAL_WRITES ESTD_TOTAL_WRITE_FACTOR ESTD_TOTAL_IOS ESTD_TOTAL_IO_FACTOR

------------------------ ------------- ----------- ----------------- ----------------------- ----------------- ----------------------- -------------- --------------------

該視圖評估在不同F(xiàn)AST_START_MATTR_TARGET設置下,系統(tǒng)需要執(zhí)行的I/O次數(shù)等操作。用戶可以根據(jù)數(shù)據(jù)庫的建議,對FAST_START_MTTR_TARGET進行相應調(diào)整。

這個建議信息的手機收到Oracle 9i新引入的初始化參數(shù)statistics_level的控制,當該參數(shù)設置為Typical或ALL時,MTTR建議信息被手機:

SQL> show parameter statistics_level

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------
statistics_level string TYPICAL

也可以通過v$statistics_level視圖來查詢MTTR_Advice的當前設置:

SQL> select * from v$statistics_level where STATISTICS_NAME='MTTR Advice';

STATISTICS_NAME DESCRIPTION SESSION_STATUS SYSTEM_STATUS ACTIVATION_LEVEL STATISTICS_VIEW_NAME SESSION_SETTABLE

---------------------------------------------------------------- -------------------------------------------------------------------------------- -------------- ------------- ---------------- ---------------------------------------------------------------- ----------------
MTTR Advice Predicts the impact of different MTTR settings on number of physical I/Os ENABLED ENABLED TYPICAL V$MTTR_TARGET_ADVICE NO

數(shù)據(jù)庫當前的實例恢復狀態(tài)可以通過視圖v$instance_recovery查詢得到:

SQL> select * from v$instance_recovery;

RECOVERY_ESTIMATED_IOS 53

ACTUAL_REDO_BLKS 376

TARGET_REDO_BLKS 184320

LOG_FILE_SIZE_REDO_BLKS 184320

LOG_CHKPT_TIMEOUT_REDO_BLKS

LOG_CHKPT_INTERVAL_REDO_BLKS

FAST_START_IO_TARGET_REDO_BLKS

TARGET_MTTR 

ESTIMATED_MTTR 18

CKPT_BLOCK_WRITES 27

OPTIMAL_LOGFILE_SIZE

ESTD_CLUSTER_AVAILABLE_TIME

WRITES_MTTR 

WRITES_LOGFILE_SIZE 

WRITES_LOG_CHECKPOINT_SETTINGS 

WRITES_OTHER_SETTINGS 

WRITES_AUTOTUNE 104

WRITES_FULL_THREAD_CKPT 

從v$instance_recovery視圖,可以看到當前數(shù)據(jù)庫估計的平均恢復時間(MTTR)參數(shù):ESTIMATED_MTTR。

ESTIMATED_MTTR的估算值是基于Dirty Buffer 的數(shù)據(jù)量和日志塊數(shù)量得出的,這個參數(shù)值告訴我們,如果此時數(shù)據(jù)庫本虧,那么進行實例恢復將會需要的時間。

在V$instance_revovery視圖中,TARGET_MTTR代表的是期望的恢復時間,通常改參數(shù)應該等于FAST_START_MTTR_TARGET參數(shù)設置值(但是如果FAST_START_MTTR_TARGET參數(shù)定義的值極大或極小,TARGET_MEER可能不等于FAST_START_MTTR_TARGET的設置)。

當ESTIMATED_MTTR接近或超過FAST_START_MTTR_TARGET參數(shù)設置(v$instance_recovery TARGET_MTTR)時,系統(tǒng)就會促發(fā)檢查點,執(zhí)行寫出之后,系統(tǒng)恢復信息將會重新計算:

View Code

RECOVERY_ESTIMATED_IOS 24

ACTUAL_REDO_BLKS 43

TARGET_REDO_BLKS 184320

LOG_FILE_SIZE_REDO_BLKS 184320

LOG_CHKPT_TIMEOUT_REDO_BLKS

LOG_CHKPT_INTERVAL_REDO_BLKS

FAST_START_IO_TARGET_REDO_BLKS

TARGET_MTTR 

ESTIMATED_MTTR 18

CKPT_BLOCK_WRITES 73

OPTIMAL_LOGFILE_SIZE

ESTD_CLUSTER_AVAILABLE_TIME

WRITES_MTTR 

WRITES_LOGFILE_SIZE 

WRITES_LOG_CHECKPOINT_SETTINGS 

WRITES_OTHER_SETTINGS 

WRITES_AUTOTUNE 183

WRITES_FULL_THREAD_CKPT 

在繁忙的系統(tǒng)中,可能會觀察到ESTIMATED_MTTR>TARGET_MTTR,這可能是因為DBWR正忙于寫出,甚或出現(xiàn)Checkpoint不能及時完成的情況。

4. Oracle 10g自動檢查點調(diào)整

從Oracle 10g開始,數(shù)據(jù)庫可以實現(xiàn)自動調(diào)整的檢查點,使用自動調(diào)整的檢查點,Oracle數(shù)據(jù)庫可以利用系統(tǒng)的低I/O負載時段寫出內(nèi)存中的臟數(shù)據(jù),從而提高數(shù)據(jù)庫的效率。因此,即使數(shù)據(jù)庫管理員設置了不合理的檢查點相關參數(shù),Oracle仍然能夠通過自動調(diào)整將數(shù)據(jù)庫的Crash Recovery時間控制在合理的范圍之內(nèi)。

當FAST_START_MTTR_TARGET參數(shù)未設置,自動檢查點調(diào)整生效。

通常,如果必須嚴格控制實例或節(jié)點恢復時間,那么可以設置FAST_START_MTTR_TARGET為期望時間值;如果恢復時間不嚴格控制,那么可以不設置FAST_START_MTTR_TARGET參數(shù),從而啟用Oracle 10g的自動調(diào)整特性。

當取消FAST_START_MTTR_TARGET參數(shù)設置之后:

SQL> show parameter fast_start_mttr

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------
fast_start_mttr_target integer 

在啟動數(shù)據(jù)庫的時候,可以從alter文件中看到如下信息:

View Code

Thu Nov 17 20:27:23 2011

MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set

檢查v$instance_recovery視圖,可以發(fā)現(xiàn)Oracle 10g的改變:

View Code

SQL> select * from v$instance_recovery;

RECOVERY_ESTIMATED_IOS 53

ACTUAL_REDO_BLKS 376

TARGET_REDO_BLKS 184320

LOG_FILE_SIZE_REDO_BLKS 184320

LOG_CHKPT_TIMEOUT_REDO_BLKS

LOG_CHKPT_INTERVAL_REDO_BLKS

FAST_START_IO_TARGET_REDO_BLKS

TARGET_MTTR 

ESTIMATED_MTTR 18

CKPT_BLOCK_WRITES 27

OPTIMAL_LOGFILE_SIZE

ESTD_CLUSTER_AVAILABLE_TIME

WRITES_MTTR 

WRITES_LOGFILE_SIZE 

WRITES_LOG_CHECKPOINT_SETTINGS 

WRITES_OTHER_SETTINGS 

WRITES_AUTOTUNE 104

WRITES_FULL_THREAD_CKPT 

在以上視圖中,WRITES_AUTOTUNE字段數(shù)據(jù)就是指由于自動調(diào)整檢查點執(zhí)行的寫出次數(shù),而CK_BLOCK_WRITES指的則是由于檢查點寫出的Block的數(shù)量。

關于檢查點的機制問題,我們側(cè)重介紹了原理,至于具體的算法實現(xiàn),不需要去追究過多,只要明白了這個原理性的規(guī)則,理解Oracle就會變成輕松的事情。

Oracle的算法改進是一種優(yōu)化,對于數(shù)據(jù)庫的調(diào)整優(yōu)化也不外如此,借鑒Oracle的優(yōu)化對于理解和優(yōu)化Oracle數(shù)據(jù)庫都具有極大的好處。

5.從控制文件獲取檢查點信息

在控制文件的轉(zhuǎn)儲中,可以看到關于檢查點進程進度的記錄:

View Code

***************************************************************************

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:34

low cache rba:(0x23.19d5.0) on disk rba:(0x23.1a68.0)

on disk scn: 0x0000.000d847d 11/14/2011 15:25:37

resetlogs scn: 0x0000.0006ce7b 11/10/2011 22:40:23

heartbeat: 767211774 mount id: 1294947385

THREAD #2 - status:0x0 flags:0x0 dirty:0

low cache rba:(0x0.0.0) on disk rba:(0x0.0.0)

這里的low cache rba(Revovery block address)指在Cache中,最低的RBA地址,在實例恢復或者崩潰恢復中,需要從這里開始恢復。

On disk rba是磁盤上的最高的重做值,在進行恢復時應用重做至少要達到這個值。

除了檢查點隊列(CKPTQ)之外,數(shù)據(jù)庫中還存在另外一個隊列和檢查點有關,這就是文件檢查點隊列(FILE QUEUE),通常稱為FILEQ,文件檢查點的引入提供了表空間相關的檢查點的性能。每個Dirty  Buffer同時鏈接到這兩個隊列,CKPTQ包含實例所有需要執(zhí)行檢查點的Buffer,F(xiàn)ILEQ包含屬于特定文件需要執(zhí)行的檢查點Buffer,每個文件都包含一個文件隊列,在執(zhí)行表空間檢查點請求時需要使用FILEQ,通常當對表空間執(zhí)行Offline等操作時會觸發(fā)表空間檢查點。CKPTQ和FILEQ都是雙向鏈表,每個隊列中都記錄了兩個地址信息,分別是前一塊和下一塊Buffer的地址信息。注意只有Dirty Buffer才會包含CKPTQ信息,否則為NULL,信息類似"ckptq:[NULL]fileq:[NULL]"。

檢查點(checkpoint)的工作機制

檢查點是一個數(shù)據(jù)庫事件,它把修改數(shù)據(jù)從高速緩存寫入磁盤,并更新控制文件和數(shù)據(jù)文件,總結(jié)起來如下:檢查點分為三類:1)局部檢查點:單個實例執(zhí)行數(shù)據(jù)庫所有數(shù)據(jù)文件的一個檢查點操作,屬于此實例的全部臟緩存區(qū)寫入數(shù)據(jù)文件。觸發(fā)命令:svmrgrl>alter  system checkpoint local;這條命令顯示的觸發(fā)一個局部檢查點。2)全局檢查點:所有實例(對應并行數(shù)據(jù)服務器)執(zhí)行數(shù)據(jù)庫所有所有數(shù)據(jù)文件的一個檢查點操作,屬于此實例的全部臟緩存區(qū)寫入數(shù)據(jù)文件。觸發(fā)命令svrmgrl>alter system checkpoint global;這條命令顯示的觸發(fā)一個全局檢查點。3)文件檢查點:所有實例需要執(zhí)行數(shù)據(jù)文件集的一個檢查點操作,如使用熱備份命令alter   tablespace USERS begin backup,或表空間脫機命令alter tablespace USERS offline,將執(zhí)行屬于USERS表空間的所有數(shù)據(jù)文件的一個檢查點操作。檢查點處理步驟:1)獲取實例狀態(tài)隊列:實例狀態(tài)隊列是在實例狀態(tài)轉(zhuǎn)變時獲得,ORACLE獲得此隊列以保證檢查點執(zhí)行期間,數(shù)據(jù)庫處于打開狀態(tài);2)獲取當前檢查點信息:獲取檢查點記錄信息的結(jié)構(gòu),此結(jié)構(gòu)包括當前檢查點時間、活動線程、進行檢查點處理的當前線程、日志文件中恢復截止點的地址信息;3)緩存區(qū)標識:當數(shù)據(jù)在buffer cache中做了修改之后會自動被為臟緩沖區(qū),加入到Checkpoint Queue的臟緩沖區(qū)隊列。

4)臟緩存區(qū)刷新:當檢查點發(fā)生時,會到CKPTQ中的臟緩沖區(qū)隊列找到到目前為止最大的LRBA,并通知DBWR進程將所有臟緩存區(qū)寫入磁盤,完成之后設置一標志,標識已完成臟緩存區(qū)至磁盤的寫入操作,以便刷新臟緩沖隊列(此時DML可以繼續(xù)進行)。系統(tǒng)進程LGWR與CKPT進程將繼續(xù)進行檢查,直至DBWR進程結(jié)束為止;

5)更新控制文件與數(shù)據(jù)文件。注:控制文件與數(shù)據(jù)文件頭包含檢查點結(jié)構(gòu)信息。在兩種情況下,文件頭中的檢查點信息(獲取當前檢查點信息時)將不做更新:1)數(shù)據(jù)文件不處于熱備份方式,此時ORACLE將不知道操作系統(tǒng)將何時讀文件頭,而備份拷貝在拷貝開始時必須具有檢查點SCN;ORACLE在數(shù)據(jù)文件頭中保留一個檢查點的記數(shù)器,在正常操作中保證使用數(shù)據(jù)文件的當前版本,在恢復時防止恢復數(shù)據(jù)文件的錯誤版本;即使在熱備份方式下,計數(shù)器依然是遞增的;每個數(shù)據(jù)文件的檢查點計數(shù)器,也保留在控制文件相對應數(shù)據(jù)文件項中。2)檢查SCN小于文件頭中的檢查點SCN的時候,這表明由檢查點產(chǎn)生的改動已經(jīng)寫到磁盤上,在執(zhí)行全局檢查點的處理過程中,如果一個熱備份快速檢查點在更新文件頭時,則可能發(fā)生此種情況。應該注意的是,ORACLE是在實際進行檢查點處理的大量工作之前捕獲檢查SCN的,并且很有可能被一條象熱備份命令 alter tablespace USERS begin backup進行快速檢查點處理時的命令打斷。ORACLE在進行數(shù)據(jù)文件更新之前,將驗證其數(shù)據(jù)一致性,當驗證完成,即更新數(shù)據(jù)文件頭以反映當前檢查點的情況;未經(jīng)驗證的數(shù)據(jù)文件與寫入時出現(xiàn)錯誤的數(shù)據(jù)文件都被忽略;如果日志文件被覆蓋,則這個文件可能需要進行介質(zhì)恢復,在這種情況下,ORACLE系統(tǒng)進程DBWR將此數(shù)據(jù)文件脫機。檢查點算法描述:臟緩存區(qū)用一個新隊列鏈接,稱為檢查點隊列。對緩存區(qū)的每一個改動,都有一個與其相關的重做值。檢查點隊列包含臟的日志緩存區(qū),這些緩存區(qū)按照它們在日志文件中的位置排序,即在檢查點隊列中,緩存區(qū)按照它們的LRBA進行排序。需要注算法特點:3)根據(jù)檢查點重做值可以區(qū)別多個檢查點請求,然后按照它們的順序完成處理。1)DBWR能確切的知道為滿足檢查點請求需要寫那些緩存區(qū);2)在每次進行檢查點寫時保證指向完成最早的(具有最低重做值的)檢查點;意的是,由于緩存區(qū)是依照第一次變臟的次序鏈接到隊列中的,所以,如果在緩存區(qū)寫出之前對它有另外的改動,鏈接不能進行相應變更,緩存區(qū)一旦被鏈接到檢查點隊列,它就停留在此位置,直到將它被寫出為止。ORACLE系統(tǒng)進程DBWR在響應檢查點請求時,按照這個隊列的LRBA的升序?qū)懗鼍彺鎱^(qū)。每個檢查點請求指定一個重做值,一旦DBWR寫出的緩存區(qū)重做值等于或大雨檢查點的重做值,檢查點處理即完成,并將記錄到控制文件與數(shù)據(jù)文件。由于檢查點隊列上的緩存區(qū)按照低重做值進行排序,而DBWR也按照低重做值順序?qū)懗鰴z查點緩存區(qū),故可能有多個檢查點請求處于活動狀態(tài),當DBWR寫出緩存區(qū)時,檢查位于檢查點隊列前端的緩存區(qū)重做值與檢查點重做值的一致性,如果重做值小于檢查點隊列前緩存區(qū)的低重做值的所有檢查點請求,即可表示處理完成。當存在未完成的活動檢查點請求時,DBWR繼續(xù)寫出檢查點緩存區(qū)。



增量檢查點如何更新控制文件

原文:http://www.askmaclean.com/archives/incremental-checkpoint-update-controlfile.html

Know more about checkpoint

checkpoint 分成很多種 full 、file、thread、parallel query、 object 、incremental 、logfile switch

每一種checkpoint 都有其自身的特性,例如Incremental Checkpoint會要求ckpt 每3s 更新一次controlfile 但是不更新datafile header, 而FULL CHECKPOINT要求立即完成(同步的) 且會同時更新 controlfile 和 datafile header。

Incremental Checkpoint會要求ckpt 每3s 更新一次controlfile
>>我想問的時:如何查看此時控制文件中更新的SCN?除了DUMP控制文件,有沒有命令查詢?

我希望通過以下演示說明該問題:

SQL> select * from v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi PL/SQL Release 10.2.0.5.0 - Production CORE    10.2.0.5.0      Production TNS for Linux: Version 10.2.0.5.0 - Production NLSRTL Version 10.2.0.5.0 - Production SQL> oradebug setmypid; Statement processed. SQL> oradebug dump controlf 4; Statement processed. SQL> oradebug tracefile_name ; /s01/admin/G10R25/udump/g10r25_ora_4660.trc 另開一個窗口等待6s在做一次controlf DUMP  SQL>  exec dbms_lock.sleep(6); oradebug setmypid; oradebug dump controlf 4; oradebug tracefile_name ;  PL/SQL procedure successfully completed. SQL> Statement processed. SQL> Statement processed. SQL> /s01/admin/G10R25/udump/g10r25_ora_4663.trc

比較以上獲得的2個前后有6s間隔的CONTROLFILE DUMP 文件:

[oracle@vrh8 udump]$ diff /s01/admin/G10R25/udump/g10r25_ora_4660.trc /s01/admin/G10R25/udump/g10r25_ora_4663.trc 1c1 < /s01/admin/G10R25/udump/g10r25_ora_4660.trc --- > /s01/admin/G10R25/udump/g10r25_ora_4663.trc 13c13 < Unix process pid: 4660, image: oracle@vrh8.oracle.com (TNS V1-V3) --- > Unix process pid: 4663, image: oracle@vrh8.oracle.com (TNS V1-V3) 15,18c15,19 < *** ACTION NAME:() 2012-07-22 07:59:08.215 < *** MODULE NAME:(sqlplus@vrh8.oracle.com (TNS V1-V3)) 2012-07-22 07:59:08.215 < *** SERVICE NAME:(SYS$USERS) 2012-07-22 07:59:08.215 < *** SESSION ID:(159.7) 2012-07-22 07:59:08.215 --- > *** 2012-07-22 07:59:31.779 > *** ACTION NAME:() 2012-07-22 07:59:31.779 > *** MODULE NAME:(sqlplus@vrh8.oracle.com (TNS V1-V3)) 2012-07-22 07:59:31.779 > *** SERVICE NAME:(SYS$USERS) 2012-07-22 07:59:31.779 > *** SESSION ID:(159.9) 2012-07-22 07:59:31.779 96,98c97,99 < THREAD #1 - status:0x2 flags:0x0 dirty:56 < low cache rba:(0x1a.3.0) on disk rba:(0x1a.121.0) < on disk scn: 0x0000.013fe7a8 07/22/2012 07:59:02 --- > THREAD #1 - status:0x2 flags:0x0 dirty:57 > low cache rba:(0x1a.3.0) on disk rba:(0x1a.148.0) > on disk scn: 0x0000.013fe7c2 07/22/2012 07:59:27 100,101c101,102 < heartbeat: 789262462 mount id: 2675014163 < Flashback log tail log# 15 thread# 1 seq 229 block 274 byte 0 --- > heartbeat: 789262470 mount id: 2675014163 > Flashback log tail log# 15 thread# 1 seq 229 block 275 byte 0 2490c2491 <   V$RMAN_STATUS: recid=140734752341296, stamp=140734752341288 --- >   V$RMAN_STATUS: recid=140733792718464, stamp=140733792718456 2501c2502 <   V$RMAN_STATUS: recid=140734752341296, stamp=140734752341288 --- >   V$RMAN_STATUS: recid=140733792718464, stamp=140733792718456 2511c2512 <   V$RMAN_STATUS: recid=140734752341296, stamp=140734752341288 --- >   V$RMAN_STATUS: recid=140733792718464, stamp=140733792718456 2521c2522 <   V$RMAN_STATUS: recid=140734752341296, stamp=140734752341288 --- >   V$RMAN_STATUS: recid=140733792718464, stamp=140733792718456 2531c2532 <   V$RMAN_STATUS: recid=140734752341296, stamp=140734752341288 --- >   V$RMAN_STATUS: recid=140733792718464, stamp=140733792718456

排除部分V$RMAN_STATUS記錄存在差異外,最主要的差別在于: CHECKPOINT PROGRESS RECORDS 這是因為 ckpt 每3s一次對controlfile做heartbeat 更新 CHECKPOINT PROGRESS RECORDS。

第一次 controlf dump:

***************************************************************************
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:0×2 flags:0×0 dirty:56
low cache rba:(0x1a.3.0) on disk rba:(0x1a.121.0)
on disk scn: 0×0000.013fe7a8 07/22/2012 07:59:02
resetlogs scn: 0×0000.01394f1a 07/19/2012 07:27:21
heartbeat: 789262462 mount id: 2675014163
Flashback log tail log# 15 thread# 1 seq 229 block 274 byte 0
THREAD #2 – status:0×0 flags:0×0 dirty:0
low cache rba:(0×0.0.0) on disk rba:(0×0.0.0)
on disk scn: 0×0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0×0000.00000000 01/01/1988 00:00:00
heartbeat: 0 mount id: 0
Flashback log tail log# 0 thread# 0 seq 0 block 0 byte 0

第二次 controlf dump:

***************************************************************************
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:0×2 flags:0×0 dirty:57
low cache rba:(0x1a.3.0) on disk rba:(0x1a.148.0)
on disk scn: 0×0000.013fe7c2 07/22/2012 07:59:27
resetlogs scn: 0×0000.01394f1a 07/19/2012 07:27:21
heartbeat: 789262470 mount id: 2675014163
Flashback log tail log# 15 thread# 1 seq 229 block 275 byte 0
THREAD #2 – status:0×0 flags:0×0 dirty:0
low cache rba:(0×0.0.0) on disk rba:(0×0.0.0)
on disk scn: 0×0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0×0000.00000000 01/01/1988 00:00:00

差異在于:
on disk rba
on disk scn
heartbeat
Flashback log tail log#

即實際CKPT每3s更新heartbeat控制文件一次,更新的內(nèi)容是 on disk rba、on disk scn、heartbeat 如果啟用了閃回日志的話那么還有Flashback log , 而并不更新數(shù)據(jù)庫當前的SCN(CURRENT SCN)。

如果你想查看ckpt每3s更新的 on disk scn的話可以參考 內(nèi)部視圖X$KCCCP–[K]ernel [C]ache [C]ontrolfile management [c]heckpoint [p]rogress  X$KCCCP Checkpoint Progress Records:

SQL> desc x$kcccp; Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ADDR                                               RAW(8)
 INDX                                               NUMBER
 INST_ID                                            NUMBER
 CPTNO                                              NUMBER
 CPSTA                                              NUMBER
 CPFLG                                              NUMBER
 CPDRT                                              NUMBER
 CPRDB                                              NUMBER
 CPLRBA_SEQ                                         NUMBER
 CPLRBA_BNO                                         NUMBER
 CPLRBA_BOF                                         NUMBER
 CPODR_SEQ                                          NUMBER
 CPODR_BNO                                          NUMBER
 CPODR_BOF                                          NUMBER
 CPODS                                              VARCHAR2(16)
 CPODT                                              VARCHAR2(20)
 CPODT_I                                            NUMBER
 CPHBT                                              NUMBER
 CPRLS                                              VARCHAR2(16)
 CPRLC                                              NUMBER
 CPMID                                              NUMBER
 CPSDR_SEQ                                          NUMBER
 CPSDR_BNO                                          NUMBER
 CPSDR_ADB                                          NUMBER

其中cpods 為 ” on disk scn” ,cpodr_seq||cpodr_bno||cpodr_bof為”on disk rba”,CPHBT為heartbeat number:

SQL> select cpods "on disk scn",
           to_char(cpodr_seq, 'xxxxxx') || ',' ||
           to_char(cpodr_bno, 'xxxxxxxxx') || ',' ||
           to_char(cpodr_bof, 'xxxxxxxxx') "on disk rba",
           CPHBT "heartbeat number"
      from x$kcccp; on disk scn      on disk rba                    heartbeat number
---------------- ------------------------------ ----------------
20968609              1a,      240a,         0         789263152
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
8 rows selected.
SQL> 
SQL> 
SQL> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
SQL> select cpods "on disk scn",
           to_char(cpodr_seq, 'xxxxxx') || ',' ||
           to_char(cpodr_bno, 'xxxxxxxxx') || ',' ||
           to_char(cpodr_bof, 'xxxxxxxxx') "on disk rba",
           CPHBT "heartbeat number"
      from x$kcccp; on disk scn      on disk rba                    heartbeat number
---------------- ------------------------------ ----------------
20968613              1a,      2410,         0         789263154
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
8 rows selected.
SQL> 
SQL> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
SQL> select cpods "on disk scn",
  2         to_char(cpodr_seq, 'xxxxxx') || ',' ||
  3         to_char(cpodr_bno, 'xxxxxxxxx') || ',' ||
  4         to_char(cpodr_bof, 'xxxxxxxxx') "on disk rba",
  5         CPHBT "heartbeat number"
  6    from x$kcccp;
on disk scn      on disk rba                    heartbeat number
---------------- ------------------------------ ----------------
20968623              1a,      241e,         0         789263156
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
0                      0,         0,         0                 0
8 rows selected.

到此,相信大家對“Oracle檢查點是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

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

AI