Killing an Oracle process from inside Oracle

I had a following situation few days ago – I was running a CREATE TABLE AS SELECT over a heterogenous services dblink. However I cancelled this command via pressing CTRL+C twice in Windows sqlplus (this actually just kills the client sqlplus and not the call).

Anyway, when I wanted to drop that table involved, this happened:

SQL> drop table MYTABLE;
drop table MYTABLE
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified

I can’t drop a table as someone is holding a lock on it. Fair enough, this was a dev environment used only by me, so I used DBA_OBJECTS.OBJECT_ID to find out the object ID of that table:

SQL> @o MYTABLE

owner                     object_name                    object_type        CREATED           LAST_DDL_TIME     status           OID      D_OID
------------------------- ------------------------------ ------------------ ----------------- ----------------- --------- ---------- ----------
XYZ_DEV01_OWNER MYTABLE TABLE 20080616 11:08:44 20080616 11:08:44 VALID 63764 63764

…and then I queried what enqueue locks were held on that object:

SQL> select * from v$lock where id1=63764;

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
40034278 40034290 130 TM 63764 0 6 0 2662 0

Ok, I see session 130 holding a TM lock on that table. I queried the corresponding SERIAL# from v$session as well and killed the session:

SQL> alter system kill session '130,8764';
alter system kill session '130,8764'
*
ERROR at line 1:
ORA-00031: session marked for kill SQL> select * from v$lock where id1=63764; ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
40034278 40034290 130 TM 63764 0 6 0 2668 0

After hanging for 60 seconds, my kill command gave up (and marked my session for kill), but my lock was still not released… Now what?

This happens when the victim session is so stuck somewhere in an Oracle call that it never has a chance to receive the message it has been killed. And apparently some resources used can in that call can’t be released (for whatever reason, it may be by design, it may just be a bug).

The below queries against V$SESSION and V$LOCK show that even though the session has been marked to be in killed status, it’s still holding a lock:

--===session usid =====

select sid,s.serial#,taddr,sql_hash_value,prev_hash_value,p.spid,s.username,machine,logon_time
from v$session s,v$process p where s.paddr=p.addr and sid='&sid';

SQL> @usid 130

USERNAME                SID                 AUDSID OSUSER           MACHINE            PROGRAM              SPID          HASH_VALUE   LASTCALL STATUS
----------------------- -------------- ----------- ---------------- ------------------ -------------------- ------------ ----------- ---------- --------
XYZ_DEV01_OWNER '130,8764' 33533 1288249 \XYZHOST001 sqlplus.exe 3872 3564023715 4032 KILLED SQL> select * from v$lock where id1=63764; ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
40034278 40034290 130 TM 63764 0 6 0 2695 0

Ok, I tried various other options, like kill immediate and disconnect, which should have higher chance to clean up my session properly:

SQL> alter system kill session '130,8764' immediate;
alter system kill session '130,8764' immediate
*
ERROR at line 1:
ORA-00031: session marked for kill SQL> alter system disconnect session '130,8764' immediate;
alter system disconnect session '130,8764' immediate
*
ERROR at line 1:
ORA-00031: session marked for kill SQL> select * from v$lock where id1=63764; ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
40034278 40034290 130 TM 63764 0 6 0 2710 0

Still no luck, lock is there.

So I found the OS PID of my server process (or actually OS Thread ID inside oracle.exe process as I was on Windows) and used oradebug short_stack to check where that process was stuck (the output is slightly formatted):

SQL> oradebug setospid 3872;
Oracle pid: 18, Windows thread id: 3872, image: ORACLE.EXE (SHAD) SQL> oradebug short_stack;
_ksdxfstk+14<-_ksdxcb+1481<-_ssthreadsrgruncallback+428<-_OracleOradebugThreadStart@4+819
<-7C80B680<-00000000<-71A557C4<-71AB4376<-6298540C<-6298325E<-60A0D931<-609D005F<-609B073D<-609AF9
endExitAgent+202<-_hoxexit+188<-_hogmdis+890<-_hogdisc+8<-_xupidhs+137<-_upidhs+20<-_kpudtch+305
<-_OCIServerDetach+12<-_ncodncf+268<-_npidr0+2300<-_npifcc+46<-_qerrmFBu+457<-_qerrmFetch+1
+1291<-_opiodr+1099<-_rpidrus+178<-_rpidru+88<-_rpiswu2+426<-_rpidrv+1461<-_psddr0+449
<-_psdnal+283<-_pevm_EXIM+153<-_pfrinstr_EXIM+34<-_pfrrun_no_tool+56<-_pfrrun+781<-_plsql_run+738
<-_pr+1099<-_opidrv+819<-_sou2o+45<-_opimai_real+112<-_opimai+92<-_OracleThreadStart@4+726<-7C80B680

This terse stack shows (start reading from bottom right to left) this process is stuck somewhere “above” qerrmFetch (Remote Fetch). I guess the functions starting with “h” above that are heterogenous services functions. By the way, V$SESSION_WAIT didn’t show any wait state changes either and the session itself was still constantly waiting for “HS message to agent” event. So, being stuck in a HS call was probably the reason why that session could not clean itself up.

Now, in such situations one normally would proceed with ORAKILL on Windows or just killing that server process at Unix level (after carefully thinking what you’re about to do). Killing the process makes PMON to perform the cleanup and PMON usually does clean all resources up ok. However I didn’t have access to that Windows server box, so OS kill was out of question.

So, I used another trick. While being connected to the victim process using oradebug, I issued this:

SQL> oradebug event immediate crash;
ORA-00072: process "Windows thread id: 3872, image: ORACLE.EXE (SHAD)" is not active
SQL>

After waiting for a while (crashdump occurred), sqlplus reported that the target process doesn’t exist anymore. Thanks to the crash, PMON had woken up and performed the cleanup.

Let’s see if it helped:

SQL> oradebug short_stack;
ORA-00072: process "Windows thread id: 3872, image: ORACLE.EXE (SHAD)" is not active SQL> select * from v$lock where id1=63764; no rows selected SQL> @usid 130 no rows selected SQL> drop table MYTABLE; Table dropped.

Yippee, I finally got rid of that session, lock and could drop my table!

Note that I would still prefer killing the processes with Unix kill or Windows orakill, however there are some bugs with orakill (search in Metalink) that it doesn’t always succeed killing the thread properly. And in my case I didn’t have OS access anyway.

Ideally, the ALTER SYSTEM KILL session command should do all needed cleanup for us, but there are some corner cases involving loops, hangs and bugs where this approach won’t work. There’s a Metalink note 1020720.102 with a list of ways for killing Oracle processes/threads from OS level.

NB! If you want to move to the "New World" - offload your data and workloads to Hadoop, without having to re-write your existing applications - check out Gluent. We are making history! ;-)

windows session 管理的更多相关文章

  1. php session session_set_save_handler 接管所有的session管理工作

    一个已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存储到数 据库,这样可以通过SQL语句来删除所有过期的sessi ...

  2. Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等

    NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ...

  3. Nhibernate的Session管理

    参考:http://www.cnblogs.com/renrenqq/archive/2006/08/04/467688.html 但这个方法还不能解决Session缓存问题,由于创建Session需 ...

  4. Openfire的启动过程与session管理

    说明   本文源码基于Openfire4.0.2.   Openfire的启动       Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...

  5. ABP(现代ASP.NET样板开发框架)系列之7、ABP Session管理

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之7.ABP Session管理 ABP是“ASP.NET Boilerplate Project (ASP.NET ...

  6. 2016-1-30 Servlet中Session管理(Sesssion追踪)

    Session管理(Sesssion追踪)是Web应用程序开发中非常重要的一个主题.这是因为HTTP是无状态的,在默认情况下,Web服务器不知道一个HTTP请求是来自初次用户,还是来自之前已经访问过的 ...

  7. Redis3.2+Tomcat实现集群的Session管理 -- tomcat-redis-session-manager的编译和开发部署环境搭建

    已经有不少文章介绍使用tomcat-redis-session-manager来实现Redis存储Tomcat的Session,实现分布式Session管理.但是现在官方编译的tomcat-redis ...

  8. tomcat架构分析 (Session管理)

    Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是获取一个session,然后向session中存取数据,然后再销毁session.那么如何产生se ...

  9. Session管理解决方案笔记

    大型网站Session管理解决方案: 1. web服务器之间的session复制.    优点:方案成熟    缺点:复制的性能开销大 2. 减少session使用,使用客户端存储cookie     ...

随机推荐

  1. Unity3D游戏开发之粒子系统实现具体解释

     今天为大家分享的是Unity3D中的粒子系统.粒子系统通经常使用来表现烟雾.云等高级效果.是一个十分注重制作技巧的部分.今天我们将以一个气泡的演示实例来一起学习怎样在Unity3D中使用粒子系统 ...

  2. 三分钟教你学Git(十四) 之 线下传输仓库

    有时候还有一个人不能从远程直接clone仓库或者说由于非常大,clone非常慢或其他原因.我们能够使用bundle命令将Git仓库打包,然后通过U盘或者是其他介质拷贝给他,这样他拿到打包好的仓库后能够 ...

  3. 记一次OGG数据写入HBase的丢失数据原因分析

    一.现象二.原因排查2.1 SparkStreaming程序排查2.2 Kafka数据验证2.3 查看OGG源码2.3.1 生成Kafka消息类2.3.2 Kafka配置类2.3.3 Kafka 消息 ...

  4. ruby 学习网站

    Ruby on Rails官网: http://rubyonrails.org/ Rails Guides:http://guides.rubyonrails.org/ -中文版: http://gu ...

  5. 序列化FastReport,重要提示少走弯路 good

    原本在开发一个报表插件,因为需要远程传输,因此需要序列化报表,序列化FastReport有两种方式, 1.仅序列化数据,由客户端接受到数据,并呈现报表,这种方式需要在客户端存储报表格式文件xxx.Fr ...

  6. bootstrap中的less

    一.如何加入变量 引入你的 .less 样式文件的时候要设置 rel 属性值为 “stylesheet/less”: 参考网站:http://www.bootcss.com/p/lesscss/  1 ...

  7. SDUT OJ 图练习-BFS-从起点到目标点的最短步数 (vector二维数组模拟邻接表+bfs , *【模板】 )

    图练习-BFS-从起点到目标点的最短步数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在古老的魔兽传说中,有两个军团,一个叫天 ...

  8. POJ3273 Monthly Expense —— 二分

    题目链接:http://poj.org/problem?id=3273   Monthly Expense Time Limit: 2000MS   Memory Limit: 65536K Tota ...

  9. POJ3414 Pots —— BFS + 模拟

    题目链接:http://poj.org/problem?id=3414 Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions ...

  10. ES6 对象的解构赋值

    对象的解构赋值 解构不仅可以用于数组,还可以用于对象. let {foo,bar} = {foo:"aaa",bar:"bbb"}; console.log(f ...