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