热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

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

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

其实问题出在了数据库是个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

推荐阅读
  • SQL中UPDATE SET FROM语句的使用方法及应用场景
    本文详细介绍了SQL中UPDATE SET FROM语句的使用方法,通过具体示例展示了如何利用该语句高效地更新多表关联数据。适合数据库管理员和开发人员参考。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 在使用SQL Server进行动态SQL查询时,如果遇到LIKE语句无法正确返回预期结果的情况,通常是因为参数传递方式不当。本文将详细探讨这一问题,并提供解决方案及相关的技术背景。 ... [详细]
  • 本文介绍如何通过创建替代插入触发器,使对视图的插入操作能够正确更新相关的基本表。涉及的表包括:飞机(Aircraft)、员工(Employee)和认证(Certification)。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
author-avatar
问道摩托
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有