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

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

参考资料:

http://www.eygle.com/faq/Kill_Session.htm

http://www.oracle-base.com/articles/misc/killing-oracle-sessions.php#unix

http://www.eygle.com/archives/2005/10/oracle_howto_kill_session.html

http://blog.sina.com.cn/s/blog_6d6e54f70100zfqp.html

http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_2013.htm#SQLRF53047

时间: 2024-10-29 10:48:12

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

ORACLE快速彻底Kill掉的会话(转载)

转载:http://www.cnblogs.com/kerrycode/p/4034231.html 在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL SESSION 'sid,serial#'杀掉一个会话进程,但是使用这个SQL语句杀掉会话后,数据库并不会立即释放掉相关的资源,有时候你会发现锁定的资源很长时间也不会释放,即使会话状态为“KILLED”,依然会阻塞其它会话. 下面根据Eygel的"Oracle中Kill session的研究",构造一个案例看看k

找出 alter system kill session ‘sid,serial#’ kill 掉的数据库会话对应进程

当我们使用alter system kill session 'sid,serial#' 在数据库中kill掉某个会话的时候,如果你观察仔细会发现v$session.paddr发生了改变,从而是的不能直接通过关联v$process.add找出spid,然后进行其他操作.本文提供三种方法找该种情况下spid的方法.数据库版本 SQL> select * from v$version; BANNER --------------------------------------------------

ORA-00031: session marked for kill 处理Oracle中杀不掉的锁

一些ORACLE中的进程被杀掉后,状态被置为"killed",但是锁定的资源很长时间不释放,有时实在没办法,只好重启数据库.现在提供一种方法解决这种问题,那就是在ORACLE中杀不掉的,在OS一级再杀. 1.下面的语句用来查询哪些对象被锁: select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session swhere l.object_id = o.object_id

锁_rac环境kill锁表会话后出现killed状态(解决)

原创作品,出自 "深蓝的blog" 博客,深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/46876961 rac生产库杀掉锁表会话出现killed状态处理 环境: 操作系统:CentOS 6.4 64BIT 数据库:Oracle RAC 11.2.0.4 R2 64bit 在某项目中,进行大数据抽取任务时,抽取出现错误,需要对大表进行重新抽取.于是取消insert操作,然后执行truncate操作. 如下,报错了,提

android 程序防止被360或者系统给kill掉

关于如果和防止android 程序防止被360kill掉之后重启的问题,肯定大家也搜索了好多方法,都不好使,对不对,什么增高权限了,什么进程优先级了,这些东西都不是我们可控的,所以有没有一些非常保险的方法,让程序被kill掉之后自动重启呢. 大家发现没有,当我们使用360进行程序清理的时候,有些应用自己快速的启动起来了,他们是怎么实现的呢?其实我们没有见过他们的源码,也不好说是怎么实现的. 我在下面将为大家提供一些思路,也许会对你有所帮助: windows上流氓软件和病毒特别多,有时候你根本查杀

windows和linux中查看端口占用情况并kill掉对应进程

好几次在不同的情况下遇到 需要查看端口信息 并且kill掉对应进程的情况 相关的参数总是记不全 在这里记录下 以后查看方便 windows中查看正在使用端口的信息netstat -ano|findstr "xxxx"kill 掉对应的进程taskkill /f /t /PID 具体参数信息http://blog.163.com/[email protected]/blog/static/45190050200741222590/ linux中查看正在使用的端口的信息sudo netst

保持Service不被Kill掉的方法--双Service守护 &amp;&amp; Android实现双进程守护

本文分为两个部分,第一部分为双Service守护,第二部分为双进程守护 第一部分: 一.Service简介:Java.lang.Object ?Android.content.Context  ?android.content.ContextWrapper  ?android.app.Service Service是应用程序Application的一个组件(component).它的作用有两点:1.用来提供一个长期在后台运行并且不与用户交互的操作,2.也可以为其他应用程序提供服务.Service

Android获取正在运行的程序并kill掉它

获取正在运行的程序并把它加入到一个listview的adapter类面,方法如下: // 正在运行的 public List<Programe> getRunningProcess() { pi = new PackagesInfo(this); am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); // 获取正在运行的应用 run = am.getRunningAppProcesses(); // 获取包管理器,在这里主要通过包

C# 强制关闭当前程序进程(完全Kill掉不留痕迹)

C#代码   /// <summary> /// 运行DOS命令 /// DOS关闭进程命令(ntsd -c q -p PID )PID为进程的ID /// </summary> /// <param name="command"></param> /// <returns></returns> public static string RunCmd(string command) { //實例一個Process類