我不能简单地停止它并继续读取块并使用回滚段。这是一个简单的选择,但我担心它不会停止......
会话被标记为已杀死。 我该怎么办?
我在以下链接中找到了一些额外的信息: http://oracleunix.wordpress.com/2006/08/06/alter-system-kill-session-marked-for-killed-forever/ 但如果我发出以下查询,它将返回241条记录。这是什么意思?
SELECT spid
FROM v$process
WHERE NOT EXISTS (SELECT 1
FROM v$session
WHERE paddr = addr);
答案 0 :(得分:6)
如果你杀死的会话有一个大的开放交易,它将必须回滚所有这些更改。所以,你应该看到使用的撤销量下降,而不是上升。
尝试此查询:
select vt.used_ublk from v$transaction vt, v$session vs where vs.taddr=vt.addr and vs.sid=&&sid;
现在,如果您连续多次运行上述查询,use_ublk是否会下降或增加?如果它正在下降,那么会话就会回滚。
希望有所帮助。
答案 1 :(得分:5)
我将假设您所杀的会话只是select
,因为您声明并且您正在运行* nix变体。
如果您正在运行update
或delete
,则等待回滚完成将是最佳选择。您可以使用以下查询检查回滚量,我从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
这意味着您可以检查拥有运行终端进程的用户名以及正在运行的程序,然后再做一些激烈的操作。你不想四处乱杀。
然后,您可以直接进入您的包装盒并发出 sigterm kill 1234
。这会在您的操作系统级别向进程发出终止信号,并且应该将其删除。
作为附录,如果您的会话正在使用数据库链接,那么在它运行的框中杀死它通常是不够的。你可能还必须在你选择的盒子上杀死它。首先尝试标准的Oracle kill,然后将其扩展到OS级别。
应该有效。但是,它可能会变得更加激烈;我不得不在最近奴隶虚拟机开始接受传入连接然后不发送错误或返回值之后。
警告:你进入垃圾箱的暴力程度越大,对你的暴力就越大,出错的可能性就越大。
sigkill 的下一步是 sigkill 。这是操作系统在不提出任何问题的情况下杀死进程的信号。在* nix上,这是kill -9 1234
。这很少是必要的。如果您正在使用DML,它将停止任何回滚,并且可能使得在发生故障时将数据库恢复到一致状态变得困难。
如果这仍然不起作用那么你就会遇到重大问题。在VM给出的示例中,我们最终执行以下操作以解决问题。其中大部分都不推荐: - )。
alter system kill 123
kill 1234
kill -9 1234
shutdown immediate
- 这实际上比kill -9 ....
更加礼貌。它不会向操作系统发送 sigkill 并等待进程回滚等。但是对您的数据库保持礼貌总是好的。shutdown abort
- 这与 sigkill 大致相同。这是数据库立即停止一切并死亡的信号(我知道的术语令人困惑)。reboot
reboot
没有用。一旦你到达这个阶段,你最好希望你使用VM。我们最终删除了它......