2012-04-04 76 views
3

这里是场景...ORACLE/ASP.NET:ORA-2020 - 数据库链接太多......这是什么原因造成的?

我们有一个内部网站运行最新版本的ODAC(Oracle客户端)。它打开数据库连接,运行存储过程或打包方法,然后断开连接。连接池已打开,目前我们在开发和测试环境下都使用11g版本,但在我们的生产环境下使用10gR2。这发生在生产上。

几天前,一个进程开始引发ORA-2020错误。该流程从我们内部网站的网页上调用。用户只需设置日期,点击按钮,并在另一个与网站分开的系统上启动作业。然而,调用本身使用数据库链接来运行一个函数。

我们搜索了SQL,发现它只使用那一个数据库链接。由于这些链接是基于每个会话并且用户不超过默认限制4,因此我们如何获得ORA-2020错误。

我们已经运行了大量的测试以试图超过4的默认限制。从我所记得的情况来看,ODAC在每次连接后运行一次提交,并且我似乎无法运行4个数据库链接,然后运行一个带有1个数据库链接的SQL,并且存在任何错误之后。我可以提出这个错误的唯一方法是如果我运行带有4个DB链接的查询,然后是一个包含数据库链接的函数或动态SQL。我们没有这个问题,因为这个问题是零星的。这并不总是发生。

问题

  1. 是否有可能连接池是允许用户B使用用户A的连接的初始过程运行之后,因此增加了打开链接数量,如果用户B运行在使用SQL语句更多数据库链接?
  2. 这是我们应该超过4的限制吗?增加号码的缺点是什么?
  3. 在从数据库断开连接之前,是否需要显式关闭打开的数据库链接? Oracle文档似乎表明它应该自动发生,但“有时”......不。

回答

1

我们最终增加了链接数量,但我们从未找到根本原因。

2

首先,简单的解决方案:我会仔细检查,在生产数据库的默认链接的数量是实际上 4.

select * 
    from v$system_parameter 
where name = 'OPEN_LINKS' 

假如你不打算下车即到轻轻:

是否有可能连接池是允许用户B使用用户 初始处理后A的连接被运行,从而增加了 打开链接号如果用户B运行SQL语句与更多数据库 链接?

你说你明确地关闭了会话,根据the documentation,该会话应该表示与该会话关联的所有链接都关闭。除此之外,我承认在这一点上完全无知。

这是我们应该超过4的限制吗?增加号码的缺点是什么?

我想不出有什么缺点。 Tom Kyte suggests,尽管很久以前,每个打开的数据库链接都使用500k的PGA内存。如果你没有,那么这显然会造成一个问题,但在大多数情况下它应该是很好的。

但是,还是会有意想不到的后果:想象一下,你将这个数字提高到100.有些人编码的东西不断打开链接,并通过它们的所有select * from my_massive_table或类似的方式绘制大量数据。而不是4个会话这样做你有100个,这是试图同时传输数百GB。你的网络在应变下死亡...

有可能更多,但你得到的图片。

从数据库断开 之前,是否需要显式关闭打开的数据库链接? Oracle文档似乎暗示应该自动发生 ,但“有时”......不。

正如你已经注意到的最好的答案是“可能不是”,这是没有多大的帮助。你没有提到你是如何终止会议的,但是如果你是在杀死它而不是优雅地关闭,那么肯定会。

使用数据库链接会在远程服务器上产生子进程。因为你的服务器不再是这个过程的绝对主管,所以有很多事情可能导致它在父进程终止时变成孤立或者不关闭。这决不是整个过程都会发生,但它可以做到。

我会做两件事。

  1. 在您的过程中,如果遇到异常,请将以下查询的结果通过电子邮件发送给您自己。

    select * 
        from v$dblink 
    

    至少你会知道在会话中打开了哪些数据库链接,并给你一些跟踪它们的方法。

  2. 请按照文件建议;具体如下:

    • 通过链路建立的网络连接是在应用程序中不经常使用的:

      “你可能有机会手动关闭链路。例如,靠近 时链接。

    • 用户会话必须终止。“

第一似乎正好适合你的情况。除非你的过程是时间敏感的,但似乎并非如此,那么你有什么损失?语法是:

alter session close database link <linkname> 
+0

经过更多测试后,第一个问题得到解答。至少在我们的11g环境中进行测试时,这绝对是不可能的。为每个事务创建一个连接,并且ODP.NET隐式提交并且连接被关闭并放置在我们的代码中。我们无法抓住另一个连接并使用会话。我们正在添加一些跟踪来查看发生错误时链接是否打开。 – jlrolin 2012-04-09 18:12:59

相关问题