Oracle ---- 同一个SQL文在RAC环境多个节点的结果一定相同吗?

昨天遇到一个有趣的问题:同一个SQL文在RAC环境多个节点的结果一定相同吗?

答案是:that depends

依存什么呢? 当然是SQL文本身了。

举个简单的例子:

  select *
   from test T1 
   where T1.c1 > 'xxxx'
     and  rownum <= 10;

在上面的SQL文中,首先检索出来的是满足" T1.c1 > 'xxxx' "条件所有数据,然后再返回这个结果集的前10行。

于是,有了这样一种可能性:如果满足" T1.c1 > 'xxxx' "条件的中间结果集在不同RAC节点的排序不同的话,这个SQL文的结果就会不同。

这是不是Bug呢?当然不是。

因为RAC的每个节点返回的结果都是满足SQL文的所有的检索条件的。
也就是说,虽然返回结果不同,但没有" Wrong Result "发生。

那有哪些条件可以造成中间结果的Sort顺不同呢?

简单地说,如果没有使用" 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环境就会比单机环境还慢,没有存在的意义了。

你可能感兴趣的:(数据库oracle)