客户端异常关闭时的 Oracle 活动会话状态

Posted

技术标签:

【中文标题】客户端异常关闭时的 Oracle 活动会话状态【英文标题】:Oracle Active Session Status on a Client's Abnormal Shutdown 【发布时间】:2014-05-13 16:30:11 【问题描述】:

好时光。

几天前,我们的数据库团队检测到,对于不再处于活动状态的客户端,存在状态为“活动”的会话。一项调查表明,此类问题有两个主要来源:

    远程SQL Developer连接(其实这个案例不是很有趣), 异常的 tomcat(我们的应用程序运行的地方)关闭(如“kill -9”)

奇怪的是,所有会话都处于“活动”状态。请有人澄清这是怎么回事(也许有一些底层进程在相应的套接字上等待,或者......只要在适当的tomcat关闭后一切正常,似乎根本原因在于事务。 ..)?

如果我们设置“IDLE_TIME”(用于所有连接)和“EXPIRE_TIME”(用于我们所有的 RAC 实例)会有帮助吗?

我是否应该发生以下场景(设置了上述参数):

    当客户端连接时,它的会话被标记为“活动” 不考虑“ACTIVE”状态,有一个“ping”过程,由 'EXPIRE_TIME' 参数发起,该参数对客户端进行 ping。 如果 ping 进程在 EXPIRE_TIME 时间段内失败,即使会话处于“活动”状态,会话也会被 oracle 终止。 如果客户端响应 ping,但不进行任何处理,则在 IDLE_TIME 时间段后,它的会话变为“不活跃”,并且(如果设置了“IDLE_TIME”参数)一段时间后 - “SNIPED”。之后,“SMON”进程会为此会话(以及其他处于“SNIPED”状态的会话)启动内务管理活动。

更新

似乎处理这种情况的唯一方法是配置 Oracle 实例。 有我的调查结果:

https://community.oracle.com/thread/873226?start=0&tstart=0

对于死连接检测使用服务器端 sqlnet.ora 文件 参数 SQLNET.EXPIRE_TIME=

另一个选项是在配置文件设置中实现 idle_time。然后通过一些工作杀死 SNIPED 会话(当 idle_time 将 达到,会话将从 INACTIVE 变为 SNIPED)。


如果我打开一个连接并去吃午饭,IDLE_TIME 限制将 导致我的会话在 15 分钟不活动后终止。一个 15 分钟的 EXPIRE_TIME 只会让 Oracle 向我的 客户端应用程序来验证客户端没有失败。如果 客户端已启动,它将应答 ping,我的会话将继续存在 无限期地。 EXPIRE_TIME 只会导致会话被终止,如果 客户端应用程序无法响应 ping,这意味着 客户端进程已失败或客户端系统已失败。 IDLE_TIME 将杀死一段时间内没有活动的会话 时间,但这通常不适用于以下应用程序 维护一个连接池,因为假设存在 连接池将有相当数量的空闲连接 一天中的某个时间段以及使用连接的应用程序 池往往对池中的连接被终止反应不佳。

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2233109200346833212

默认情况下,TCP/IP 在设计上不会中断事物。当一个 连接消失,客户端和/或服务器不会立即获取 通知。因此,如果您的客户端连接到数据库并且什么都不做 然后你拔掉你的客户端(蓝屏,杀掉它,拔掉网线,让电脑崩溃,无论如何),很可能是会话 将留在数据库中。服务器不会知道它永远不会 收到您的消息。我们有死客户检测如果 这成了一个问题:

http://download.oracle.com/docs/cd/B12037_01/network.101/b10776/sqlnet.htm#sthref476

至于活动会话,这真的很容易。你打开一个连接, 您通过此连接提交请求,例如“锁定表 T”。药片 在您的会话中被您的事务锁定。然后你提交一个块 代码如下:

开始循环 dbms_lock.sleep(5);结束循环;结尾; /

只要该代码正在运行,您的会话就会一直处于活动状态 - 客户端进程在等待服务器读取的套接字上被阻塞 发回一个结果 - 一个响应(当然永远不会出现)。这 服务器现在根本没有接触网络 - 它是活跃的 你的代码。所以,如果你的客户现在“死”了——代码块 将继续运行,运行,运行 - 因为它从不提交 - 它会挂在那里并运行,当然你拥有的任何锁都会 留在原地。

http://www.databaseskill.com/4267817/

http://www.dba-oracle.com/t_connect_time_idle_expire_timeout.htm

sqlnet.expire_time 参数用于设置时间间隔,在 分钟,以确定应该多久发送一次探测以验证 客户端/服务器连接处于活动状态。如果您需要确保 连接不会无限期地保持打开状态(或直到由 操作系统特定的参数),您应该设置一个值为 大于 0。这可以保护系统免受打开的连接的影响 由于客户端异常终止。

https://asktom.oracle.com/pls/apex/f?p=100:11:0::NO::P11_QUESTION_ID:453256655431

如果会话正在等待资源锁或闩锁,并且如果这 等待时间超过配置文件中的 idle_time 设置,会话是否 被狙击,即使会话处于事务中间并且 等待锁定等。

如果是这样,警报日志中是否会有任何条目。

跟进

如果在等待锁,你是活跃的——不是空闲的。


在我获得 Oracle 支持的六个月前,这些页面引起了我的注意 对于 Data Guard 问题,所以其中一位 Oracle 人员,请注意我使用 Idle_Time 他告诉我这个参数不能很好地工作 因为 Oracle 不会释放被标记的会话的资源 剪断,直到用户下次尝试使用它(等待 告诉你的会话被杀死,清除会话资源)

跟进

...经过调查...“会话”在那里, 在客户确认之前不会消失,但是 “交易”不见了。


Tom,我已将个人资料更改为 IDLE_TIME=240(4 小时)并 确保我的 resource_limit 参数设置为 TRUE。当我查询 v$session 我看到了一些“剪断”的会话,但也看到了“非活动”的会话 已经闲置了一天多。所有这些用户都有此个人资料 分配给他们。如果用户会话在 idle_time 之前连接 已设置,这些会话是否会受到此更改的影响?我有 很久以前做出了改变。还有什么我应该做的吗 做了吗?

跟进

如果用户会话在设置 idle_time 之前连接, 他们是“祖父”——他们不会被狙击。它只是 影响新会话。

http://agstamy.blogspot.ru/2011/03/profile-and-resource-limit.html

其他内容和建议:https://rebby.com/blog.php?detail=32

【问题讨论】:

您好,您使用哪种连接方式?专用或共享(或汇集)?共享服务器存在一些错误。我们遇到了这个错误。 Oracle 看不到活动客户端的断开连接并继续查询。他们只是给我们发了一个补丁来纠正它 你好,埃利亚图。我们使用池连接,但详细了解上述所有内容也很有趣。请您尽可能详细地分享有关此问题的知识,如果可能,请分享补丁。 我记错了。我们的错误是关于像你这样的池连接!请参阅补丁 17054981:DRCP 不会终止死连接 好的,谢谢你,eliatou! 嘿@Dmitry,你找到解决方案了吗?在异常连接丢失问题后,您是否能够释放锁定或终止会话? 【参考方案1】:

我们已经检查了上面调查中列出的参数,一切正常!

【讨论】:

以上是关于客户端异常关闭时的 Oracle 活动会话状态的主要内容,如果未能解决你的问题,请参考以下文章

排查oracle会话非活动状态的语句

ORACLE自动杀活动会话

如何判断会话是不是处于活动状态? [复制]

Java Hibernate 会话没有被正确终止

ORACLE定期清理INACTIVE会话

检测会话当前是不是处于活动状态并加入而不是开始新的会话