Oracle數(shù)據(jù)庫(kù)機(jī)Exadata自推出以后,因?yàn)樵跍p小帶寬占用,快速檢索等方面的優(yōu)勢(shì)而備受業(yè)界關(guān)注。但是對(duì)于具體的技術(shù)細(xì)節(jié),很多數(shù)據(jù)庫(kù)運(yùn)維人員并不是很了解。
自從 Oracle 和HP 推出Exadata 之后,我就很關(guān)注這個(gè)產(chǎn)品,之前也寫了一篇Oracle Database Machine介紹它。去年,Oracle和SUN合并后,推出了Oracle Exadata V2,相比較上一代產(chǎn)品有幾個(gè)變化:第一,使用SUN的硬件;第二,宣稱支持OLTP應(yīng)用;第三,Oracle 11g R2 提供了更多的新特性。Exadata Smart Flash Cache
Exadata V2整體架構(gòu)并沒有太多改變,換用了SUN的硬件,除了采用Intel最新的Nehalem CPU 以外,每臺(tái)Storage Cell 更是配置了384GB 的Flash,這也是為什么V2 可以支持OLTP 應(yīng)用的關(guān)鍵。
Flash Cache 完全是自動(dòng)管理,Oracle會(huì)根據(jù)數(shù)據(jù)的訪問情況,決定哪些數(shù)據(jù)放在 Flash Cache中。所有的數(shù)據(jù)都是先被寫到普通磁盤上,再根據(jù)訪問情況讀入Flash Cache的,所以如果 Flash Card 發(fā)生故障,數(shù)據(jù)不會(huì)丟失。當(dāng)然,Oracle提供了方式,可以讓用戶手動(dòng)將表或者索引Pin 在 Flash Cache 中。
在自動(dòng)管理的方式之外,Oracle還允許用戶人工創(chuàng)建flash disks,和普通磁盤一樣,這些Flash Disks通過ASM輸出給數(shù)據(jù)庫(kù)使用,用戶可以把一些訪問非常頻繁的數(shù)據(jù)文件放在上面。這些 Flash Disks 不僅僅是Cache了,所以 ASM 會(huì)在Cell和Cell之間做鏡像。如果某塊卡發(fā)生故障,那么整個(gè)Storage Cell上的Flash Disks會(huì)offline,保證數(shù)據(jù)不會(huì)丟失。
Smart Scan
Smart Scan是 Exadata最重要的一個(gè)功能,它的作用就是把SQL 放在每個(gè)Cell 上去運(yùn)行,然后每個(gè)Cell只返回符合條件的數(shù)據(jù)給數(shù)據(jù)庫(kù),這樣就極大的降低了數(shù)據(jù)庫(kù)服務(wù)器的負(fù)載和網(wǎng)絡(luò)流量,并充分利用了Cell的計(jì)算資源和IO資源。
傳統(tǒng)方式:所有的數(shù)據(jù)都需要返回給數(shù)據(jù)庫(kù)服務(wù)器,網(wǎng)絡(luò)帶寬要求高,所有的計(jì)算在數(shù)據(jù)庫(kù)服務(wù)器上完成。
Smart scan:只返回符合條件的數(shù)據(jù),減少網(wǎng)絡(luò)帶寬,并充分利用了Cell 上的計(jì)算和IO資源。
這里有一點(diǎn)要注意,在使用Smart Scan 時(shí),每個(gè)Cell返回給DB Server的是結(jié)果集,而不再是傳統(tǒng)的Block, DB Server 完成結(jié)果集的處理,并返回給客戶端。
Smart Scan 如何處理 Join ?
這是我一直想要搞清楚的問題。事實(shí)上, Smart Scan 只能處理Join filtering,而真正Join的工作必須在DB Server上完成,而且Smart Scan 僅適合于處理 DSS 環(huán)境的復(fù)雜Join,對(duì)于 OLTP 類型的簡(jiǎn)單Join,Smart Scan 并不能發(fā)揮其優(yōu)勢(shì)。設(shè)想下面的查詢:
select e.ename,d.dname from emp e, dept d where and e.ename='Jacky' and e.deptno=d.deptno; 假設(shè)采用nested loops join,Smart Scan 只能完成 e.ename='Jacky' 這個(gè)條件的過濾,然后將符合條件的 emp 表的數(shù)據(jù)返回到 DB server,然后由 DB Server 完成 join 的工作,逐條查詢dept表 (e.deptno=d.deptno) 的數(shù)據(jù)。所以Smart Scan 并不適合nested loop join(我認(rèn)為 Smart Scan 只有在適合的條件下才會(huì)啟用),只有 DSS 環(huán)境的大數(shù)據(jù)量復(fù)雜join才會(huì)發(fā)揮出優(yōu)勢(shì)。而且 Smart Scan 只能完成filtering的工作,而不能真正完成Join 的工作,這個(gè)與Greenplum 數(shù)據(jù)庫(kù)是不同的(有興趣可以看我的文章,Greenplum技術(shù)淺析)。設(shè)想下面的查詢(emp和dept都是大表):
select e.ename,d.dname from emp e, dept d where e.deptno=d.deptno; 假設(shè)采用Hash Join ,由于沒有任何過濾條件,Smart Scan只能把兩個(gè)表的數(shù)據(jù)全部返回到DB Server 上進(jìn)行join操作,不過Smart Scan也不是一點(diǎn)用都沒有,至少還可以進(jìn)行column 的過濾,只返回需要的字段就可以了。
Oracle的文檔中,曾經(jīng)提到對(duì)于一個(gè)大表和小表join時(shí),Smart Scan會(huì)采用bloom filter來快速定位(可以看我以前的文章,有趣的bloom filter )。方法是把小表build成為bloom filter,然后在每個(gè)storage cell上對(duì)大表做scan,利用bloom filter快速定位符合條件的結(jié)果,并返回給DB Server 作 join。
Storage Index
存儲(chǔ)索引,顧名思義是在存儲(chǔ)級(jí)別建立的索引,簡(jiǎn)單的說就是為表中的每一列數(shù)據(jù)建立一個(gè)索引,每個(gè)index entry記錄一段數(shù)據(jù)區(qū)間的最大值,最小值以及它們的物理位置,文檔上說1MB數(shù)據(jù)對(duì)應(yīng)一條index entry,見下圖:
如果我們查詢B<2,或者B>8的數(shù)據(jù),根據(jù)存儲(chǔ)索引,我們就可以跳過這些不在min和max之間的數(shù)據(jù)塊,極大的提高了掃描的速度,這就是存儲(chǔ)索引的意義。
Hybrid Columnar Compress
首先我們要搞清楚,什么是行壓縮,什么叫列壓縮。我們熟悉的數(shù)據(jù)庫(kù),如Oracle、MySQL等都是基于行的數(shù)據(jù)庫(kù),就是行的不同字段物理上存放在一起,還有一種是基于列的數(shù)據(jù)庫(kù),就是每個(gè)字段的不同行物理上存放在一起。他們的優(yōu)缺點(diǎn)同樣突出:
基于行的數(shù)據(jù)庫(kù),訪問一行非常方便,但是由于同一列的數(shù)據(jù)是分開存放的,如果要針對(duì)某一列進(jìn)行查詢時(shí),幾乎要掃描整個(gè)表才能得到結(jié)果;谛袛(shù)據(jù)庫(kù)的壓縮,稱為行壓縮。
基于列的數(shù)據(jù)庫(kù),因?yàn)橥涣械臄?shù)據(jù)物理上放在一起,所以訪問一列非常方便,也就是說如果針對(duì)某一列進(jìn)行查詢時(shí),不需要掃描整個(gè)表,只需要掃描這一列的數(shù)據(jù)就可以了,但是訪問一行的全部字段非常不方便(又是廢話);诹袛(shù)據(jù)庫(kù)的壓縮,稱為列壓縮。
Oracle 通常說的 compress 功能(包括11g R2的Advanced compress),都是行壓縮,因?yàn)镺racle是個(gè)基于行的數(shù)據(jù)庫(kù)。大概的方法就是在block頭部存放一個(gè)symbol table,然后將相同的值放在那里,每行上相同的數(shù)據(jù)指向symbol table,以此來達(dá)到壓縮的目的。行壓縮的效果通常不好,因?yàn)槲覀冎佬信c行之間,其實(shí)相同的數(shù)據(jù)并不多。但是列壓縮則不同,因?yàn)橄嗤械臄?shù)據(jù)類型相同,很容易達(dá)到很好的壓縮效果。
行壓縮和列壓縮都有其優(yōu)缺點(diǎn),而Oracle的混合列壓縮技術(shù),實(shí)際上是融合了列壓縮的高壓縮比和行數(shù)據(jù)庫(kù)的訪問特性,將兩者的優(yōu)點(diǎn)結(jié)合起來。Oracle提出了 CU 的概念(compress unit),在一個(gè) CU 內(nèi),是一個(gè)基于列的存儲(chǔ)方式,采用列壓縮,但是一個(gè) CU 內(nèi)保存了行的所有字段信息,所以在CU與CU之間,Oracle還是一個(gè)基于行的數(shù)據(jù)庫(kù),訪問某一行,總是只在一個(gè) CU 內(nèi)(一個(gè)CU總是在一個(gè)block內(nèi))。