首页 > 数据库 >Oracle如何清理临时表空间中的僵尸会话_Kill对应进程

Oracle如何清理临时表空间中的僵尸会话_Kill对应进程

来源:互联网 2026-04-30 18:54:03

先查v$sort_usage确认会话是否真占TEMP段,再用ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE强杀,若仍KILLED则kill -9 OS进程;残留时用COALESCE或重建TEMP文件。 查临时表空间的活跃会话和对应OS进程 临时表空

先查v$sort_usage确认会话是否真占TEMP段,再用ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE强杀,若仍KILLED则kill -9 OS进程;残留时用COALESCE或重建TEMP文件。

查临时表空间的活跃会话和对应OS进程

临时表空间出现“僵尸会话”,这事儿其实挺常见。问题往往不出在表空间本身,而是某些数据库会话已经异常断开,但之前操作(比如大排序、哈希连接)产生的临时段数据却没被释放。与此同时,它在操作系统层面的后台进程可能还在运行。所以,第一步不是急着动表空间,而是得精准定位这些残留的会话和它们对应的操作系统进程ID。

怎么定位?跑一下下面这个查询,关键信息就都出来了:

长期稳定更新的攒劲资源: >>>点此立即查看<<<

SELECT s.sid, s.serial#, s.username, s.osuser, s.machine, s.program,
       p.spid AS os_pid,
       s.status, s.sql_id, s.last_call_et
FROM v$session s
JOIN v$process p ON s.paddr = p.addr
WHERE s.username IS NOT NULL
  AND s.status = 'INACTIVE'
  AND s.last_call_et > 3600  -- 空闲超1小时,大概率是僵尸
  AND s.sql_id IS NULL;       -- 无当前SQL,进一步佐证

这里有个细节需要注意:v$session.status显示为'INACTIVE',并不代表这个会话就绝对安全、可以随意清理。特别是当它实际还在占用临时段时(这个信息需要关联v$sort_usage视图来确认),贸然处理可能会出问题。

确认会话是否真占用了临时段

光看v$session容易误判。有些会话虽然空闲了,但可能刚完成一个大规模排序,临时段还没来得及被Oracle的自动清理机制回收。所以,必须再验证一下,它到底有没有在占用临时空间:

SELECT s.sid, s.serial#, s.username, u.tablespace, u.blocks * 8 / 1024 AS mb_used
FROM v$sort_usage u
JOIN v$session s ON u.session_addr = s.saddr
WHERE u.tablespace = 'TEMP';

如果查询结果里有记录,并且对应的sid正好出现在上一步的“疑似僵尸”列表里,那么这个会话就是我们要处理的目标了。不过,这时候可别直接上ALTER SYSTEM KILL SESSION命令,因为很可能会遇到ORA-00031: session marked for kill错误,然后命令就卡在那里了——这是新手常踩的坑,根本原因在于会话可能正在清理资源或者被挂起了。

  • 如果blocks值一直不下降,基本可以断定会话没有真正释放TEMP段。
  • 发现username是应用账号(比如APP_USER),稳妥起见,最好先联系业务方确认是否可以中断。
  • 如果是SYSDBSNMP这类系统用户,那就得更谨慎了,这可能是监控或备份任务留下的尾巴。

安全 Kill 会话并清理 OS 进程

清理工作要分两步走,顺序很重要:先在数据库内部发出KILL SESSION指令,然后根据系统的反馈,决定是否需要在操作系统层面进行强制清理。顺序一旦搞错,有可能引发实例级别的锁争用,甚至导致TEMP表空间的头块损坏。

标准操作流程是这样的:

ALTER SYSTEM KILL SESSION '123,45678' IMMEDIATE;

这里的123sid45678serial#。加上IMMEDIATE选项可以跳过等待事务回滚,对于处理僵尸会话通常更有效。

命令执行后,记得检查一下结果:

  • 如果v$session里对应的记录消失了——很好,TEMP段通常会在几秒钟内被自动回收。
  • 如果记录还在,并且status变成了'KILLED'——这说明需要在操作系统层面手动“补刀”。
  • 查找对应的OS PID:SELECT spid FROM v$process WHERE addr IN (SELECT paddr FROM v$session WHERE sid = 123);

接着,在数据库服务器上执行操作系统命令:

kill -9 

在Linux/Unix系统下用kill -9,在Windows系统下则使用orakill 。需要警惕的是,千万别用kill -9去杀PMONSMON这类Oracle核心后台进程,这个操作只针对前面查询出来的用户进程spid

TEMP 表空间未释放的兜底处理

在极少数情况下,即使完成了上述清理,v$sort_usage里可能还有残留记录,DBA_TEMP_FREE_SPACE显示的空闲空间也没增加——这往往意味着临时段的头块状态出现了异常。这时候,重建整个TEMP表空间风险较高,应该先尝试强制刷新:

ALTER TABLESPACE temp COALESCE;

如果这个命令报错(比如ORA-1652)或者无法分配新的区,那说明有未释放的排序段卡在了内存结构里。此时,最稳妥的解决办法有两个:

  • 在允许的维护窗口内,重启数据库实例。
  • 或者,执行ALTER DATABASE TEMPFILE '/path/to/temp01.dbf' DROP INCLUDING DATAFILES;删除并重建特定的临时文件(前提是确保有其他可用的TEMP文件,不影响业务)。

最后提醒一点:临时表空间不像永久表空间,它不存储数据字典对象,所以没有那些复杂的依赖关系。但是,在重建之前,务必确认所有应用程序连接都已停止,否则新的连接进来可能会因为找不到默认的TEMP表空间而报ORA-01119错误。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。