關於ORACLE 和MYSQL INNODB 觸發髒資料寫的機制對比

gaopengtttt發表於2015-08-07



首先要說明在ORACLE和INNODB觸發checkpoint方面都採用LRU進行管理,並且都有全量檢查點和增量檢查點一說
在MYSQL中全量檢查點叫做sharp checkpoint,增量檢查點叫做FUZZY CHECKPOINT,


在ORACLE中更加細化,加入了LRUW連結串列,並且加入CHECKPOINT-Q列表,兩者共同配合完成增量CHECKPOINT,在ORACLE
中DBWR寫是按照CHECKPOINT-Q的順序寫的其是LRBA的連結串列,其觸發條件受到MTTR的限制,如果ORACL估計能夠達到INSTANCE
CRASH RECOVERY的時間就會不觸發CHECKPOINT-Q寫,而加入LRUW列表更是為了減輕按照CHECKPOINT-Q來寫的負擔,如果檢查到
哪些每3秒訪問少2次的髒塊就會從LRU中拿下計入LRUW,等待DBWR3秒醒來觸發寫,對於3秒訪問大於等於2次的髒塊,依然按照
checkpoint-Q來寫,因為很可能還會修改,寫完後從CHECKPOINT-Q下摘下。這樣LRUW基本就是為了那些修改次數少的髒塊而生的,
目的在於優先寫入修改次數少髒塊減輕CHECKPOINT-Q增量檢查點壓力。
其實在ORACLE中LRU和LRUW都分為輔助和主列兩個,關於這一點是為了加快掃描LRU的效率,詳細參加呂海波ORACLE核心揭秘
這裡給出ORACLE寫髒塊的機制(來自呂海波ORACLE核心揭秘)
1、DBWR 3秒寫冷髒塊上面說的3秒內訪問一次的髒塊
2、CHEKPOINT-Q 寫入,他也是DBWR來判斷的如果不能滿足MTTR的設定就開始寫,由CKPT修改CONTROLFILE裡面的各種資訊,重要的
就是LRBA,關於LRBA和髒塊數量可能透過X$KCCCP來檢視
3、伺服器程式掃描LRU發現25%的髒塊直接出發DBWR寫,不需要等待3秒,從LRUW進行寫,有隱含引數_db_large_dirty_queue控制預設25%
4、伺服器程式掃描超過40%的BUFFER沒有找到可用的BUFFER來快取新的資料塊,不需要等待3秒,從LRUW進行, 
   由隱含_db_block_max_scan_pct控制
5、各種全量檢查點
   alter system checkpoint
   SHUTDOWN DATABASE非ABORT
   log switch
   表空間OFFLINE 表空間一級檢查點
   DDL語句drop truncate等物件一級檢查點


在MYSQL中一切其實差不多,但是從MYSQL內幕innodb儲存引擎一書來看,所有的髒塊和乾淨的塊都在LRU列中,同時還存放了一份
在flush列表中(類似ORACLE的CHECKPOINT-q),同樣MASTER程式也是用來讀取FLUSH列表進行髒資料寫的,但是MYSQL沒有LRUW的
概念,所以所有的髒塊正常情況下都是衝FLUSH列表中的髒塊寫入的。
這裡給出MYSQL寫髒塊的機制(姜承曉MYSQL內幕innodb儲存引擎)
FUZZY CHECKPOINT
1、MASTER程式每秒或者每10秒從FLUSH列表中按照順序寫入髒塊
2、根據innodb_lru_scan_depth 引數設定預設5.6 1024,如果沒有PAGE CLEANR 程式發現沒有1024可用空閒頁,刷出LRU鏈尾端的頁
   如果有髒塊觸發髒塊寫show engine innodb status 來看及如下:
   Buffer pool size   70400
   Free buffers       32776--這裡
   Database pages     34879
   Old database pages 12711
   Modified db pages  662
   
3、根據日誌的使用情況,如果從show engine innodb status 來看及如下:
   Log sequence number 3100866076
   Log flushed up to   3100744765
   Pages flushed up to 3099998234
   Last checkpoint at  3099878300
   
   75%*日誌量>Log sequence number-Last checkpoint at 不需要觸發髒塊寫
   75%*日誌量<Log sequence number-Last checkpoint at<90%*日誌量觸發非同步寫
   Log sequence number-Last checkpoint at>90%*日誌量觸發同步寫

4、根據INNODB_MAX_DIRTY_PAGE_PCT設定預設75,當髒塊數量達到75%進行髒資料庫寫
   Buffer pool size   70400
   Free buffers       32776
   Database pages     34879
   Old database pages 12711
   Modified db pages  662  ---這裡
   
sharp checkpoint 只有在關閉資料庫的時候觸發並且INNODB_FAST_SHUTDOWN=1的情況下(預設設定)




由此來看ORACLE的第一條和第二條屬於正常重新整理他們對應了MYSQL第一條
ORACLE的第三條屬於髒塊過多重新整理對應MYSQL的第四條
ORACLE的第四條屬於沒有可用的BUFFER BLOCK對應MYSQL的第二條
ORACLE雖然沒有根據日誌量的使用情況來判斷是否需要寫髒塊,但是ORACLE實際每次SWITCH LOGFILE
都會觸發檢查點,那麼也就不存在這樣的問題了。
最後思考一個問題,ORACLE中實際上可能會出現髒資料寫趕不上日誌切換的速度會出現等待
Checkpoint not complete,這個時候可能要加大LOGFILE 組來滿足,或者減少LOG生成量,我想
MYSQL INNODB中應該也會有同樣的情況發生,但是沒有模擬出來,也不知道怎麼檢視。
我這裡對比只是為了更加加深兩種不同資料庫的CHECKPOINT和髒資料寫機制,同時加入了自己的一些理解,可能有誤
給出參考文獻尊重原著


參考:呂海波ORACLE核心揭秘
參考:姜承曉MYSQL內幕innodb儲存引擎

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-1764910/,如需轉載,請註明出處,否則將追究法律責任。

相關文章