0

我正在试验 Oracle 会话并尝试捕捉数据库中存在陈旧会话的情况。我在关闭网络后设法做到了这一点 - 数据库会话仍然存在并持有所有已被占用的锁。这很清楚:Oracle 不知道 TCP 会话已中断并且仍在等待请求。

但是另一个试验不起作用:当我连接了客户端并最终通过“kill -9”将其杀死时。我预计与上一个示例中的情况相同(Oracle 中的陈旧会话,因为 TCP 连接仍在服务器端工作) - 但我看到该会话已清除!以及任何锁。我不知道为什么 - SIGKILL 信号预计会杀死进程,而没有任何机会启动任何钩子,例如使用“再见”消息关闭 TCP 等。我怀疑操作系统(MacOs)释放任何 TCP 套接字并在进程终止时发送结束消息,但这只是猜测,我无法证明这一点。

谁知道?

4

2 回答 2

2

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

我希望 Oracle 在您描述的其他情况下使会话超时。

于 2013-09-30T21:06:06.483 回答
1

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

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

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

于 2013-09-30T22:52:03.430 回答