您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Oracle的增量檢查點指的是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
一、為什么要有檢查點
被修改過的塊,在oracle中都被統稱為臟塊.所有的臟塊被一個鏈表串起來,稱做檢查點隊列.在buffer cache中,每一個塊都有一個buffer header 簡稱BH,在BH中有一個ckptq項,此項目中記錄了指向檢查點隊列上一個塊和下一個塊的指針.如果某一個塊不在檢查點隊列中,他的ckptq項為空.通過ckptq項oracle將所有的臟塊串成了一個雙向鏈表.這個雙向鏈表就是檢查點隊列了.
1,只有臟塊才會在檢查點隊列中,非臟塊的ckptq為空.
2,當塊首次被更改時,塊會立即被加進檢查點隊列.如果檢查點隊列中的臟塊再次被修改,并不會改變其在檢查點隊列中的位置.
3,檢查點隊列中臟塊的排列順序:根據第2點,所有臟塊按照首次被更改的時間的順序排列.更準確點說:按照塊的lrba排列.
二、什么是rba? lrba? hrba
rba就是重做塊地址,比如說,用戶發出了一條update命令,更新了塊A,塊A現在變成了臟塊,oracle會為他生成一條重做記錄.這條重做記錄在重做日志文件中的位置就是rba(redo block address).過了一會兒,假如:塊A依然還是臟塊,此時.用戶又發出一條更新塊A的命令,這又會生成一條重做記錄.第一條更新命令對應的重做記錄的rba被稱為塊A的lrba(low
rba),第二條更新命令對應的rba,被稱為hrba(high
rba).其實,按照lrba來排列,就是按照塊首次被修改的順序來排列.
下面說說DBWR寫臟塊的方式,有了檢查點隊列之后,臟塊按照首次變臟的時間順序排列,DBWR每到一定的時機,就會被觸發,沿著檢查點隊列的順序刷新臟塊,具體在oracle中有幾個參數用來確定檢查點隊列的長度.另有一個CKPT進程,會監控著檢查點隊列的長度,當檢查點隊列的長度達到一定限制時,CKPT會通知DBWR寫臟塊.CKPT會根據參數的設置和I/O的速度以及繁忙程度,計算出來一個Target
rba(目標rba),DBWR會沿著檢查點隊列,將所有Target rba之前的臟塊刷新到磁盤.當CKPT通知完DBWR Target rba后,CKPT的任務就結束了.他并不會等待DBWR寫完所有的Target rba之前的臟塊.通知DBWR寫臟塊,這是CKPT的任務之一,CKPT另有一個任務,就是每3秒,檢測一次DBWR的寫進度.檢查點隊列最前面的塊被稱為檢查點位置.DBWR是沿著檢查點隊列寫臟塊的,CKPT每3秒鐘查看一下DBWR沿檢查點隊列寫到了哪里,并且將這個位置設置為檢查點位置.也就是說檢查點位置之前的塊,都是已被DBWR刷新到磁盤上的塊.這個3秒一次檢查DBWR進度的工作,也是CKPT的一個重要的任務.CKPT每3秒一次將檢查點位置記錄進控制文件,當然同時被記錄進控制文件的還有'心跳'等其他信息.CKPT每3秒一次的工作和CKPT定期觸發DBWR,這兩項操作合一起被稱為--增量檢查點.
下面的就是CKPT每3秒寫進控制文件的信息
SQL> alter session set events 'immediate trace name controlf level 8';
會話已更改。
具體內容如下:
***************************************************************************
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:89
low cache rba 0x2ad.908.0)[檢查點位置] on disk rba 0x2ad.d2f.0)[最后一條重做記錄的rba]
on disk scn: 0x0000.00237745 03/02/2008 15:03:44[最后一條重做記錄的scn]
resetlogs scn: 0x0000.0008297b 08/27/2007 09:51:58
heartbeat: 648318959[心跳] mount id: 1201288562
...
...
這里面的大多數信息可以通過x$kcccp中看到.
SQL> select
CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low
RBA",CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk
RBA",CPODS,CPODT,CPHBT from x$kcccp;
CPDRT Low
RBA On disk
RBA CPODS CPODT CPHBT
---------- --------------- --------------- ----------------
-------------------- ----------
35
686.124.0 686.220.0 2325376 03/02/2008
15:18:54 648319278
說明:
CPDRT列是檢查點隊列中的臟塊數目.
CPODS列是on disk rba的scn
CPODT列是on disk rba的時間戳
CPHBT列是心跳
檢查點位置是是個rba,他指向著重做日志文件中的某個重做記錄.在此位置前的重做記錄,其對應的信息已經被寫進了數據文件,在此位置后的重做記錄,所對應的是數據塊,有可能還在內存中.如果發生了實例崩潰,只需要在日志文件中找到檢查點位置,從此處開始應用所有的重做日志文件,就完成了前滾操作.實例崩潰后,再次啟動數據庫,oracle會到控制文件中讀取low cache rba,這就是檢查點位置.從此處開始應用重做信息,應用到on disk rba處.on
disk rba是磁盤中重做日志文件的最后一條重做記錄的rba. 如果某條命令的重做記錄的rba高于on disk rba,那說明此重做記錄還沒有被寫進日志文件中,崩潰發生時,他是不可能被恢復的.on disk rba是oracle前滾操作的終點.on disk 顧名思義 就是'在磁盤上'的意思.比這個更高的rba,都在log buffer中,還沒有來的急被寫進磁盤中的日志文件.所以是不能被用于恢復的.下面假設一個實例恢復的例子:
Table表每行2000個字節,塊大小8K,每塊可容納table的3行,按如下發布7條更新命令:
Update table set name=low(name) where id=1; ------塊1 RBA :692.2998.10
Update table set name=low(name) where id=2; ------塊1
RBA :692.3015.10
Update table set name=low(name) where id=4; ------塊2
RBA :692.3024.10
Update table set name=low(name) where id=7; ------塊3
RBA :692.3033.10
Update table set name=low(name) where id=3; ------塊1
RBA :692.3102.10
Update table set name=low(name) where id=10; ------塊4
RBA :692.3127.10
Update table set name=low(name) where id=13; ------塊5
RBA :692.3136.10
上面七條更新命令后,每塊狀態為:
1號塊 | 2號塊 | 3號塊 | 4號塊 | 5號塊 | ||
Lrba:692.2998.10 Hrba:692.3102.10 | Lrba:692.3024.10 Hrba:692.3024.10 | Lrba:692.3033.10 Hrba:692.3033.10 | Lrba:692.3127.10 Hrba:692.3127.10 | Lrba:692.3136.10 Hrba:692.3136.10 |
Lrba就是塊首次變臟時的RBA,而Hrba,是最后一次改變塊中信息,所對應的重做記錄的RBA。1號塊外被修改兩次,Lrba和Hrba不同。2到5號塊只被修改一次,Lrba和Hrba相同。相應的重做記錄有:
RBA:692.2998.10(第一條更新命令對應的重做記錄) 回滾段頭重做信息 回滾段塊重做信息 1號塊第1行重做信息 (下面的重做記錄中省略具體的信息) |
RBA:692.3015.10 (第二條更新命令對應的重做記錄) |
RBA:692.3024.10 (第三條更新命令對應的重做記錄) |
RBA:692.3033.10 (第四條更新命令對應的重做記錄) |
RBA:692.3102.10 (第五條更新命令對應的重做記錄) |
RBA:692.3127.10 (第六條更新命令對應的重做記錄) |
RBA:692.3136.10 (第七條更新命令對應的重做記錄) |
假如此時,1號塊和2號塊已經變得不臟,3、4、5號塊仍是臟塊,所有的臟塊依Lrba順序按列為檢查點隊列,其中檢查點隊列頭(此處是3號塊)的Lrba就是檢查點位置,此處為692.3033.10。這個值被記錄在控制文件中。如果發生了實例崩潰,Oracle將從控制文件中取出692.3033.10,到692號重做日志中,找到第3033塊,從此處開始,應用所有的重做日志,直到重做日志文件的最未尾。而重做日志文件的最未尾重做記錄的RBA,又叫On disk rba。從檢查點位置處,應用重做記錄到On disk rba處,這個過程就是前滾。
如下幾個參數可以用來限制檢查點隊列的長度:
1,fast_start_io_target
該參數用于表示數據庫發生Instance
Recovery 的時候需要產生的IO總數,他通過v$filestat的AVGIOTIM來估算的.比如我們一個數據庫發生Instance Crash后需要在10分鐘內恢復完畢,假定OS的IO每秒為500個,那么這個數據庫發生Instance Recovery的時候大概產生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這么一個參數,用于表示數據庫發生Instance Recovery的時間.以秒為單位,這個參數我們從字面上也比較好理解,其中的mttr是mean time to recovery的簡寫,如上例中的情況我們可以將fast_start_mttr_target設置為600.當設置了fast_start_mttr_target后,fast_start_io_target這個參數將不再生效,從9I后fast_start_io_target這個參數被oracle廢除了.
3,log_checkpoint_timeout
該參數用于表示檢查點位置和重做日志尾之間的時間間隔,以秒為單位,默認情況下是1800秒,這個參數實際上表示了臟塊保持臟狀態的最長時間.如果它被定為1800秒,沒有臟塊保持1800秒后,還是為臟.設log_checkpoint_timeout為1800秒.
相比fast_start_mttr_target,它也是時間,但它的時間值表示完成恢復操作所需要的時間,即從最后的檢查點位置開始,應用所有日志直到日志末尾所需要的時間.而本參數表示從最后的檢查點位置開始,到日志末尾經過的時間.在標準版中,本參數的最小值是900.
4,log_checkpoint_interval
該參數是表示檢查點位置和重做日志末尾的塊的數量.以OS表示.
5,90% OF SMALLEST REDO LOG
Oracle內部事實上還將重做日志末尾前面90%的位置設為檢查點位置,這不是一個參數,這是oracle內部規定的一個觸發增量檢查點的事件.上面這些條件,嚴格來說,并不是控制檢查點什么時候發生,而是控制檢查點隊列中可以有多少個塊.在前4個參數中,9I中oracle推薦使用fast_start_mttr_target替代第一個fast_start_io_target.fast_start_mttr_target,log_checkpoint_timeout,log_checkpoint_interval和90% OF SMALLEST REDO LOG 可以同時使用.考慮這樣一種情況,如果上面的這些觸發增量檢查點的參數都被設置,并且在某一時刻,這幾個參數一起被觸發,但他們指定的Target
RBA位置可能不盡相同,oracle將離日志末尾最近的那個位置認為檢查點位置,如下圖所示:
在這種情況下,將會把log_checkpoint_interval的位置定為下一增量檢查點的Target
RBA.在9I后,對檢查點頻率,建議只設置fast_start_mttr_target.根據需要,也可以通過設置log_checkpoint_timeout,設置一個臟塊保持臟狀態的最大時間,而其他兩個參數
fast_start_io_target,log_checkpoint_interval建議不再使用.
Oracle寫臟塊并不一定都從檢查點隊列中寫.在v$sysstat視圖中,有兩項關于物理寫的資料.physical writes 和physical writes non
checkpoint.也就是說,oracle將對臟塊的寫分為兩類.一類是通過檢查點的寫,一類是不通過檢查點的寫.我把它叫做檢查點無關寫.比如說:當表空間脫機時,會把隸屬于該表空間的所有臟塊都寫進數據文件,但是不會發生檢查點,這個寫就是檢查點無關寫. 還有其他的情況會發生檢查點無關寫,我會在以后的實驗中介紹.一個小實驗,證明下檢查點無關寫:為了避免檢查點對實驗的影響,將檢查點的發生頻率設置的低一些.
命令如下:
alter system set fast_start_mttr_target=0;
alter system set log_checkpoint_timeout=3600;
步驟一:在實驗前先觀察下當前物理寫的值:
SQL> select * from v$sysstat where name='physical writes non checkpoint';
STATISTIC#
NAME CLASS VALUE STAT_ID
---------- ------------------------------ ---------- ---------- ----------
67 physical writes non
checkpoint 8 3738
2602029796
步驟二:隨便開始一個事務
SQL> update jj_10 set name='aa' where id=20;
已更新 1 行。
步驟三:把步驟二中的表脫機:
SQL> alter tablespace jj_ts_1 offline;
表空間已更改。
步驟四:此時再去查看資料視圖:
SQL> select * from v$sysstat where name='physical writes non checkpoint';
STATISTIC#
NAME CLASS VALUE STAT_ID
---------- ------------------------------ ---------- ---------- ----------
67 physical writes non
checkpoint 8 3759
2602029796
比較后發現,檢查點無關寫從3738增加到3759.為了觀察到通過檢查點隊列的寫,把檢查點頻率調的高一點:
alter system set log_checkpoint_timeout=10;
步驟一:
SQL> select * from v$sysstat where name='physical writes' or name='physical
writes non
checkpoint';
STATISTIC#
NAME CLASS VALUE STAT_ID
---------- ------------------------------ ---------- ---------- ----------
62 physical
writes 8 5822
1190468109
67 physical writes non
checkpoint 8 3829
2602029796
用physical
writes減去physical writes non checkpoint所得到的結果,將近似于通過檢查點隊列的寫.為什么說近似于呢?因為oracle內部會有很多寫,比如說控制文件的寫操作,也會被記錄進physical writes資料.
步驟二:發布更新命令
SQL> update jj_10 set name='aa' where id=20;
已更新 1 行。
步驟三:觀察塊是否變的不臟.
SQL> select dirty,status from v$bh where file#=7 and block#=406 and
status='xcur';
D STATUS
- -------
N xcur
步驟四:在塊變的不臟后,馬上查看資料視圖.
SQL> select * from v$sysstat where name='physical writes' or name='physical
writes non
checkpoint';
STATISTIC#
NAME CLASS VALUE STAT_ID
---------- ------------------------------ ---------- ---------- ----------
62 physical
writes 8 5851
1190468109
67 physical writes non
checkpoint 8 3832
2602029796
可以看到檢查點無關寫多了3個字節,這3個字節和我們的更新聲明沒有關系.我們的更新聲明更新了幾十個字節.這3個字節應該是屬于oracle內部的一些寫操作,我們的更新聲明,所產生的臟塊,是通過檢查點隊列寫出的.physical writes 多了很多。
上述就是小編為大家分享的Oracle的增量檢查點指的是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。