ORACLE快速彻底Kill掉的会话

在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL
SESSION
'sid,serial#'杀掉一个会话进程,但是使用这个SQL语句杀掉会话后,数据库并不会立即释放掉相关的资源,有时候你会发现锁定的资源很长时间
也不会释放,即使会话状态为“KILLED”,依然会阻塞其它会话。

下面根据Eygel的"Oracle中Kill session的研究",构造一个案例看看kill session到底做了什么。如下所示

会话1:

SQL> conn etl/etl
Connected.
SQL>  update test set status='invalid';
 
55944 rows updated.
 
SQL> update test2 set dropped='Y';
 
3090 rows updated.

会话2:

 
SQL> show user
USER is "SYS"
SQL> update etl.test2 set dropped='Y';
 
3090 rows updated.

会话3

 
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username =upper('etl') or username =upper('sys');
 
SADDR                   SID    SERIAL# PADDR            USERNAME                       STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00         27      33353 000000025F1D1FC8 ETL                            INACTIVE
000000025C23A608         37      11448 000000025F1D27B0 SYS                            ACTIVE
000000025C24BC50         63      54311 000000025F1D5F08 SYS                            ACTIVE
 
 
SQL> alter system kill session '27,33353';
 
System altered.
 
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username =upper('etl') or username =upper('sys');
 
SADDR                   SID    SERIAL# PADDR            USERNAME                       STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00         27      33353 000000025C21A0B0 ETL                            KILLED
000000025C23A608         37      11448 000000025F1D27B0 SYS                            ACTIVE
000000025C24BC50         63      54311 000000025F1D5F08 SYS                            INACTIVE

 


下所示,我杀掉了其中两个会话后,这两个会话的地址都变为000000025C21A0B0了(请见PADDR列)。当在Oracle中kill
session以后, Oracle只是简单的把相关session的paddr
指向同一个虚拟地址.此时v$process和v$session失去关联,进程就此中断。 然后Oracle就等待PMON去清除这些Session.所以通常等待一个被标记为Killed的Session退出需要花费很长的时间. 如果此时被Kill的process,重新尝试执行任务,那么马上会收到进程中断的提示,process退出,此时Oracle会立即启动PMON 来清除该session.这被作为一次异常中断处理.

SQL> alter system kill session '63,54311';
 
System altered.
 
SQL> select saddr,sid,serial#,paddr,username,status 
from v$session where username =upper('etl') or username =upper('sys');
 
SADDR                   SID    SERIAL# PADDR            USERNAME                       STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00         27      33353 000000025C21A0B0 ETL                            KILLED
000000025C23A608         37      11448 000000025F1D27B0 SYS                            ACTIVE
000000025C24BC50         63      54311 000000025C21A0B0 SYS                            KILLED

我们根据下面SQL找到进程的地址,然后在v$process里面找到对应的spid,然后从操作系统中杀掉该进程。

SQL> select p.addr from v$process p where pid <> 1
  2  minus
  3  select s.paddr from v$session s;
 
ADDR
----------------
000000025F1D1FC8
000000025F1D5F08
 
 
 
SQL> select saddr,sid,serial#,paddr,username,status from v$session 
    where username =upper('etl') or username =upper('sys');
 
SADDR                   SID    SERIAL# PADDR            USERNAME                       STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00         27      33353 000000025C21A0B0 ETL                            KILLED
000000025C23A608         37      11448 000000025F1D27B0 SYS                            ACTIVE
000000025C24BC50         63      54311 000000025C21A0B0 SYS                            KILLED
 
SQL>  select addr, pid, spid, username from v$process where addr in ('000000025F1D1FC8','000000025F1D5F08');
 
ADDR                    PID SPID         USERNAME
---------------- ---------- ------------ ---------------
000000025F1D1FC8         22 12959        oracle
000000025F1D5F08         38 12971        oracle
 
SQL> ! kill -9 12959
 
SQL> ! kill -9 12971
 
SQL> select saddr,sid,serial#,paddr,username,status 
    from v$session where username =upper('etl') or username =upper('sys');
 
SADDR                   SID    SERIAL# PADDR            USERNAME                       STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C23A608         37      11448 000000025F1D27B0 SYS                            ACTIVE

 

在ORACLE数据库杀掉会话进程有三种方式:

1: ALTER SYSTEM KILL SESSION

关于KILL SESSION Clause ,如下官方文档描述所示,alter system kill session实际上不是真正的杀死会话,它只是将会话标记为终止。等待PMON进程来清除会话。

The KILL SESSION clause lets you mark a session as terminated, roll back ongoing transactions, release all session locks, and partially recover session resources. To use this clause, your instance must have the database open. Your session and the session to be terminated must be on the same instance unless you specify integer3.You must identify the session with the following values from the V$SESSION view:
 
For integer1, specify the value of the SID column.
 
For integer2, specify the value of the SERIAL# column.
 
For the optional integer3, specify the ID of the instance where the target session to be killed exists. You can find the instance ID by querying the GV$ tables.
If the session is performing some activity that must be completed, such as waiting for a reply from a remote database or rolling back a transaction, then Oracle Database waits for this activity to complete, marks the session as terminated, and then returns control to you. If the waiting lasts a minute, then Oracle Database marks the session to be terminated and returns control to you with a message that the session is marked to be terminated. The PMON background process then marks the session as terminated when the activity is complete.
Whether or not the session has an ongoing transaction, Oracle Database does not recover the entire session state until the session user issues a request to the session and receives a message that the session has been terminated.

可以使用ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE 来快速回滚事物、释放会话的相关锁、立即返回当前会话的控制权。

Specify IMMEDIATE to instruct
Oracle Database to roll back ongoing transactions, release all session
locks, recover the entire session state, and return control to you
immediately.

 

2: ALTER SYSTEM DISCONNECT SESSION

 

ALTER
SYSTEM DISCONNECT SESSION 杀掉专用服务器(DEDICATED
SERVER)或共享服务器的连接会话,它等价于从操作系统杀掉进程。它有两个选项POST_TRANSACTION和IMMEDIATE,
其中POST_TRANSACTION表示等待事务完成后断开会话,IMMEDIATE表示中断会话,立即回滚事务。

SQL> ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' POST_TRANSACTION;

SQL> ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' IMMEDIATE;

 

3: KILL -9 SPID (Linux) 或 orakill ORACLE_SID spid (Windows)

可以使用下面SQL语句找到对应的操作系统进程SPID,然后杀掉。当然杀掉操作系统进程是一件危险的事情,尤其不要误杀。所以在执行前,一定要谨慎确认。

SET LINESIZE 100
COLUMN spid FORMAT A10
COLUMN username FORMAT A10
COLUMN program FORMAT A45
 
SELECT s.inst_id,
       s.sid,
       s.serial#,
       p.spid,
       s.username,
       s.program
FROM   gv$session s
       JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id
WHERE  s.type != 'BACKGROUND';

 

在数据库如果要彻底杀掉一个会话,尤其是大事务会话,最好是使用ALTER SYSTEM DISCONNECT SESSION IMMEDIATE或使用下面步骤:

1:首先在操作系统级别Kill掉进程。

2:在数据库内部KILL SESSION

或者反过来亦可。这样可以快速终止进程,释放资源。

时间: 2024-11-29 16:40:07

ORACLE快速彻底Kill掉的会话的相关文章

如何在Windows 2000环境中Kill掉单个Oracle线程

oracle|window  如何在Windows 2000环境中Kill掉单个Oracle线程   来源:http://metalink.oracle.com 关键字:Oracle Thread Kill 描述:本文说明在Windows环境下, Orakill工具的使用 正文:        你遇到过下面类似的情况吗?一个用户进程长期占用资源而不释放,导致Oracle进程占用了系统的大量资源,Oralce系统的效率变得很低.如果简单的关闭重启Oracle 实例,势必影响所有的用户.有没有办法仅

Oracle中如何彻底的清除会话

kill session 是DBA经常碰到的事情之一.如果kill 掉了不该kill 的session,则具有破坏性,因此尽可能的避免这样的错误发生.同时也应当注意, 如果kill 的session属于Oracle 后台进程,则容易导致数据库实例宕机. 通常情况下,并不需要从操作系统级别杀掉Oracle会话进程,但并非总是如此,下面的描述中给出了在Oracle级别杀掉会话以及操作系统级别杀掉进程. 一.获得需要kill session的信息(使用V$SESSION 和 GV$SESSION视图)

Oracle中如何Kill Session

在Oracle的日常维护中,经常出现以下两种情况需要我们DBA kill session: 1. App 抱怨他们的应用hang住了,在数据库里查询得知他们的session被其它session block,此时 要把其它session kill掉,以便App应用能及时跑完. 2. App的应用跑到一半,突然决定 不跑了,需要DBA把他们的session kill掉. 以下是我经常采用的kill session的方法: 1. 在数据库层面用语句alter system kill 'sid, ser

Oracle OAM10g配置不当,导致会话劫持(附POC和视频)

本文讲的是Oracle OAM10g配置不当,导致会话劫持(附POC和视频), 漏洞简介 Oracle OAM10g配置不当会导致用户在不知情的情况下被攻击者劫持.不得不说,这种方法为钓鱼攻击提供了一个全新领域.大概有99%的公司的Oracle数据库没有被正确配置. 去年年底,我和TOM在做一次安全评估当中,偶然发现一个非常复杂的单点登录(SSO),为了保证能够访问到请求的资源,它会处理18种不同的请求.在了解清楚并且绘制出来这些cookie和参数在登录过程中的作用后,挑选出来了作用最大的coo

oracle快速删除重复的记录_oracle

正在看的ORACLE教程是:oracle快速删除重复的记录.做项目的时候,一位同事导数据的时候,不小心把一个表中的数据全都搞重了,也就是说,这个表里所有的记录都有一条重复的.这个表的数据是千万级的,而且是生产系统.也就是说,不能把所有的记录都删除,而且必须快速的把重复记录删掉. 对此,总结了一下删除重复记录的方法,以及每种方法的优缺点. 为了陈诉方便,假设表名为Tbl,表中有三列col1,col2,col3,其中col1,col2是主键,并且,col1,col2上加了索引. 1.通过创建临时表

Android下写一个永远不会被KILL掉的进程/服务

  Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用.当系统觉得当前的资源非常有限的时候,为了保证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存.这样就能保证真正对用户有用的程序仍然再运行.如果你的 Service 碰上了这种情况,多半会先被杀掉.但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级.   为什么是

python内部线程假死,有什么办法在进程内kill掉这个假死的线程呢

问题描述 python内部线程假死,有什么办法在进程内kill掉这个假死的线程呢 python内部线程假死,有什么办法在进程内kill掉这个假死的线程呢 解决方案 应该先解决你python代码怎么引起线程假死的. 解决方案二: 线程数比较少的时候,一个月都不假死,但超过一定的数量就会假死,而且每次假死,最后日志停止的位置都不一样,所以也是无所下手

急!was忘记控制台密码,修改security后,kill掉dmgr,重启报错,求大侠指导

问题描述 急!was忘记控制台密码,修改security后,kill掉dmgr,重启报错,求大侠指导 10C was忘记控制台密码,看网上说把security.xml中ture改为false然后kill掉dmgr再启动时报错,请各位大侠赐教,谢谢!!! 另外SystemOut.log中有一句[1/15/16 16:11:03:327 CST] 00000000 WsServerImpl E WSVR0100W: An error occurred initializing dmgr [class

【VNC】手工kill掉VNC进程的故障处理

1.模拟Kill掉已经启动的VNC服务1)启动桌面1的服务[root@testdb ~]# vncserver :1 New 'testdb:1 (root)' desktop is testdb:1 Starting applications specified in /root/.vnc/xstartupLog file is /root/.vnc/testdb:1.log 2)手工杀掉已经启动的VNC服务进程[root@testdb ~]# ps -ef | grep -i vnc | g