2012-02-05 99 views
3

我不能简单地停止它,它会继续读取块并使用回滚段。这是一个简单的选择,但我担心它不会停止...Oracle:杀死会话继续运行

会话被标记为终止。 我能做什么?

我发现下面的链接,一些额外的信息: http://oracleunix.wordpress.com/2006/08/06/alter-system-kill-session-marked-for-killed-forever/ 但如果我launche下面的查询返回241条记录。这是什么意思?

SELECT spid 
    FROM v$process 
WHERE NOT EXISTS (SELECT 1 
         FROM v$session 
         WHERE paddr = addr); 

回答

5

我打算假设你遇到的会话只是一个select,因为你声明了你正在使用* nix变体。

如果您运行的是updatedelete,那么等待回滚完成将是最好的。您可以使用下面的查询,我已经无耻地从orafaq被盗,因为我不记得这些东西把我的头顶部检查回滚量:

select rn.Name "Rollback Segment", rs.RSSize/1024 "Size (KB)", rs.Gets "Gets" 
    , rs.waits "Waits", (rs.Waits/rs.Gets)*100 "% Waits" 
    , rs.Shrinks "# Shrinks", rs.Extends "# Extends" 
    from sys.v_$rollName rn, sys.v_$rollStat rs 
where rn.usn = rs.usn; 

首先一个select不应该正在使用回滚...如果它有,那么你可能有一个功能,在某个地方做一些DML,这不是一个好主意。你也不会提到这个select是否正在使用数据库链接,如果是这样的话,就会清理一些东西。

如果select没有使用数据库链接并且没有执行任何DML,那么您找到的链接将完成您所需的一切。你的241行应该大部分是相同的 - 如果你有多个进程有这个问题,那么可能有多个值。我想查询更改为:

select p.* 
    from v$process p 
    left outer join v$session s 
    on p.addr = s.paddr 
where s.saddr is null 

这意味着你可以查看拥有的进程,从运行终端以及正在做什么过激举动之前运行的程序的用户名。你不想四处乱杀错误的东西。

然后,您可以直接进入您的方框并发出sigtermkill 1234。这会在您的操作系统级别向进程发出终止信号,并且应该将其清除。

作为附录,如果您的会话正在使用数据库链接,那么在它运行的盒子上杀死它通常是不够的。您可能还必须在您从中选择的框中杀死它。先尝试标准的Oracle kill,然后将其调整到OS级别。

这个应该工作。然而,它可能会变得更激烈;我最近不得不在最后一个从VM开始接受连接传入,然后不发送错误或返回值。

警告:越暴力,你越接近盒子,对你来说越是暴力,出错的可能性就越大。

sigterm开始的下一步是sigkill。这是操作系统在不询问任何问题的情况下杀死进程的信号。在* nix这是kill -9 1234。这应该很少是必要的。如果你在做DML,它会停止任何回滚,并且在发生故障时可能难以将数据库恢复到一致状态。

如果这仍然不起作用,那么你有重大问题。在VM给出的例子中,我们最终做了以下的事情来阻止这个问题。这些大多数不推荐:-)。

  1. 甲骨文 - alter system kill 123
  2. OS - kill 1234
  3. OS - kill -9 1234
  4. 甲骨文 - shutdown immediate - 这实际上比kill -9 .... politer。它不会向操作系统发送sigkill,并等待进程回滚等。对数据库进行礼貌总是件好事。
  5. Oracle - shutdown abort - 这与sigkill大约相同。这是数据库立即停止并终止一切的信号(我知道这些混淆的术语)。
  6. OS - reboot
  7. 是的没错,reboot没有工作。一旦你到达这个阶段,你最好希望你使用的是虚拟机。我们最终删除它...
+0

非常感谢!会话自我终止几个小时后,但它真的很有趣,知道 – Revious 2012-02-05 14:48:46

+0

我已经改善和澄清此答案的部分在这里:http://stackoverflow.com/questions/9545560/how-to-kill-a-running-select语句来/ 9546094#9546094 – Ben 2013-07-23 07:34:31

5

如果您杀死的会话有一个很大的打开事务,它将不得不回滚所有这些更改。所以,你应该看到正在使用的撤消量减少了,而不是增加了。

尝试此查询:

select vt.used_ublk from v$transaction vt, v$session vs where vs.taddr=vt.addr and vs.sid=&&sid; 

现在,如果您连续运行上面的查询多次,被used_ublk下降或增加?如果它正在下降,那么会话会回滚。

希望有所帮助。

+0

谢谢,知道这真的很有趣! – Revious 2012-02-05 14:39:06