1. 程式人生 > >Oracle後臺程序詳解

Oracle後臺程序詳解

1 資料庫的物理結構和邏輯結構之間的關係由後臺程序來維護和實現,後臺程序由資料庫來管理

 

2 只有當出現問題,才建立跟蹤檔案。後臺程序追蹤檔案的命令約定和位置隨作業系統和資料庫版本而定

 

3 一般而言,追蹤檔案含有後臺程序名和後臺程序的作業系統程序ID。通過設定BACKGROUND_DUMP_DEST來指定後臺程序追蹤檔案位置

 

4 排除資料庫故障時,追蹤檔案是最重要的

 

5 影響後臺程序的嚴重問題通常記錄在資料庫的警告日誌中,警告日誌通常位於BACKGROUND_DUMP_DEST目錄下,路徑為Oracle_BASE目錄下的/admin/INSTANCE_NAME/bdump目錄


 

 

6 可以檢視檢視V$BGPROCESS檢視資料庫中可用後臺程序的完整清單

 

7 SMON (系統監控程式)程序執行所需的例項恢復操作(使用聯機重做日誌檔案),它也可以清除資料庫,消除系統不再需要的事務物件,還可以將連續的自由空間合成一個大的自由空間,SMON只合並表空間中的空閒空間,這些表空間的預設pctincrease儲存值為0

 

8 PMON (程序監控程式)後臺程序清除失敗的使用者程序,釋放使用者當時正在使用的資源,同SMON一樣,PMON週期性地喚醒檢測它是否需要被使用。

 

9:DBWR(資料庫寫入程式)後臺程序負責管理資料塊緩衝區及字典快取區的內容,它以批量寫入的方式將修改塊從SGA寫到資料檔案中. 當緩衝區中的一緩衝區被修改,它被標誌為“弄髒”,DBWR的主區的緩衝區填入資料庫或被使用者程序弄髒,未用的緩衝區的數目減少。當未用的緩衝區下降到很少,以致使用者程序要從磁碟讀入塊到記憶體儲存區時無法找到未用的緩衝區時, DBWR將管理緩衝儲存區,使使用者程序總可得到未用的緩衝區。 ORACLE採用LRU(LEAST RECENTLY USED)演算法(最近最少使用演算法)保持記憶體中的資料塊是最近使用的,使I/O最小。

 

在下列情況預示DBWR 要將弄髒的緩衝區寫入磁碟:

n         當一個伺服器程序將一緩衝區移入“弄髒”表,該弄髒表達到臨界長度時,該服務程序將通知DBWR進行寫。該臨界長度是為引數DB-BLOCK-WRITE-BATCH的值的一半。

 

n         當一個伺服器程序在LRU表中查詢DB-BLOCK-MAX-SCAN-CNT緩衝區時,沒有查到未用的緩衝區,它停止查詢並通知DBWR進行寫。

n         出現超時(每次3秒),DBWR 將通知本身。

n         當出現檢查點時,LGWR將通知DBWR .

在前兩種情況下,DBWR將弄髒表中的塊寫入磁碟,每次可寫的塊數由初始化引數DB-BLOCK-WRITE-BATCH所指定。如果弄髒表中沒有該引數指定塊數的緩衝區,DBWR從LUR表中查詢另外一個弄髒緩衝區。 如果DBWR在三秒內未活動,則出現超時。在這種情況下DBWR對LRU表查詢指定數目的緩衝區,將所找到任何弄髒緩衝區寫入磁碟。每當出現超時,DBWR查詢一個新的緩衝區組。每次由DBWR查詢的緩衝區的數目是為寢化引數DB-BLOCK-WRITE-BATCH的值的二倍。如果資料庫空運轉,DBWR最終將全部緩衝區儲存區寫入磁碟。

在出現檢查點時,LGWR指定一修改緩衝區表必須寫入到磁碟。DBWR將指定的緩衝區寫入磁碟。

 

10 每個資料庫只有一個SMON和一個PMON程序在執行,但可有多個DBWR程序,多個DBWR有助於在進行大的操作期間減少DBWR衝突。

 

11 DBWR的數量由引數DB_WRITER_PROCESSES 決定,命名方式為:DBW1、DBW2、DBW3…

 

12 LGWR(日誌寫程式)後臺程序負責把聯機重做日誌緩衝區的內容寫入聯機重做日誌檔案,LGWR分批將日誌條目寫入聯機重做日誌檔案,重做日誌緩衝區條目總是包含著資料庫的最新狀態,這是因為將資料塊緩衝區中的修改資料塊寫入到資料檔案中之前,DBWR程序將一直處於等待狀態

 

12 LGWR是資料庫正常操作時唯一向聯機重做日誌檔案寫入內容並從重做日誌緩衝區直接讀取內容的程序.與DBWR對資料檔案執行的完全隨機訪問相反,聯機重做日誌檔案按順序方式寫入,如果聯機重做日誌檔案被映象,LGWR同時向映象日誌檔案中寫入內容.

 

以下幾個條件觸發LGWR執行寫操作:

 

(1)超時(timeout)

 

當LGWR處於空閒狀態時,它依賴於rdbms ipc message等待,處於休眠狀態,直到3秒超時時間到。如果LGWR發現有redo需要寫出,那麼LGWR將執行寫出操作,log file parallel write等待事件將會出現。

 

(2)預設的_log_io_size等於1/3 log buffer大小,上限值為1M,此引數在X$KSPPSV中顯示的0值,意為預設值。也就是,LGWR將在Min(1M,1/3 log buffer size)時觸發。注意此處的log buffer size是以log block來衡量的。此值通常為512 bytes.

(3)提交(commit)

當一個事物提交時,在redo stream中將記錄一個提交標誌。

在這些redo被寫到磁碟上之前,這個事物是不可恢復的。所以,在事務返回成功標誌給使用者前,必須等待LGWR寫完成。程序通知LGWR寫,並且以log file sync事件開始休眠,超時時間為1秒。

Oracle的隱含引數_wait_for_sync引數可以設定為false避免redo file sync的等待,但是就將無法保證事務的恢復性。

 

注意,在遞迴呼叫(recursive calls)中的提交(比如過程中的提交)不需要同步redo直到需要返回響應給使用者。因此遞迴呼叫僅需要同步返回給使用者呼叫之前的最後一次Commit操作的RBA。存在一個SGA變數用以記錄redo執行緒需要同步的log block number。

如果多個提交在喚醒LGWR之前發生,此變數記錄最高的log block number,在此之前的所有redo都將被寫入磁碟。這有時候被稱為組提交(group commit).

(4)在DBWR寫之前

如果DBWR將要寫出的資料的高RBA超過LGWR的on-Disk RBA,DBWR將post LGWR去執行寫出。在Oracle8i之前,此時DBWR將等待log file sync事件。從Oracle8i開始,DBWR把這些Block放入一個defer佇列,同時通知LGWR執行redo寫出,DBWR可以繼續執行無需等待的資料寫出。

 

13 CKPT(檢查點程序)用來減少執行例項恢復所需的時間,檢查點使DBWR將自上一個檢查點之後的全部已修改的資料塊寫入資料檔案,並更新資料檔案頭和控制檔案以記錄該檢查點.當一個聯機重做日誌檔案被填滿時,檢查點程序會自動出現,可以使用例項的初始化引數檔案中的 LOG_CHECKPOINT_INTERVAL 引數設定讓一個更頻繁的檢查點出現

 

14 ARCH 後臺程序以迴圈方式寫入聯機重做日誌檔案,一旦最後一個重做日誌檔案被填滿時,LGWR 就開始重寫第一個重做日誌檔案的內容。當Oracle以ARCHIVELOG(歸檔方式)模式執行時,資料庫在開始重寫重做日誌檔案之前先對其進行備份。歸檔可以寫入到一個磁碟、備份資料庫和網路磁碟中

 

15 RECO(恢復程序)用於解決分散式資料庫中的故障問題,只有在平臺支援Distributed

 

Option(分散式選項)且初始化引數檔案中的DISTRIBUTED_TRANSACTIONS引數值大於零時才建立這個程序。

 

16 CJQn Oracle的作業佇列管理依賴於後臺程序的執行,它們進行資料重新整理及其他定期的作業。排程程序CJQ0,選擇將要執行的作業並擴充套件作業佇列程序(J000-J999)以執行這些作業,其最大數量由初始化引數JOB_QUEUE_PROCESSES 決定

 

17 LMSn 當使用Oracle真正的應用叢集(Oracle Real Application Clusters)選項時,多個LMS後臺程序(命令為LCK0-LCK9)用於解決內部例項的鎖定問題

 

18 Dnnn (排程程式程序)是共享伺服器結構的一部分,有助於減少處理多個連線所需要的資源。對於資料庫伺服器支援的每一種協議必須至少建立一個排程程式程序,排程程式程序在資料庫啟動時,基於初始化引數DISPATCHERS建立,也可以在資料庫開啟時建立或取消。

 

19 Server:Snnn 建立伺服器程序來管理需要專用伺服器的資料庫連線。伺服器程序可以資料檔案進行I/O操作。它的最大數量由初始化引數SHARED_SERVERS確定

 

20 Pnnn(並行查詢伺服器程序) 當資料庫內部啟用並行查詢選項,一個查詢的資源要求可以分佈在多個處理器中。當例項啟動時,就啟動指定數量的並行查詢伺服器程序,其數量由引數:PARALLEL_MIN_SERVERS引數決定。這樣的程序出現在作業系統級,其命名為P000、P0001等。其最大數量由PARALLEL_MAX_SERVERS 決定。

 

 


需要牢牢記住的幾個程序觸發條件
查詢( Query )處理步驟
查詢不同於其它型別的SQL 語句,因為如果查詢成功它們會返回作為結果的資料,查詢可以返回一行或者上千行,而其它語句只是返回成功或失敗,查詢的處理有三個主要階段:
       l 分析編譯SQL 語句
        執行標識選定的行或對資料應用DML 更改l
        提取返回SELECTl 語句查詢的行
1. 分析SQL 語句:在分析階段SQL 語句從使用者程序傳遞到伺服器程序,並且SQL 語句的分析說明被載入共享的SQL 區,在分析過程中伺服器程序做如下工作:
        在共享池中搜索SQL 語句的現有副本l
        通過檢查語法驗證SQLl 語句
        執行資料字典查詢來驗證表和列的定義l
        分析SQL 語句續l
       l 獲取物件的分析鎖以便在語句的分析過程中物件的定義不會改變
        檢查使用者訪問引用方案物件的許可權l
       l 確定語句的最佳執行計劃
        將語句和執行計劃載入共享的SQLl 區
主意:分析階段包括處理某些要求,不論語句執行多少次這些要求通常只需要處理一次。Oracle 伺服器總是驗證使用者是否具有執行SQL 語句所需的許可權。
2. 執行SELECT 語句:到了SELECT 語句這一步伺服器程序準備要檢索資料了
3. 提取查詢行:在提取階段對行進行選擇和排序(如有必要)並且由伺服器返回給使用者
發出COMMIT 命令時執行下面的步驟
1.        伺服器程序隨同SCN 一起在重做日誌緩衝區中放置一個提交記錄。
2.        LGWR 向重做日誌檔案中連續寫入,直到提交記錄(含提交記錄)的所有重做日誌緩衝區條目,這之後Oracle 伺服器就能夠保證即使存在例程失敗也不會丟失更改。
3.        通知使用者COMMIT 命令已完成。
4.        伺服器程序記錄資訊以指出事務處理已完成,並且可以釋放資源鎖,將灰資料緩衝區重新整理到資料檔案由DBW0 獨立執行,在提交之前或之後進行都可以。(因此請牢記,DBWR的觸發不依賴於Commit行為)
快速提交( Fast Commit )
快速提交機制將更改寫入重做日誌緩衝區而不是寫入資料檔案,這樣確保資料得以恢復,Oracle 伺服器使用這種機制來保證提交的更改能夠在例程失敗的情況下得以恢復。它有如下優勢
       l 連續寫入日誌檔案比寫入資料檔案的各個塊更快。(因為日誌檔案是順序寫的)
       l 只將記錄更改必須的最少資訊寫入日誌檔案,然而寫入資料檔案卻需要寫入整個資料塊(它記錄被更改的塊,更改位置,以及重做條目中的新值。)。
       l 如果多個事務處理同時請求提交那麼例程將重做日誌記錄合成為單個寫入。
       l 除非重做日誌緩衝區特別滿否則每個事務處理只需要一個同步寫入,如果發生合成,那麼每個事務處理的同步寫入可能不到一個,  因為提交之前可能會重新整理重做日誌緩衝區,所以事務處理的大小並不影響實際的提交操作所需的時間量。(因為,每3秒,重做日誌緩衝區填滿1M,重做日誌緩衝區填滿1/3,或者事務提交的時候,LGWR程序會將REDO LOG BUFFER中內容的寫入到REDO LOG FILE 中。)
注:回退事務處理並不會觸發LGWR 寫入磁碟(因為沒有提交的資料本身不會被寫入資料檔案)。
資料庫寫入程序( DBWR )(8i之前的條件)
伺服器程序在緩衝區快取記憶體中記錄回退和資料塊的更改,資料庫寫入程序(DBW0) 將灰資料緩衝區從資料庫緩衝區快取記憶體寫入資料檔案,它確保有足夠數量的空閒緩衝區,即當伺服器程序需要讀取資料檔案中的塊時,可以覆蓋的緩衝區在資料庫緩衝區快取記憶體中可用。由於伺服器程序只在緩衝區快取記憶體中進行更改,因此資料庫效能得到改善,而且DBW0 延遲寫入資料檔案直到發生下列事件之一:
       l 灰資料緩衝區的數量達到閾值; 
       l 當進行掃描而無法找到任何空閒緩衝區時程序掃描了指定數量的塊;
       l 出現超時每三秒; 
       l 出現檢查點(檢查點是使資料庫緩衝區快取記憶體與資料檔案同步的一種方法)
9i是這麼寫的:
DBWn defers writing to the data files until one of the following events occurs:
* Incremental or normal checkpoint
* The number of dirty buffers reaches a threshold value
* A process scans a specified number of blocks when scanning for free buffers and cannot 
fine any.
* Timeout occurs.
* A ping request in Real Application Clusters environment.
* Placing a normal or temporary tablespace offline.
* Placing a tablespace in read only mode.
* Dropping or Truncating a table.
* ALTER TABLESPACE tablespace name BEGIN BACKUP
日誌寫入程序( LGWR )
LGWR 在下列情況下執行從重做日誌緩衝區到重做日誌檔案的連續寫入:
       l 當提交事務處理時( Commit )
       l 當重做日誌緩衝區的三分之一已滿時
       l 當重做日誌緩衝區中記錄了超過1 MB 的更改時
       l 在DBW0 將資料庫緩衝區快取記憶體中修改的塊寫入資料檔案以前

      l 在DBWR寫之前
 因為恢復操作需要重做,所以LGWR 只在重做寫入磁碟後確認COMMIT 命令。(所以,LGWR是5個不可缺少的後臺程序中,唯一個與SQL語句執行相關的程序。當然,SQL語句的執行還要依賴於在客戶端執行的使用者程序和在伺服器端執行的伺服器程序。)
檢查點( CKPT )
檢查點後臺程序(CKPT)用於更新所有資料檔案的標題和控制檔案以反映該程序已成功完成,使資料庫檔案同步。
資料庫在檢查點期間做如下工作: DBWn 將許多由正在經歷檢查點事件的日誌覆蓋的灰資料庫緩衝區寫入到資料檔案中。由DBWn 寫入的緩衝區數量由引數FAST_START_IO_TARGET 決定。

 

檢查點可發生在下面情況中:
       l 每次日誌切換時;(alter system switch logfile)
       l 當已通過正常事務處理或者立即選項關閉例程時;shutdown immediate或者shutdown)
    l當通過設定初始化引數LOG_CHECKPOINT_INTERVAL、LOG_CHECKPOINT_TIMEOUT 和FAST_START_IO_TARGET 強制時;
       l 當資料庫管理員手動請求時;(ALter system checkpoint)
如果初始化引數LOG_CHECKPOINTS_TO_ALERT設定為TRUE ,則每個檢查點資訊都記錄在ALERT檔案內;該引數預設值為FALSE,不記錄檢查點。
注意:FAST_START_IO_TARGET 引數是在 ORACLE 8.1.x Enterprise Edition 版本及其後續版本中新增的引數。
強制檢查點
可以使用下面的SQL 命令手動強制檢查點發生:
SQL> ALTER SYSTEM CHECKPOINT;
設定資料庫檢查點時間間隔
當資料庫使用大型聯機重做日誌檔案時,可以通過設定以下初始化引數來設定其它資料庫檢查點,以改善資料庫的效能:
l       LOG_CHECKPOINT_INTERVAL
l       LOG_CHECKPOINT_TIMEOUT

l      FAST_START_IO_TARGET (只限於ORACLE 8.1.x Enterprise

Edition 版本及其後續版本)

LOG_CHECKPOINT_INTERVAL 
在低於ORACLE 8.1.X 的版本中,LGWR 一寫入引數LOG_CHECKPOINT_INTERVAL 指定的塊數就啟動了檢查點。LOG_CHECKPOINT_INTERVAL 值在作業系統塊中指定而不是在Oracle 資料庫塊中指定。

但是,無論該值如何,當從一個聯機重做日誌檔案切換到另一個時檢查點始終發生。
如果該值超過實際聯機重做日誌檔案大小,那麼檢查點僅在日誌切換時發生。
注意:將時間間隔值指定為0 可能導致非常頻繁地啟動檢查點,因為即使上一個請求啟動後僅對單個重做日誌緩衝區寫入仍會啟動新的請求。
在ORACLE 8.1.x Enterprise Edition 版本及其後續版本內,當指定了LOG_CHECKPOINT_INTERVAL 後,檢查點位置目標相對於日誌尾的滯後不能大於該引數指定的重做日誌塊數,這確保了在例程恢復期間需要讀取不超過固定數目的重做塊。
LOG_CHECKPOINT_TIMEOUT 
對於低於ORACLE 8.1 的版本,該初始化引數值指定了另一個檢查點發生前的最大時間量,該值按秒指定該時間。從前一個檢查點啟動時,開始經過該引數指定的時間量後發生另一個檢查點,將超時值指定為0 就可以禁用基於時間的檢查點。
在ORACLE 8.1.x Enterprise Edition 版本及其後續版本內,當指定了LOG_CHECKPOINT_TIMEOUT 後,該引數將檢查點位置目標設定到日誌檔案中的某個位置,而該日誌在該引數指定的秒數前結束,這確保了在恢復期間需要讀取的重做塊數不超過與指定秒數相當的塊數。
FAST_START_IO_TARGET 
引數FAST_START_IO_TARGET 改善了例項失敗恢復的效能,該引數值越小,由於需要恢復的塊就越少因而恢復效能就越好。該引數設定後DBWn 更頻繁地將灰緩衝區寫出。該引數在在ORACLE 8.1.x Enterprise Edition 版本及其後續版本中引入。


CheckPoint Process 的深入研究
“三個鍾”的故事:假設一個公司只有三個員工,每個員工有自己的一個鐘。該公司規定,每天早晨8:30上班。有一天,非常不幸,三個員工的鐘的時間各不相同,在沒有其他外部因素的幫助下,他們無法確定當前的確切時間,他們無法上班,該公司無法正常的OPEN 運作。

  這個故事,幫助我們說明,在例項經過分配記憶體結構,載入控制檔案後,然後要開啟資料庫的時候,需要做到控制檔案,資料檔案,聯機重做日誌保持相互狀態一致性,資料庫才可以開啟。當資料庫發生例項不正常關閉時(比如系統掉電或者Shutdown abort 進行關閉),要進行例項恢復,Oracle 資料庫具有相應的機制來實現這一點。

像任何一家公司一樣,不同的員工具有不同的技能專長,負責不同的工作,但是一個成功的專案,需要一個優秀的專案經理,來保持,督促專案中的成員各自工作步調相互一致。在Oracle 例項中,這樣的一個重要角色,被檢查點(CheckPoint) 程序(CKPT)擔任。Oracle 例項在必要的時候,出現檢查點,當檢查點出現時,CKPT 程序一方面催促DBWR 程序及時地把該檢查點時刻前DB_Buffer 中被一些Service_Process 程序修改過的資料及時寫入資料檔案中,寫完之後,CKPT 程序更新相關的資料檔案和控制檔案的同步時刻點。也就是說,Oracle 例項在執行過程中,需要CKPT 程序來定期同步控制檔案、資料檔案和聯機日誌檔案的“時間點”。
  在這篇文章當中,我們將詳細,深入的討論檢查點和檢查點程序的作用。

注:這篇文章主要參考Http://www.AskGuoYu.com 上的一篇文章

大多數關係型資料庫都採用“在提交時並不強迫針對資料塊的修改完成”而是“提交時保證修改記錄(以重做日誌的形式)寫入日誌檔案”的機制,來獲得性能的優勢。這句話的另外一種描述是:當用戶提交事務,寫資料檔案是“非同步”的,寫日誌檔案是“同步”的。這就可能導致資料庫例項崩潰時,記憶體中的DB_Buffer 中的修改過的資料,可能沒有寫入到資料塊中。資料庫在重新開啟時,需要進行恢復,來恢復DB Buffer 中的資料狀態,並確保已經提交的資料被寫入到資料塊中。檢查點是這個過程中的重要機制,通過它來確定,恢復時哪些重做日誌應該被掃描並應用於恢復。

檢查點和檢查點程序的操作的三個步驟:

A、系統觸發一個檢查點,系統並記錄該檢查點時刻的Checkpoint SCN 號,並記錄該時刻修改的DB Buffer的塊所參考的RBA 作為Checkpoint RBA RBA (Redo Byte Address)。

B、該Checkpoint RBA 之前的日誌實體所參考的DB_Buffer 中資料塊的修改,要被寫出到資料檔案中。

C、完成2步驟後,CKPT 程序記錄該檢查點完成資訊到控制檔案。

只有上面三個步驟完成,才表示系統的檢查點已經被推進,推進了日誌檔案,資料檔案,控制檔案到一個新的“同步點”。

檢查點只發生在下列情形:

  管理員使用:Alter system checkpoint 命令;

  例項被正常的關閉;

  特別注意:日誌切換並不導致一個完全檢查點的發生。

如何確定哪些DB_Buffer中的資料塊需要被寫到磁碟上,是一個蠻複雜的演算法。大致思想就是:所有dirty data按照Low RBA 的升序進行連結成一個list,當CKPT被喚醒的時候,首先先從控制檔案讀取上次check point,把中間這段時間的dirty data 寫到磁碟上。

二、觸發的條件

這裡需要明白兩個概念“完全檢查點和增量檢查點”的區別。

增量檢查點(incremental checkpoint)
oracle8以後推出了incremental checkpoint的機制,在以前的版本里每checkpoint時都會做一個full thread checkpoint,這樣的話所有髒資料會被寫到磁碟,巨大的i/o對系統性能帶來很大影響。為了解決這個問題,oracle引入了checkpoint queue機制,每一個髒塊會被移到檢查點佇列裡面去,按照low rdb(第一次對此塊修改對應的redo block address)來排列,靠近檢查點佇列尾端的資料塊的low rba值是最小的,而且如果這些贓塊被再次修改後它在檢查點佇列裡的順序也不會改變,這樣就保證了越早修改的塊越早寫入磁碟。每隔3秒鐘ckpt會去更新控制檔案和資料檔案,記錄checkpoint執行的情況。

在執行的Oracle 資料中,有很多事件、條件或者引數來觸發檢查點。比如
        l 當已通過正常事務處理或者立即選項關閉例程時;(shutdown immediate或者Shutdown normal;)
       l  當通過設定初始化引數LOG_CHECKPOINT_INTERVAL、LOG_CHECKPOINT_TIMEOUT 和FAST_START_IO_TARGET 強制時;
        l 當資料庫管理員手動請求時;(ALter system checkpoint)

 l alter tablespace ... offline;

   l  每次日誌切換時;(alter system switch logfile)

需要說明的是,alter system switch logfile也將觸發完全檢查點的發生。

alter database datafile ... offline不會觸發檢查點程序。

如果是單純的offline datafile,那麼將不會觸發檔案檢查點,只有針對offline tablespace的時候才會觸發檔案檢查點,這也是為什麼online datafile需要media recovery而online tablespace不需要。

對於表空間的offline後再online這種情況,最好做個強制的checkpoint比較好。

  上面幾種情況,將觸發完全檢查點,促使DBWR 將檢查點時刻前所有的髒資料寫入資料檔案。

另外,一般正常執行期間的資料庫不會產生完全檢查點,下面很多事件將導致增量檢查點,比如:

在聯機熱備份資料檔案前,要求該資料檔案中被修改的塊從DB_Buffer 寫入資料檔案中。所以,發出這樣的命令:

l  ALTER TABLESPACE tablespace_name BIGEN BACKUP & end backup; 也將觸發和該表空間的資料檔案有關的區域性檢查點;另外,

l  ALTER TABLESPACE tablespace_name READ ONLY;

l  ALTER TABLESPACE tablespace_name OFFLINE NORMAL;

等命令都會觸發增量檢查點。

三、檢查點位置的影響因素

相比傳統檢查點(也就是指那些有明確含義的檢查點) ,增量檢查點可以平緩的、持續的推進日誌檔案和資料檔案的同步點。理解這一點是學習Checlpoint 有關原理的關鍵點。。很多朋友(包括我自己),總是將增量檢查點和那些有明確含義的檢查點做對比聯絡起來,竭力去探求,什麼時候該出現增量檢查點?很難得到確定的答案,是大家學習的難點。實際上,對於增量檢查點,主要討論的並不是什麼時候出現增量檢查點,而是:如何控制增量檢查點推進的速率?檢查點本質上是為了推進寫日誌和寫資料.

檔案的“非同步機制”的同步,我們感興趣的內容終究要歸結到:系統崩潰時,“非同步的距離”將需要系統多少時間來進行恢復?事實上,Oracle 正是這樣設計的,資料庫提供了一些引數設定(以oracle 9.2 為例)

A、FAST_START_MTTR_TARGET 引數來控制增量檢查點的推進速率

我們都希望當例項崩潰後,恢復需要讀取的日誌流盡可能的短,恢復需要的時間儘可能的短。這樣,我們會將FAST_START_MTTR_TARGET 設定值更小, 增量檢查點會出現的更加密集頻繁。但設定值太小,將顯劇增加DBWR 寫資料檔案的工作量,寫資料檔案的I/O 的增加將降低系統的效能,降低“寫日誌檔案和寫資料檔案的非同步機制”所帶來的效能效益。

難以說明設定FAST_START_MTTR_TARGET 為多少是合適的設定,這和我們各自的資料庫應用業務有關。Oracle 提供了一個檢視V$MTTR_TARGET_ADVICE 作為我們設定參考,從該檢視中,Oracle 會給出一些估計,當您設定不同的FAST_START_MTTR_TARGET 的值時,對應的物理寫資料檔案的數量的估計值。我們可以選擇一個合適的值,可以降低恢復時間,但是不讓DBWR 的工作量增加太大。

 

 

 

資料庫在“事務”當中發生變化,Oraccle 資料庫系統使用系統變更號(System Change Number,簡寫為SCN)來記錄資料庫內部的變化。資料庫內部的很多事件,以及使用者通過SQL 語句對資料庫內容進行變化,會讓SCN 值增長。< xmlnamespace prefix ="o" />

  我們知道,當應用程式提交(Commit)某個事務時,先是日誌寫入程序(LGWR)將Log Buffer 中的該事務的紀錄寫入到聯機重做日誌檔案成功後,才由Service Process 通知相關的使用者程序:你的提交已成功。

www.ixdba.net


 

檢查點出現,將推動檢查點時刻前的日誌檔案中所參考的資料塊的修改,已經被DBWR 寫入到資料檔案中。CKPT程序會紀錄該檢查點的Checkpoint SCN 的資訊到資料檔案和控制檔案中。從而推動了資料庫的一個“同步點”。如果在下一個同步點完成之前,資料庫發生失敗,在資料庫的例項恢復從系統當前檢查點開始,運用後面的日誌進行例項恢復。

可以看出,檢查點的出現,可以讓資料庫在執行時,“定期”的維護日誌檔案,資料檔案進行狀態一致性。有些類似於我們生活中:不同的公司定期的賬目結清,當一個檢查點完成後,大家都承認,這個時間之前的一切賬目已經結清。

 

一、Oracle 是如何確定需要恢復的

1、正常執行的資料庫的有關檢查點資訊紀錄

在資料庫正常OPEN 執行時,當一個檢查點完成後,Oracle儲存新的System Checkpoint SCN 值

到控制檔案中,我們可以通過下面的查詢來得到該值。

SQL> select a.CHECKPOINT_CHANGE# from v$database a;

CHECKPOINT_CHANGE#

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

2798752785243

SQL> select a.NAME,a.CHECKPOINT_CHANGE# from v$datafile a;

NAME CHECKPOINT_CHANGE#

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

C:ORACLEORADATAJACKYSYSTEM01.DBF 2798752785243

C:ORACLEORADATAJACKYUNDOTBS01.DBF 2798752785243

C:ORACLEORADATAJACKYCWMLITE01.DBF 2798752785243

C:ORACLEORADATAJACKYDRSYS01.DBF 2798752785243

C:ORACLEORADATAJACKYEXAMPLE01.DBF 2798752785243

C:ORACLEORADATAJACKYINDX01.DBF 2798752785243

C:ORACLEORADATAJACKYODM01 2798752785243

C:ORACLEORADATAJACKYTOOLS01.DBF 2798752785243

D:DATAFILEUSERS01.DBF 2798752785243

C:ORACLEORADATAJACKYXDB01.DBF 2798752785243

C:ORACLEORADATAJACKYBLOCK.DBF 2798752785243

C:ORACLEORADATAJACKYRMAN.DBF 2798752785243

C:ORACLEORADATAJACKYTEST01.DBF 2798752785243

13 rows selected

Oracle 也會在每個資料檔案的頭部儲存儲存Checkpoint SCN的值,名稱叫做Start SCN。主要作用是在資料庫Open的時候,用於和控制檔案有關資訊進行比較,從而確定是否需要做恢復。

SQL> select a.NAME,a.CHECKPOINT_CHANGE# from v$datafile_header a;

NAME CHECKPOINT_CHANGE#

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

C:ORACLEORADATAJACKYSYSTEM01.DBF 2798752785243

C:ORACLEORADATAJACKYUNDOTBS01.DBF 2798752785243

C:ORACLEORADATAJACKYCWMLITE01.DBF 2798752785243

C:ORACLEORADATAJACKYDRSYS01.DBF 2798752785243

C:ORACLEORADATAJACKYEXAMPLE01.DBF 2798752785243

C:ORACLEORADATAJACKYINDX01.DBF 2798752785243

C:ORACLEORADATAJACKYODM01 2798752785243

C:ORACLEORADATAJACKYTOOLS01.DBF 2798752785243

D:DATAFILEUSERS01.DBF 2798752785243

C:ORACLEORADATAJACKYXDB01.DBF 2798752785243

C:ORACLEORADATAJACKYBLOCK.DBF 2798752785243

C:ORACLEORADATAJACKYRMAN.DBF 2798752785243

C:ORACLEORADATAJACKYTEST01.DBF 2798752785243

13 rows selected

Oracle 在控制檔案為每個資料檔案儲存Stop SCN 的值,在正常OPEN 的資料庫中,該值為一個無窮大,查詢時,顯示NULL。

SQL> select a.NAME,a.LAST_CHANGE# from v$datafile a;

NAME LAST_CHANGE#

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

C:ORACLEORADATAJACKYSYSTEM01.DBF

C:ORACLEORADATAJACKYUNDOTBS01.DBF

C:ORACLEORADATAJACKYCWMLITE01.DBF

C:ORACLEORADATAJACKYDRSYS01.DBF

C:ORACLEORADATAJACKYEXAMPLE01.DBF

C:ORACLEORADATAJACKYINDX01.DBF

C:ORACLEORADATAJACKYODM01.DBF

C:ORACLEORADATAJACKYTOOLS01.DBF

D:DATAFILEUSERS01.DBF

C:ORACLEORADATAJACKYXDB01.DBF

C:ORACLEORADATAJACKYBLOCK.DBF

C:ORACLEORADATAJACKYRMAN.DBF

C:ORACLEORADATAJACKYTEST01.DBF

13 rows selected

2、正常關閉的資料庫的有關檢查點記錄資訊

當我們正常關閉資料庫(Shutdown immediate 或者Shutdown normal),此時會執行一個檢查點的過程,該過程會把控制檔案中記錄的每個資料檔案的Stop SCN 進行設定,等於每個資料檔案頭部的StartSCN。所以,我們以start mount 載入資料庫,然後進行上面的查詢。得到下圖的結果:

正常關閉資料庫,在Mount 模式下啟動資料庫,查詢System Checkpoint SCN 和Data File

Checkpoint SCN 以及Start SCN、Stop SCN 變得一致。

SQL> startup mount;

ORACLE 例程已經啟動。

Total System Global Area 135338868 bytes

Fixed Size 453492 bytes

Variable Size 109051904 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

資料庫裝載完畢。

SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#

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

2.7988E+12

SQL> select name,checkpoint_change#,last_change# from v$datafile where name like '%USER%';

NAME CHECKPOINT_CHANGE# LAST_CHANGE#

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

D:DATAFILEUSERS01.DBF 2.7988E+12 2.7988E+12

SQL>

在OPEN 資料庫時,Oracle 先檢查資料檔案頭部所記錄的Start SCN 和控制檔案中所記錄的資料檔案的Checkpoint SCN 是否一致,如果一致,Oracle 進一步檢查Start SCN 和控制檔案中記錄的資料檔案的Stop SCN,如果一致。這表示所有的已經被修改的資料塊已經反映到了資料檔案中。在是正常關閉資料庫的情況。資料庫可以正常OPEN,無需作例項恢復,當資料庫開啟後,控制檔案中的Stop SCN 會變為NULL。

SQL> alter database open;

資料庫已更改。

SQL> select name,checkpoint_change#,last_change# from v$datafile where name like '%USER%';

NAME CHECKPOINT_CHANGE# HANGE#

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

D:DATAFILEUSERS01.DBF 2.7988E+12

資料庫在開啟時,對每個資料檔案要進行兩個比對:

  A、控制檔案中記錄的資料檔案的Checkpoint SCN  和 資料檔案頭部所記錄的Start SCN 是否相等;

  B、然後檢查:控制檔案中記錄資料檔案的Stop SCN 和 資料檔案頭部所記錄的Start SCN 是否相等;

3、例項Crash 後的有關檢查點記錄資訊

SQL> create table test (a number) tablespace test ;

Table created

SQL> insert into test values(1);

1 row inserted

SQL> shutdown abort

ORACLE 例程已經關閉。

SQL> startup mount

ORACLE 例程已經啟動。

Total System Global Area 135338868 bytes

Fixed Size 453492 bytes

Variable Size 109051904 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

資料庫裝載完畢。

SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#

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

2.7988E+12

SQL> select name,checkpoint_change#,last_change# from v$datafile where name like '%TEST%';

NAME CHECKPOINT_CHANGE# LAST_CHANGE#

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

C:ORACLEORADATAJACKYTEST01.DBF 2.7988E+12 NULL

SQL> select name,checkpoint_change# from v$datafile_header where name like'%TEST%';

NAME CHECKPOINT_CHANGE#

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

C:ORACLEORADATAJACKYTEST01.DBF 2.7988E+12

從上面可以看出控制檔案中記錄的Stop SCN (查詢中的Last_Change#)為無窮大。不等於資料檔案頭部的Start SCN。這表示:資料庫在Crash 關閉時,沒有進行Checkpoint和相關過程。例項在Open 之前,需要做例項恢復。

例項恢復由Oracle 例項自動完成。Oracle 依照控制檔案記錄的資料庫的Checkpoint SCN 定位聯機重做日誌檔案中的重做日誌位置。從該位置開始應用重做日誌一直到Crash 時日誌結束點。這中間所有被提交的事務,將會確保寫入到資料檔案,這個過程叫做前滾過程(Roll Forward)。沒有提交的活動事務將從回滾段中恢復過來;在上面的例子中Crash前,我們插入了一行資料,但是沒有被提交。所以,例項恢復後,將查詢不到該行資料。

SQL> alter database open;(oracle 例項自動完成)

資料庫已更改。

SQL> select * from test;

未選定行

控制檔案中記錄的資料檔案的Checkpoint SCN 和資料檔案頭部所記錄的Start SCN 始終是相等的。這是因為資料庫在經歷檢查點後,檢查點後臺程序會同時修改資料庫的System Checkpoint SCN、控制檔案中記錄的資料檔案的Checkpoint SCN、以及資料檔案標頭檔案中的Start SCN,設定它們的值為檢查點開始的系統變更號SCN。

只有在當資料檔案丟失時,我們使用以前的備份的資料檔案時,這個比對就不一致,資料檔案頭部紀錄的Start SCN 將會小於控制檔案中所記錄的該資料檔案的Checkpoint SCN。將使用到必要的歸檔/聯機日誌檔案進行恢復。

4、使用備份的控制檔案進行恢復

   在正常情況下,資料檔案頭部所記錄的Start SCN 都不會大於控制檔案中記錄的資料檔案的CheckpointSCN 的。我們也許覺得奇怪,控制檔案已經記錄了Checkpoint SCN,為何還需要紀錄System Checkpoint SCN 呢,這主要有下列原因:

A、有時候,資料庫的某些表空間處於只讀模式,當系統經歷檢查點,只讀表空間的資料檔案頭部的StartSCN 將不會更新; System Checkpoint SCN 有助於識別這一點。

B、有時候,我們的控制檔案丟失了,當我們使用以前備份的控制檔案。此時,資料檔案頭部的Start SCN會大於控制檔案的System Checkpoint SCN,這表明使用了備份的控制檔案。如果我們使用正常的recover database 的恢復方法,將會出現錯誤訊息。我們應該使用:recover database using backup controlfile;

二、例項恢復的詳細過程

當我們系統掉電,或者通過Shutdown abort 關閉資料後,再重新開啟資料庫前,系統會自動進行恢復,這個恢復過程可以分為下列三個階段

A.     前滾過程,前滾是按照redo file的記錄來前滾的,不管有沒有commit,都會利用聯機日誌檔案的有關重做資訊,寫入到資料檔案中。

前滾是按照redo file的記錄來前滾的,不管有沒有commit,只要有已經寫入redo就會前滾,所以前滾完成後,data file中可能會有 沒有提交的資料,這樣才需要後面的回退過程。另外,由於undo的生成也是要記錄redo的,所以這個過程還會按照redo重新生成後面回退時需要的undo資訊。另外,例項恢復是在從最近的一次checkpoint後開始到失敗的一刻,所以,增加checpoint的頻率可以減少例項恢復所需要的時間,但同時會影響系統的效能,所以需要在這兩者之間做一個權衡。

前滾又叫緩衝區恢復cache recovery,顧名思義,就是恢復已經在記憶體中存在但還沒有寫入資料檔案中的內容,而不管這個內容所在的事務是不是已經提交。

B.      資料庫開啟:進行完畢前滾過程後,資料庫就可以開啟,可以接受使用者連線訪問了。

C.         回退(Roll Back) 過程:沒有提交的事務將會被回退。
回退階段又叫事務恢復transaction recoery,也就是恢復完後將保持事務一致性。該過程保證資料庫中的資料只有已經提交的,沒有提交的事務將會被回退。

1、redo buffer 的操作

當用戶User A 發出資料修改命令: UPDATE emp SET sal=10 WHERE id=1234

資料塊被讀入DB Buffer 中;相應的回滾段的資料塊也被讀入到DB Buffer 中,並將數修改前的值資訊記錄下來,作為前映像; 這樣的變化過程會作為REDO 實體記錄在Redo Buffer中。

然後,修改DB Buffer 中資料塊的值為新值;並在Redo Buffer中生成重做資訊。在Redo Buffer 中的重做記錄實體主要包含三部分資訊:

 事務的識別號

 修改目標Column 的地址

 修改Column 的新值

然後,使用者User A 發出提交命令:

Commit

在Redo Buffer 中生成相應的重做資訊實體,該資訊主要包含三部分:

A、一個標誌指示該實體是一個Commit。如果是Rollback 或者是Checkpoint也有相應的標誌。

B、時間。

C、當前的SCN 號。

SCN 是System Change Number,用來幫助識別資料庫的事務,資料庫在事務當中變化,我們可以認為SCN 是資料庫變化的“時鐘”。SCN 一般用來標識資料庫內事務的開始,事務的提交,回滾,或者是檢查點的時間,以及其他資料庫內部的事件。

LGWR 程序負責將Log Buffer 中內容寫入到聯機日誌檔案中去。觸發LGWR 工作的機制有:

  使用者提交

  Redo Buffer 的1/3 寫滿了

  Redo Buffer 中寫滿< XMLNAMESPACE PREFIX ="ST1" />1M 內容

超時3 秒

DBWR 寫

總之,LGWR是一個極為頻繁的工作程序,從而保證事務資訊被非常快速,及時地寫入到聯機日誌檔案。

當聯機日誌檔案Log 1 寫滿之後,則發生日誌切換到Log 2。在正常的生產資料庫上,聯機日誌檔案的組數和大小需要靈活考慮,通常情況下,較好的經驗值是讓日誌切換的發生時間間隙為20-30分鐘之間。這只是一個建議,某些情況或者某些特別的需求,也有要求日誌切換更加頻繁或者間隙更長。

2、資料庫恢復的過程

因為系統掉電或者不正常關閉資料庫(Shutdown abort),當資料庫要重新開啟前,系統自動會進行恢復過程。這個恢復過程是首先從讀取控制檔案的資訊開始的。控制檔案中記錄的Checkpoint RBA (Redo Byte Address) 指向聯機日誌檔案中一個恢復開始點。由於每次操作都在redo log都有記錄,所以可以從這個開始點往後的重做資訊直到重做資訊的結束點,每次操作都進行“重演”,也就是恢復。

對於已經提交的事務,事務被“重新提交(Re-Commit)”,這就是前滾的概念。然而,在資料庫Crash 前沒有提交的事務,當時所引起的資料檔案的修改變化。在恢復過程後,資料庫開啟執行期間,如果有使用者訪問到這些資料塊,才利用以前的“前映像”來重新修改回去。這是未提交的事務的回退過程。

從oracle9i開始,Oracle 改善了恢復過程中“前滾”的操作。這個小的改變提高了例項恢復過程中的效率--在例項失敗後可以更快速的恢復過來。當一次DBWR寫 完成後,LGWR會在Redo Buffer 中記錄該次寫完成的資料塊。

這種新的快速前滾機制分為兩個步驟:

A、 先快速選擇哪些塊的事務需要處理;掃描一次Redo Log, 根據DBWR的寫塊記錄濾去已經寫入了資料檔案的那些重做實體的處理,這個過程不需要讀取資料檔案塊。速度非常快。

B、 然後對選擇的塊進行處理;

這個小的改善,顯劇減少了恢復過程中去讀取和修改資料塊的數量。再加上Checkpoint 的同步特性和有關引數控制。讓例項Crash後的快速恢復過程的時間是快速的,可控的
--------------------- 
作者:wxwpxh 
來源:CSDN 
原文:https://blog.csdn.net/wxwpxh/article/details/50532445 
版權宣告:本文為博主原創文章,轉載請附上博文連結!