为什么SIGKILL for oracle客户端不会在服务器中留下过时的会话?

时间:2013-09-30 20:51:27

标签: java oracle tcp

当我在数据库中存在陈旧的会话时,我正在试验Oracle会话并尝试捕捉情况。在我关闭网络后,我设法做到了这一点 - 数据库会话仍处于活动状态,并保留所有锁定。很清楚:Oracle不知道,TCP会话已经中断并仍在等待请求。

但是另一个试验不起作用:当我连接客户端并最终通过" kill -9"杀死它时。我期望与前一个示例相同的情况(Oracle中的陈旧会话,因为TCP连接仍然在服务器端工作) - 但我看到会话被清除了!以及任何锁。我无法找到原因 - 预计SIGKILL信号会在没有任何机会启动任何钩子的情况下杀死进程,例如关闭TCP和#34; bye"消息等。我怀疑OS(MacOs)释放任何TCP套接字并在进程终止时发送结束消息,但这只是猜测,我实际上无法证明这一点..

谁知道?

2 个答案:

答案 0 :(得分:2)

操作系统在退出时释放进程的所有未发布资源。这包括套接字,文件描述符,内存,信号量,... TCP将重置或在这样的套接字上发送FIN。

我希望Oracle能够在你描述的其他情况下超时。

答案 1 :(得分:1)

当您关闭TCP连接时,Oracle进程接收SIGHUP,回滚活动事务(如果有)并退出。如果您终止Oracle会话进程(-9),后台进程(“pmon”)会检测到这会触发一个新会话,该会话将负责死会话的恢复(UNDO)。不要在生产系统上尝试这个 - 这只是为了展示Oracle的弹性。

当您终止客户端处理它们时,操作系统会将FIN数据包发送到服务器a,因此Oracle知道然后TCP连接已关闭。这适用于Unix和Linux但我怀疑,由于某些未知的原因,这在Windows上不起作用。 (当VSphere死亡时,即使Windows内核仍在运行,Oracle也会看到悬空的TCP连接。)

如果您想使用死连接检测进行一些实验,请在tnsnames.ora中查看选项enable=broken。然后将TCP Keepalive设置为一段合理的时间(eaxmple为15秒),并使用tcpdump来获取客户端内核发送的tcp keepalive数据包。 这是100%透明的,不需要任何应用程序的合作。