ORACLE讀寫磁盤經過的緩存
Cache和Buffer是兩個不同的概念,簡單的說,Cache是加速“讀”,而buffer是緩沖“寫”,前者解決讀的問題,保存從磁盤上讀出的數據,後者是解決寫的問題,保存即將要寫入到磁盤上的數據。在很多情況下,這兩個名詞並沒有嚴格區分,常常把讀寫混合類型稱為buffer cache,本文後續的論述中,統一稱為cache。
Oracle中的log buffer是解決redo寫入的問題,而data buffer cache則解決data block的讀寫問題。對於Oracle來說,如果IO沒有在SGA中命中,都會發生物理IO,Oracle並不關心底層存儲的類型,可能是一套存儲系統,可能是本地磁盤,可能是RAID 10,也可能是RAID 5,可能是文件系統,也可能是裸設備,或是ASM。總之,Oracle把底層的存儲系統稱為存儲子系統。
在存儲系統中,cache幾乎無處不在(在後面的論述中,我們統稱為cache),文件系統有cache,存儲有cache,RAID控制器上有cache,磁盤上也有cache。為了提高性能,Oracle的一個寫操作,很有可能寫在存儲的cache上就返回了,如果這時存儲系統發生問題,Oracle如何來保證數據一致性的問題。
首先先說明一下oracle體系結構裡面會出現緩存的地方:
1、oracle緩存(包括PGA/SGA);
2、OS緩存(其實這個一直都有點歧義,我個人感覺應該是說文件系統的緩存,所以說如果是裸設備的話就會沒有OS緩存這個說法);
3、存儲緩存;
4、硬盤緩存;(如果使用的是存儲,硬盤緩存通常都是關掉的。存儲的電池,一般只保護存儲CACHE,不對硬盤緩存提供保護。如果沒使用存儲,我們之前的做法,是禁掉硬盤緩存。)
5、cpu一二級緩存。
Oracle的Buffer Cache和操作系統的Cache Buffer誰更有效率。其實無論誰,都很有效率,但為什麼通常建議繞過OS 文件系統的CACHE呢,這是因為數據庫的Buffer Cache是針對數據庫設計的,OS 文件系統層CACHE是通用型的,所以在有些情況下,OS層CACHE不如Oracle Buffer Cache表現更好。
一般讀流程:
CPU------一二級緩存(如有)-----SGA-----OS(如有)------存儲coache-----硬盤coache------存儲物理
一般寫寫流程:
CPU-----SGA-----存儲coache-----存儲物理
相關CACHE L1、L2 CACHE的,在Oracle中不必關心,因為無法觀察。如果對這一塊感興趣,推薦一本書《深入理解計算機系統》,有比較詳細的CPU 一、二級CACHE原理。還有就是,硬盤CACHE大部分是關閉的,如果沒關,建議關閉,否則有可能丟失數據。
Oracle數據庫最重要的特性是:Write ahead logging,在data block在寫入前,必須保證首先寫入redo log,在事務commit時,同時必須保證redo log被寫入。Oracle為了保證數據的一致性,對於redo log采用了direct IO,Direct IO會跳過了OS上文件系統的cache這一層。但是,OS管不了存儲這一層,雖然跳過了文件系統的cache,但是依然可能寫在存儲的cache上。
一般的存儲都有cache,為了提高性能,寫操作在cache上完成就返回給OS了,我們稱這種寫操作為writeback,為了保證掉電時cache中的內容不會丟失,存儲都有電池保護,這些電池可以供存儲在掉電後工作一定時間,保證cache中的數據被刷入磁盤,不會丟失。不同於UPS,電池能夠支撐的時間很短,一般都在30分鐘以內,只要保證cache中的數據被寫入就可以了。存儲可以關閉寫cache,這時所有的寫操作必須寫入到磁盤才返回,我們稱這種寫操作為writethrouogh,當存儲發現某些部件不正常時,存儲會自動關閉寫cache,這時寫性能會下降。
RAID卡上也有cache,目前一般是256MB或者更大,同樣是通過電池來保護的,不同於存儲的是,這個電池並不保證數據可以被寫入到磁盤上,而是為cache供電以保護數據不丟失,一般可以支撐幾天的時間。還有些RAID卡上有flashcache,掉電後可以將cache中的內容寫入到flash cache中,保證數據不丟失。如果你的數據庫沒有存儲,而是放在普通PC機的本地硬盤之上的,一定要確認主機中的RAID卡是否有電池,很多硬件提供商默認是不配置電池的。當然,RAID卡上的cache同樣可以選擇關閉。
磁盤上的cache,一般是16MB-64MB,很多存儲廠商都明確表示,存儲中磁盤的cache是禁用的,這也是可以理解的,為了保證數據可靠性,而存儲本身又提供了非常大的cache,相比較而言,磁盤上的cache就不再那麼重要。SCSI指令中有一個FUA(Force Unit Access)的參數,設置這個參數時,寫操作必須在磁盤上完成才可以返回,相當於禁用了磁盤的寫cache。雖然沒有查證到資料,但是我個人認為一旦磁盤被接入到RAID控制器中,寫cache就會被禁用,這也是為了數據可靠性的考慮,我相信存儲廠商應該會考慮這個問題。
至此,我們可以看到Oracle的一個物理IO是經歷了一系列的cache之後,最終被寫入到磁盤上。cache雖然可以提高性能,但是也要考慮掉電保護的問題。關於數據的一致性,是由Oracle數據庫,操作系統和存儲子系統共同來保證的。