4

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

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

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

4

6 回答 6

3

This is a bug in Oracle ( or call it a feature ) till 11.1.0.6 and they said the patch on Oracle 11g release 1 ( patch 11.1.0.7 ) which has the fix. Need to see that. If it happens you will have to cancel ( kill ) the thread performing this action. Not good approach though

于 2010-09-13T17:40:55.363 回答
1

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

于 2009-10-15T07:18:39.737 回答
0

OTL 中有一个set_timeoutAPI 可能对此有用。

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

于 2009-09-16T10:16:38.157 回答
0

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

主意

If (current_time - lastPingTime > configuredPingTime)
{
     //Dummy query
     select 1 from dual;
}
于 2009-10-08T12:43:16.557 回答
0

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

于 2009-12-15T23:20:24.190 回答
0

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

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

于 2009-12-17T19:13:41.367 回答