Heim  >  Artikel  >  Datenbank  >  RAC环境下序列缓存导致数据库序列不同步

RAC环境下序列缓存导致数据库序列不同步

WBOY
WBOYOriginal
2016-06-07 17:04:591214Durchsuche

其实问题出在了数据库是个RAC环境,序列是要被共享的,而且查看序列的创建语句,序列的cache 是8000,是有缓存的。rac两节点中若

一、【问题描述】

最近,客户提出,KC70的医疗账户使用余额与KC04中的账户余额不一致。

二、【分析过程】

根据数据库后台包查得,后台包是根据KC70中最大的OAE001取每个人当前的余额,按照正常的思路,序列是递增的,应该不会有问题。

查询该人的KC70(如上图),发现有两条记录变更前金额一致。仔细观察发现2010-11-4 8:35产生的KC70记录的OAE001居然要比后来2010-11-4 20:25产生的OAE011还要大。导致取变更后金额时都取的OAE001大的那条记录,导致错误。

1、  是否存在调用不同的序列?

查看后台包过程,发现KC70调用的统一的是seq_a_rowid 这个序列。不存在调用不用序列的问题。

2、  因为用的是数据库集群,会不会同一个序列在不同数据库实例里是不一样的?

通过PL/SQL观察,发现两个数据库实例的seq_a_rowid序列的开始值一样。

3、  用PL/SQL同时连接两个实例(1和3),同时执行SELECT seq_a_rowid.nextval FROM dual 发现取得的两个实例居然不是连续的,而且对比两个产生的序列值,,有时候实例1比实例3产生的序列大,有时候实例3又比实例1大。

三、【解决途径】

其实问题出在了数据库是个RAC环境,序列是要被共享的,而且查看序列的创建语句,序列的cache 是8000,是有缓存的。rac两节点中若序列的cache为20的话,在节点一上cache了1-20个,然后节点二上cache了20-40。当从不同的节点来进行对sequence取值的时候,会造成先取的值不一定是小的,后取的值不一定会大。而且默认序列都是noordered的。因此完全有可能会出现这种情况:

在节点1先执行SELECT seq_a_rowid.nextval FROM dual;的值比节点2后执行SELECT seq_a_rowid.nextval FROM dual;大。

具体的说解决办法有2个:

1、设置cache 的值为空。(通过PLSQL查看显示为0);

2、创建序列的时候,增加order属性,使用cache+order属性 ;

简便方法:

用PL/SQL DEVELOPER 打开序列设置该序列高速缓存大小为0,或者排序(ORDER)选项打上。

Oracle为了管理sequence使用了以下三种锁:

* row cache lock :调用sequence.nextval过程中(nocache)

* SQ锁 : 调用sequence.nextval过程中(cache+noorder)

* SV锁(dfs lock handel) :RAC上节点之间顺序得到保障的的前提下,调用sequence.nextval期间拥有。赋予了cache + order属性的sequence上发生。 (cache+order)

row cache lock的目的是在sequence指定nocache的情况下调用sequence.nextval过程中保证序列的顺序性;

cache参数告诉oracle预先分配一个sequence numbers的集合,并且保留在内存中,以便sequence number能够被快速的访问。这个内存的大小就是cache所指定的大小,当多个用户同时访问一个sequence的时候,是在oracle SGA中读取sequence当前的合理数值,如果并发访问太大,cache的大小不够,那么就会产生sequence cache相关的等待(enq: SQ - contention),影响系统性能。

在RAC多节点环境下,Sequence的Cache属性对性能的影响很大。应该尽量赋予cache+noorder属性,并要给予足够的cache值。

如果需要保障顺序,必须赋予cache+order属性。但这时为了保障顺序,实例之间需要不断的交换数据。因此性能稍差。

四、【经验总结】

虽然设置cache 的值为空也可以解决问题,但会使得程序在集群环境中的性能得到很大的降低。所以请在一般情况下,请使用增加ORDER的方式。

在集群环境下,对序列大小顺序有要求的时候,必须对按上述的方式对序列进行控制。

linux

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn