昨天遇到一个有趣的问题:同一个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环境就会比单机环境还慢,没有存在的意义了。