rac环境导致的sequence序列号混乱
(2016-01-13 22:34:13)分类: Oracle |
最近把一套系统从单机迁移到rac上之后,开发人员反映在插入数据的时候,序列号产生的主键id出现混乱,没有连续性。一开始以为是dblink分布式事务导致的,
经过排查之后,确定是有sequence的缓存引起的。
Oracle在创建序列(sequence)时有个参数你可以选择cache或者nocache,如果指定CACHE值,Oracle就可以预先在内存里面放置一些Sequence,这样存取的快些。cache里面的取完后,Oracle自动再取一组到cache。使用cache或许会跳号,比如数据库突然不正常down掉(shutdown abort),cache中的Sequence就会丢失。
举个例子:比如你的sequence中cache100,那当你sequence取到90时突然断电,那么在你重启数据库后,sequence的值将从101开始。
如果指定NOCACHE值,Oracle就不会预先在内存里面存放Sequence,当然这也就可以避免数据库不正常down掉的sequence丢失。不过会产生一些问题:创建nocache sequence在高并发访问时,容易导致row cache lock等待事件,主要原因是每次获取nextval时都需要修改rowcache中的字典信息。
没有指定这个参数的话,oracle默认会指定cache20。这对一些对sequence的序列号高度敏感的系统来说,有致命影响。因为在rac上,几个节点会同时缓存sequence,在生成数据的时候,就会导致序列号跟时间匹配不上,从而出现序列混乱的问题。
在一些对序列号没有严格要求的系统上,建议是设置cache的,这样可以避免一些性能问题。
由于每次修改字典信息都需要commit,可能导致logfile sync等待,nocache sequence在RAC环境下,会对基于sequence生成的列创建的索引造成实例间大量索引块争用。
经过排查之后,确定是有sequence的缓存引起的。
Oracle在创建序列(sequence)时有个参数你可以选择cache或者nocache,如果指定CACHE值,Oracle就可以预先在内存里面放置一些Sequence,这样存取的快些。cache里面的取完后,Oracle自动再取一组到cache。使用cache或许会跳号,
举个例子:比如你的sequence中cache
如果指定NOCACHE值,Oracle就不会预先在内存里面存放Sequence,当然这也就可以避免数据库不正常down掉的sequence丢失。不过会产生一些问题:创建nocache
没有指定这个参数的话,oracle默认会指定cache
在一些对序列号没有严格要求的系统上,建议是设置cache的,这样可以避免一些性能问题。
由于每次修改字典信息都需要commit,可能导致log