昨天遇到一個有趣的問題:同一個SQL文在RAC環境多個節點的結果必定相同嗎?數據庫
答案是:that dependscode
依存什麼呢? 固然是SQL文自己了。排序
舉個簡單的例子:索引
select * from test T1 where T1.c1 > 'xxxx' and rownum <= 10;
在上面的SQL文中,首先檢索出來的是知足" T1.c1 > 'xxxx' "條件全部數據,而後再返回這個結果集的前10行。io
因而,有了這樣一種可能性:若是知足" T1.c1 > 'xxxx' "條件的中間結果集在不一樣RAC節點的排序不一樣的話,這個SQL文的結果就會不一樣。ast
這是否是Bug呢?固然不是。test
由於RAC的每一個節點返回的結果都是知足SQL文的全部的檢索條件的。
也就是說,雖然返回結果不一樣,但沒有" Wrong Result "發生。select
那有哪些條件能夠形成中間結果的Sort順不一樣呢?gc
簡單地說,若是沒有使用" Order by "句指定順序,就是SQL文執行過程當中內部處理順序,也就是數據塊和數據塊內Records的Access順序。若是使用了" Order by "句指定順序,那就在獲得中間結果集
再進行Sort處理。並行
下面是兩種之前遇到過的小例子。
第一個是12c導入的" Index BATCHED Access ",這種處理會把針對索引的單塊隨機訪問變爲多塊並行訪問,目的是改善" 隨機I/O "的影響。可是這種I/O會破壞原有索引的順序訪問而帶來的有序結果。使訪問結果順序變得不可預測。
第二種是RAC環境中,每一個數據塊都有" Master "節點,若是從" Master "節點之外的節點訪問這個數據塊,就須要先經過" Cache Fusion "讀取" Master "節點的數據塊。若是在非" Master "節點發行的SQL文須要訪問其餘節點的數據塊和本身節點的數據,這就會因爲內部處理的不一樣形成數據庫Access順序的不一樣。
這個問題能夠從10046 Trace裏看出一點端倪。
--Node1 WAIT #139656782947424: nam='gc current block 2-way' ela= 124 p1=98 p2=364159 p3=1 obj#=113146 tim=10700529845367 --Node2 沒有出現上面的Cache Fusion待機。
如今總結一下今天的話題:Rac環境並不保證相同的SQL文在不一樣的節點必定獲得相同的結果。Rac的每個Instance都是獨立的,只對SQL文負責,沒有義務對比不一樣節點的結果。若是那樣作,Rac環境就會比單機環境還慢,沒有存在的意義了。