checkpoint掃盲
什麼是checkpoint
在數據庫系統中,寫日誌和寫數據文件是數據庫中IO消耗最大的兩種操做,在這兩種操做中寫數據文件屬於分散寫,寫日誌文件是順序寫,所以爲了保證數據庫的性能,一般數據庫都是保證在提交(commit)完成以前要先保證日誌都被寫入到日誌文件中,而髒數據塊着保存在數據緩存(buffer cache)中再不按期的分批寫入到數據文件中。也就是說日誌寫入和提交操做是同步的,而數據寫入和提交操做是不一樣步的。這樣就存在一個問題,當一個數據庫崩潰的時候並不能保證緩存裏面的髒數據所有寫入到數據文件中,這樣在實例啓動的時候就要使用日誌文件進行恢復操做,將數據庫恢復到崩潰以前的狀態,保證數據的一致性。檢查點是這個過程當中的重要機制,經過它來肯定,恢復時哪些重作日誌應該被掃描並應用於恢復。php
通常所說的checkpoint是一個數據庫事件(event),checkpoint事件由checkpoint進程(LGWR/CKPT進程)發出,當checkpoint事件發生時DBWn會將髒塊寫入到磁盤中,同時數據文件和控制文件的文件頭也會被更新以記錄checkpoint信息。數據庫
checkpoint的做用
checkpoint主要2個做用:緩存
- 保證數據庫的一致性,這是指將髒數據寫入到硬盤,保證內存和硬盤上的數據是同樣的;
- 縮短實例恢復的時間,實例恢復要把實例異常關閉前沒有寫出到硬盤的髒數據經過日誌進行恢復。若是髒塊過多,實例恢復的時間也會很長,檢查點的發生能夠減小髒塊的數量,從而提升實例恢復的時間。
通俗的說checkpoint就像word的自動保存同樣。oracle
檢查點分類
- 徹底檢查點(Normal checkpoint)
- 增量檢查點(Incremental checkpoint)
checkpoint相關概念術語
在說明checkpoint工做原理以前咱們先了解一些相關的術語。app
RBA(Redo Byte Address), Low RBA(LRBA), High RBA(HRBA)
RBA就是重作日誌塊(redo log block)的地址,至關與數據文件中的ROWID,經過這個地址來定位重作日誌塊。RBA由三個部分組成:ide
- 日誌文件序列號(4字節)
- 日誌文件塊編號(4字節)
- 重作日誌記錄在日誌塊中的起始偏移字節數(2字節)
一般使用RBA的形式有:性能
-
LRBA
-
數據緩存(buffer cache)中一個髒塊第一次被更新的時候產生的重作日誌記錄在重作日誌文件中所對應的位置就稱爲LRBA。
-
HRBA
-
數據緩存(buffer cache)中一個髒塊最近一次被更新的時候產生的重作日誌記錄在重作日誌文件中所對應的位置就稱爲HRBA。
-
checkpoint RBA
-
當一個checkpoint事件發生的時候,checkpoint進程會記錄下當時所寫的重作日誌塊的地址即RBA,此時記錄的RBA被稱爲checkpoint RBA。從上一個checkpoint RBA到當前的checkpoint RBA之間的日誌所保護的buffer cache中的髒塊接下來將會被寫入到數據文件當中去。
Buffer checkpoint Queues (BCQ)
Oracle將全部在數據緩存中被修改的髒塊按照LRBA順序的組成一個checkpoint隊列,這個隊列主要記錄了buffer cache第一次發生變化的時間順序,而後有DBWn進程根據checkpoint隊列順序將髒塊寫入到數據文件中,這樣保證了先發生變動的buffer能先被寫入到數據文件中。BCQ的引入是爲了支持增量checkpoint的。spa
Active checkpoint Queue (ACQ)
ACQ中包含了全部活動的checkpoint請求。每次有新checkpoint請求是都會在ACQ中增長一條記錄,ACQ記錄中包含了相應的checkpoint RBA。checkpoint完成之後相應的記錄將被移出隊列。.net
徹底檢查點 (normal checkpoint)
徹底檢查點工做過程
一個checkpoint操做能夠分紅三個不一樣的階段:日誌
- 第一階段,checkpoint進程開始一個checkpoint事件,並記錄下checkpoint RBA,這個一般是當前的RBA。
- 第二階段,checkpoint進程通知DBWn進程將全部checkpoint RBA以前的buffer cache裏面的髒塊寫入磁盤。
- 肯定髒塊都被寫入磁盤之後進入到第三階段,checkpoint進程將checkpoint信息(SCN)寫入/更新數據文件和控制文件中。
更新SCN的操做由CKPT進程完成,在Oracle 8.0以後CKPT進程默認是被啓用的,若是CKPT進程沒有啓用的話那相應的操做將由LGWR進程完成。
何時發生normal checkpoint
下面這些操做將會觸發checkpoint事件:
- 日誌切換,經過ALTER SYSTEM SWITCH LOGFILE。
- DBA發出checkpoint命令,經過ALTER SYSTEM checkpoint。
- 對數據文件進行熱備時,針對該數據文件的checkpoint也會進行,ALTER TABLESPACE TS_NAME BEGIN BACKUP/END BACKUP。
- 當運行ALTER TABLESPACE/DATAFILE READ ONLY的時候。
- SHUTDOWN命令發出時。
特別注意:
- 日誌切換會致使checkpoint事件發生,可是checkpoint發生卻不會致使日誌切換。
- 日誌切換觸發的是normal checkpoint,而不是你們所說的增量checkpoint,只不過log switch checkpoint的優先級很是低,當一個log switch checkpoint發生的時候它並不會當即的通知DBWn進程去寫數據文件,可是當有其它緣由致使checkpoint或者是寫入數據文件的RBA超過log switch checkpoint的checkpoint RBA的時候,此次的log switch checkpoint將會被標記成完成狀態,同時更新控制文件和數據文件頭。咱們隨後能夠作個實驗驗證這個說法。
checkpoint和SCN有什麼關係?
在Oracle中SCN至關於它的時鐘,在現實生活中咱們用時鐘來記錄和衡量咱們的時間,而Oracle就是用SCN來記錄和衡量整個Oracle系統的更改。
Oracle中checkpoint是在一個特定的「時間點」發生的,衡量這個「時間點」用的就是SCN,所以當一個checkpoint發生時SCN會被寫入文件頭中以記錄這個checkpoint。
增量checkpoint
增量checkpoint工做過程
由於每次徹底的checkpoint都須要把buffer cache全部的髒塊都寫入到數據文件中,這樣就是產生一個很大的IO消耗,頻繁的徹底checkpoint操做很對系統的性能有很大的影響,爲此Oracle引入的增量checkpoint的概念,buffer cache中的髒塊將會按照BCQ隊列的順序持續不斷的被寫入到磁盤當中,同時CKPT進程將會每3秒中檢查DBWn的寫入進度並將相應的RBA信息記錄到控制文件中。
有了增量checkpoint以後在進行實例恢復的時候就不須要再從崩潰前的那個徹底checkpoint開始應用重作日誌了,只須要從控制文件中記錄的RBA開始進行恢復操做,這樣能節省恢復的時間。
發生增量checkpoint的先決條件
- 恢復需求設定 (FAST_START_IO_TARGET/FAST_START_MTTR_TARGET)
- LOG_checkpoint_INTERVAL參數值
- LOG_checkpoint_TIMEOUT參數值
- 最小的日誌文件大小
- buffer cache中的髒塊的數量
增量checkpoint的特色
- 增量checkpoint是一個持續活動的checkpoint。
- 沒有checkpoint RBA,由於這個checkpoint是一直都在進行的,因此不存在normal checkpoint裏面涉及的checkpoint RBA的概念。
- checkpoint advanced in memory only
- 增量checkpoint所完成的RBA信息被記錄在控制文件中。
- 增量checkpoint能夠減小實例恢復時間。
增量checkpoint相關參數設置
-
log_checkpoint_interval
-
設定兩次checkpoint之間重作日誌塊(重作日誌塊和系統數據塊是同樣的)數,當重作日誌塊數量達到設定值的時候將觸發checkpoint。
-
log_checkpoint_timeout
-
設定兩次checkpoint之間的間隔時間,當超時值達到時增量checkpoint將被觸發。Oracle建議不用這個參數來控制,由於事務(transaction)大小不是按時間等量分佈的。將此值設置成0時將禁用此項設置。
-
fast_start_io_target
-
由於log_checkpoint_interval主要看的時候重作日誌塊的數量,並不能反應buffer cache中髒數據塊的修改,所以Oracle又引入了這個參數來實現當髒數據塊達到必定數量的時候觸發checkpoint,不過此參數實際上控制的是恢復時所需IO的數量。
-
fast_start_mttr_target
-
- 此參數是在9i中引入用來代替前面的三個參數的,它定義了數據塊崩潰後所須要的實例恢復的時間,Oracle在實際上內在的解釋成兩個參數:fast_start_io_target和log_checkpoint_interval.若是這兩個參數沒有顯式的指定,計算值將生效.。
- fast_start_mttr_target能夠設定的最大值是3600,即一個小時。它的最小值沒有設限,可是並非說能夠設置一個任意小的值,這個值會受最小dirty buffer(最小爲1000)的限制,同時還會受初始化時間以及文件打開時間的限制。
- 在設置此參數的時候要綜合考慮系統的IO,容量以及CPU等信息,要在系統性能和故障恢復時間之間作好平衡。
- 將此參數設置成0時將禁用 fast-start checkpointing,這樣能見效系統負載但同時會增長系統的恢復時間。
- 若是fast_start_io_target or log_checkpoint_interval被指定,他們會自動覆蓋由fast_start_mttr_target參數計算出來的值。
在10g中,數據庫能根據各類系統參數的設置值來自動調整檢查點的執行頻率,以得到最好的恢復時間以及系統的正常運行影響最小。經過自動checkpoint調整,Orach能在系統低IO操做的時候將髒塊寫入到數據文件中,所以即時DBA沒有設置checkpoint相關的參數值或是設置了一個不合理的值的時候系統仍是能得到一個很合理的系統恢復時間。
10g中的增量checkpoint更能體現它持續活動的特色,在10g中,增量checkpoint不是在某一個特定的條件下觸發,而是由數據庫根據系統參數設置自動觸發。
與徹底checkpoint的區別
- 徹底checkpoint會將checkpoint的信息寫入到控制文件以及數據文件頭中
- 增量checkpoint只會將RBA信息寫入到控制文件中。
查看系統的checkpoint動做
咱們能夠經過將LOG_checkpointS_TO_ALERT設置成TRUE來打開checkpoint的trace,這樣就能夠跟蹤checkpoint的操做了。
ALTER
SYSTEM
SET
LOG_checkpointS_TO_ALERT
=
TRUE
;
這設置之後系統的checkpoint將會被記錄alert_$SID.log文件中。
在V$DATAFILE_HEADER裏面也保存了發生徹底checkpoint的時候一些相關信息,包括checkpoint發生時間、對應SCN已經checkpoint的次數。
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
*/
徹底檢查點
-- 咱們先執行一個
ALTER
SYSTEM
checkpoint
;
-- 下面是alert文件中的數據結果
Mon
Aug
4
22
:
22
:
08
2008
Beginning
global
checkpoint
up
to
RBA
[
0
x8
.
c9d4
.10
],
SCN
:
533714
Completed
checkpoint
up
to
RBA
[
0
x8
.
c9d4
.10
],
SCN
:
533714
-- 咱們能看到徹底checkpoint發生的SCN 533714
-- 下面咱們再對照下V$DATAFILE_HEADER中的結果
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已經被記錄到數據文件頭中了。
日誌切換時的檢查點
-- 咱們先作一第二天志切換
ALTER
SYSTEM
SWITCH
LOGFILE
;
-- 而後看看alert裏面的記錄
Mon
Aug
4
22
:
31
:
39
2008
Beginning
log
switch
checkpoint
up
to
RBA
[
0
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
[
0
x9
.2.10
],
SCN
:
534450
-- 咱們能看到checkpoint是在過了一段時間(這裏是4分鐘)以後才完成的
-- 接着咱們來看下V$DATAFILE_HEADER中的結果
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
-- 在這裏咱們能發現下V$DATAFILE_HEADER裏面記錄的SCN和日誌切換髮生的checkpoint的SCN是同樣的,
-- 這就證實了日誌切換是會更新數據文件頭的,同時日誌切換的checkpoint是一個級別比較低的操做,
-- 它不會當即完成,這也是出於性能上考慮的。
增量checkpoint查看
當前所知只有在LOG_checkpoint_TIMEOUT設置了非0值以後觸發的增量checkpoint會在alert文件中有記錄,其餘條件觸發的增量checkpoint都不會記錄在alert文件中。
-- 下面是當LOG_checkpoint_TIMEOUT設置爲1800s的時候所產生的增量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動態性能視圖能夠查看一些MTTR相關的信息。
SELECT TARGET_MTTR,ESTIMATED_MTTR,CKPT_BLOCK_WRITES,CKPT_BLOCK_WRITES FROM V$INSTANCE_RECOVERY
-
TARGET_MTTR
-
用戶設置的參數FAST_START_MTTR_TARGET的值.
-
ESTIMATED_MTTR
-
根據目前髒塊數目和日誌塊數目,評估的如今進行恢復所須要的時間.
-
CKPT_BLOCK_WRITES
-
檢查點寫完的塊數目.
-
CKPT_BLOCK_WRITES
-
額外的由於檢查點引發的數據庫寫入操做 (由於沒必要要的檢查點的產生,設置一個很是小的系統恢復時間將會對性能產生負面影響,爲了幫助管理員監測這個參數設置較小時對數據庫的影響,這個視圖顯示了這個列)
相關視圖
V$視圖
-
V$DATAFILE_HEADER
-
查看數據文件的徹底checkpoint信息。
-
V$INSTANCE_RECOVERY
-
查看fast_start_mttr_target設置以及系統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的區別這方面的爭論裏來很多,特別是對於日誌切換究竟是增量仍是徹底的爭論更是如此,可是其實翻遍Oracle的文檔就沒有發現有提到增量checkpoint(incremental checkpoint)或是徹底checkpoint(full checkpoint)這兩個概念。
個人觀點是根本就沒有必要能夠的區分是增量仍是徹底,真正要理解的是不一樣狀況下的checkpoint都會有些什麼樣的行爲,而後根據這些行爲來對數據庫進行配置,設置相應的參數,制定相應的備份/恢復策略,就此而已。
下面列出寫常見的checkpoint行爲:
- 相似於alter system checkpoint這樣的語句所產生的,先記錄下當前的scn,而後推進DBWn進程去寫髒數據,當寫到所記錄的scn時候檢查點結束,而後ckpt進程將記錄的scn寫入到控制文件和數據文件頭。
- 設置參數log_checkpoint_timeout以後產生的,在超時值達到的時候,ckpt進程記錄當時DBWn寫髒數據的進度,也就是寫到那個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]
- ckpt進程每3s起來一次記錄checkpoint的進度到控制文件中,這種狀況跟上面的相似,只不過在alert裏面是看不到的,並且也不是每次喚醒都會寫控制文件的,而是有就記,沒有就拉倒。
- 相似於alter system switch logfile所產生的,先記錄下發出命令時刻的scn,ckpt進程不會推進DBWn去寫髒數據,而是讓DBWn按照本身的狀態去寫髒數據,等到寫到記錄的scn時,chpt進程再去更新控制文件和數據文件頭。這種狀況在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