【问题标题】:How to detect Oracle broken/stalled connection?如何检测 Oracle 断开/停滞的连接?
【发布时间】:2010-11-28 17:29:24
【问题描述】:

在我们的服务器/客户端设置中,我们遇到了一些奇怪的行为。客户端是一个 C/C++ 应用程序,它使用 OCI 连接到 Oracle 服务器(使用 OTL 库)。

数据库服务器时不时地以某种方式死机(是的,这是核心问题,但从应用程序端我们无法解决它,但无论如何都必须处理它),机器不再响应到新的请求/连接,但现有的请求/连接,如 Oracle 连接,不会丢失或超时。发送到数据库的查询再也不会成功返回。

Oracle 提供了哪些可能性(如果有)来从客户端应用程序端检测这些停滞的连接并以或多或少安全的方式恢复?

【问题讨论】:

  • +1,我有一个与 DB Link 上的 SQL 命令相关的问题。该链接在接受连接时会出现问题,但命令只是挂起。

标签: c++ oracle database-connection oracle-call-interface otl


【解决方案1】:

在 11.1.0.6 之前,这是 Oracle 中的一个错误(或称其为功能),他们说 Oracle 11g 第 1 版(补丁 11.1.0.7)上的补丁已修复。需要看到那个。 如果发生这种情况,您将不得不取消( kill )执行此操作的线程。 虽然不是很好的方法

【讨论】:

  • 因为这是很长一段时间以来最有用的提示,并引导我查看补丁集的更改日志 (anysql.net/doc/bug11107.html#OCI),所以我最终接受了这个作为最佳答案。谢谢。
【解决方案2】:

在我所有的数据库模式中,我都有一个包含一个常量记录的表。只需通过简单的 SQL 请求定期轮询此类表。所有其他方法都不可靠。

【讨论】:

  • 正如我的问题中所述,这样的定期提取最终会锁定并且永远不会再返回。我需要的是检测这种可能已经停止连接的情况并恢复它们的可能性。
【解决方案3】:

OTL 中有一个 set_timeout API 可能对此有用。

编辑:实际上,忽略这一点。 set_timeout 不适用于 OCI。查看来自hereset_timeout 描述,其中描述了一种可与OCI 一起使用的技术

【讨论】:

  • 您指的是解决方法,其中另一个线程监视执行请求的线程并在它认为连接已死时启动 otl_connect->cancel()?
【解决方案4】:

听起来您需要启动对数据库的查询(例如SELECT * FROM dual;),然后如果数据库在指定的时间内没有响应,则假设服务器已死并做出相应的反应。恐怕我不懂 C/C++,但你能用多线程触发语句然后等待响应,而不挂起应用程序吗?

【讨论】:

  • 我已经在做这样的事情了。第二个线程检查我正在跟踪的连接上的最后一个活动时间戳,如果它太长,则触发 otl_connect->cancel()。奇怪的是,它不会因 ORA-xxx(用户请求取消)而中断,而是卡住了。
【解决方案5】:

这行得通 - 我已经完成了您正在寻找的工作。 让父进程 (A) 创建子进程 (B)。子进程(B)连接数据库, 执行查询(类似于“从 a_table 中选择 1” - 如果您避免为此使用“双重”并创建自己的表,您将获得更好的性能)。如果 (B) 成功,那么它会写出成功并退出。 (A) 正在等待指定的时间。我用了15秒。如果 (A) 检测到 (B) 仍在运行 - 那么它可以假设数据库已挂起 - 它会杀死 (B) 并采取必要的措施(比如用短信打电话给我)。

如果您将 SQL*NET 配置为使用超时,您可能会注意到大型查询会因此而失败。 OCI set_timeout 配置也会导致这种情况。

【讨论】:

  • 听起来很有趣。您是否使用客户端进程只是为了定期检查数据库的一般功能或所有与数据库相关的东西?如果前者你也有办法处理已经停止的其他连接吗?
  • 是的,父进程检查了一堆 d.b.相关项目。它还会检查网络连接。
【解决方案6】:

有一种手动方法可以避免这种情况。您可以在每个指定的时间段后打开防火墙并执行诸如 ping 数据库之类的操作。这样数据库连接就不会丢失。

想法

If (current_time - lastPingTime > configuredPingTime)
{
     //Dummy query
     select 1 from dual;
}

【讨论】:

  • 抱歉,这不起作用,因为问题是连接没有断开或丢失,只是不再反应。这是数据库服务器本身的一个已知问题(并且正在接受大量调查),但应用程序必须能够抵抗这些奇怪的情况。
  • 如果您可以将 ORACLE 代码和在这种情况下收到的错误字符串发送给我,我会进一步帮助您。
  • 没有 ORACLE 代码和错误字符串,因为连接上的最后一个查询/操作只是停止并且永远不会返回任何结果或错误。
猜你喜欢
  • 2012-11-03
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多