Kill a session from database procedure
Scott Morin, October 10, 2002 - 4:58 pm UTC
Granting alter system to the user allows them to kill any session to the procedure become redundant and offers no protection against the users killing any other session. Dangerous!
October 11, 2002 - 7:48 pm UTC
You missed the point entirely.
One of the primary uses of PLSQL stored procedures is to encapsulate logic.
Suppose, you wanted BOB and MARY to be able to kill sessions but NOT do any other ALTER SYSTEM commands? What would you do?
I would
a) create a schema, granting it the needed privs
b) create this procedure in there
c) grant execute on this procedure to BOB and MARY
d) lock the account (or just revoke CREATE SESSION from it, munge the password, whatever)
So, now BOB and MARY have the ability to kill sessions but not change ANY other system settings.
Further, since it is procedural logic, you CONTROL exactly what is going on. Maybe, you want to make it so that BOB can kill only HIS sessions and MARY only hers -- how easy would that be? Trivial. Oh wait, it already does that.
Kill a session from database procedure
Scott Morin, October 10, 2002 - 5:34 pm UTC
Granting alter system to the user allows them to kill any session to the procedure become redundant and offers no protection against the users killing any other session. Dangerous!
October 11, 2002 - 7:56 pm UTC
not when used as described! Then it makes it very very safe (and is the way to grant very very granular priveleges like just "kill session" or "kill your own sessions" to people).
Maybe I didn't make the fact that the "owner" of this procedure is some "utility" account like CTXSYS, MDSYS, ORDSYS, OUTLN and so on are in Oracle and should be "locked" and protected from general use.
how to kill a stored proc by name
Jerry, April 28, 2003 - 3:54 pm UTC
Tom,
Want to follow up on this. How do I kill a stored proc by name? I have a web user having multiple sessions open in the database. I only want to kill the one that's running stored proc. How do I find out which session is the stored proc since the sql_text is reflecting the queries within the stored proc.
April 28, 2003 - 4:19 pm UTC
have the developer put a call into their procedure using dbms_application_info.set_client_info -- that way you can tell what procedure it is.
In fact, have them put these calls all over their code -- setting the client_info, action, and module columns in v$session with useful information for you.
What is the datatype of SID / SERIAL#
Dilbert, June 17, 2003 - 2:48 pm UTC
Hi Tom,
Your procedure is a VERY VERY helpful one.
I have a question though about the parameters. The Input parameters are defined as VARCHAR2 while when I looked into the definition of v$session, both of them are NUMBER datatype. Is there a particular reason you made the Input parameters as Varchar2 ?
June 17, 2003 - 4:36 pm UTC
no reason in particular. does violate my "compare number to numbers strings to strings dates to dates" rule ;)
oversight, pure and simple
Drawback of killing session
kom, February 26, 2004 - 8:22 pm UTC
Hi Tom,
Our users will execute adhoc report queries say 10,000 a day on real time web application. Now some queries can return results in 1 min or some may take 5 hours to execute. I am in no position to filter which query will take how much time to execute.
I need to develop some kind of intelligence on which queries to execute immediately based on time they will take to execute or to form a queue to handle the big queries execution one at a time so that I do not stress my db server.
One method which I am thinking of is , send all queries to db server and put some kind of query timeout say 1 min, if the sql does not execute in 1 min than KILL the session and queue the SQL in a batch one at a time. In this way I will end up killing alot of sessions. Is there any drawback of killing sessions. Will the resources be used correctly.
Is the above way correct or please suggest me BEST way to handle this requirement.
Thanks in advance
February 27, 2004 - 7:21 am UTC
I would put all in a queue.
1 minute is 60 times too long for a web based application. 5 hours is just "longer".
No one should have to sit for a minute wondering "hmm, is my query ever going to come back" (i would not necessarily call this "real time").
So, I would use a queue of some form for all -- and then have some notification method (eg: email them a URL that when they click on it, instant report. SMS them when it is ready. give them a page they can goto to check the status. whatever you want...) to let them know it is done.
Additon
kom, February 27, 2004 - 9:28 am UTC
Hi Tom,
I told the business team that we need to queue all the incoming report request and notify the user as you mentioned, but they do not agree with this
.
They want all reports to be executed when requested and only those ones which do not execute in 1 min should be queued.
1) is there any command which will tell near realistic time to execute the query.
2) Will killing alot of sessions ( time < 1 min ) harm the system.
Can oracle save me in this case ?
I have oracle 8.1.7
Please suggest me the BEST way to handle this requirment.
February 27, 2004 - 10:03 am UTC
1) not really
2) yes, it'll waste that much time constantly.
The saviour would not be running things that take 1 minute interactively in a browser. could you imagine if google did that?
ugh. guess you could use the resource manager IN 9i and above, but not in 8i. In 8i, you'd have to let the silly thing run for a minute and have the system kill it (using a resource plan).
documentation on resource plan
Kom, March 01, 2004 - 4:05 pm UTC
Hi Tom,
I have oracle 8.1.7 on win 2k
I would like to read more on resource plan for my above requirment.
Can you please send me a link.
Thanks in advance,
March 01, 2004 - 4:51 pm UTC
otn.oracle.com has all documentation. you are interested in the Admin Guide (chapter on resource mgmt). All versions from 8.0 on up are there -- you want to look at either 9ir2 or 10g docs.
SN, March 01, 2004 - 5:18 pm UTC
Kom, you might want to tell your business users about Oracle Discoverer - It has the feature of predicting the expected run-time (with near accuracy). If it is too long then they can submit it in batch mode. The system you describe can't be classified "real time".
Killing the session of a running job
Faran, March 03, 2004 - 3:57 am UTC
Tom! how can we kill a session handling a long running internal job to update some very large tables. When I kill the session handling that particular job; It simply says that the session has been marked killed; but it doesn't release the locks on the underlying objects (involved in update by the job). I wanna know any method (in Oracle9i Rel. 2) by which Oracle can release the locks in such a case.
Thanks :)
Faran
March 03, 2004 - 9:53 am UTC
it is in the ACT of releasing the locks (watch used_ublk in v$transaction, you can watch it rolling back)
Hi Tom,
A reader, August 04, 2004 - 4:12 pm UTC
I understood your point of allowing users to kill their own sessions.
If we grant "alter system" privilege to a user, can they misuse it by doing certain other things apart from killing their own sessions through a procedure?
I want the alter system privilege for the user only when they execute the "kill_session" procedure.
August 05, 2004 - 8:42 am UTC
then you have everything you need here -- the original answer gives you that.
Hi Tom,
A reader, August 04, 2004 - 4:17 pm UTC
Please igonre my previous question. In fact you have answered it in the beginning of this thread.
But, I did not understood one of the steps you mentioned
"d) lock the account (or just revoke CREATE SESSION from it, munge the password,
whatever"
Can you explain what does it mean?
thanks,
August 05, 2004 - 8:45 am UTC
make it so the account that owns the procedure cannot log in if you want. secures it, you don't have an account that has alter system that someone can hack into.
lock it.
Find and kill he session which hangs
Sean, August 05, 2004 - 6:56 am UTC
Hi Tom,
The stored procedure to kill session is great. I have a question related to this technique.
Sometimes one developer have multiple sessions on the same host, is it possible to use v$session and some other views to find out which session is using which sql statement, so we can kill the session that hangs?
Thanks so much for your help.
August 05, 2004 - 12:56 pm UTC
search this site for showsql
kill session
A reader, September 01, 2005 - 12:35 am UTC
This gives an exact answer to user demands
Evan, May 12, 2006 - 10:34 am UTC
As usual, when I need an answer, I come to Ask Tom. One quick search, one right answer. I have not found that for any other product/vendor/expert.
I never need to ask a new question because the answers are almost always there.
Thanks,
Evan
How to kill session in RAC
sean, December 22, 2006 - 2:19 pm UTC
The procedure you mentioned works well in a single instance. But how do I implement it in RAC environment? Thanks so much for your help.
Sean
update procedure?
joshc, April 12, 2007 - 2:17 pm UTC
Very helpful.
How could we update this procedure for use in 10g?
April 13, 2007 - 12:20 pm UTC
you do not need to. it still works.
Does the original question work on 10.2..0.3
marc, February 02, 2009 - 1:14 pm UTC
I notices this thread was created in Oracle 8. Does it still work in 10.2.0.3. I receive the ora-1031 error.
I granted the owner the following grants.
SQL> SELECT *
2 FROM user_sys_privs
3 WHERE privilege = 'ALTER SESSION'
4 ;
USERNAME PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
testdbauser ALTER SESSION NO
SQL>
SQL> SELECT u.owner,
2 u.table_name,
3 u.grantor,
4 u.privilege,
5 u.grantable,
6 u.hierarchy
7 FROM sys.user_tab_privs_recd u
8 WHERE table_name = 'V_$SESSION';
OWNER TABLE_NAME GRANTOR PRIVILEGE GRANTABLE HIERARCHY
------ ------------ -------- ---------- ------------- ----------
SYS V_$SESSION SYS SELECT YES NO
SQL>
grant execute on kill_session to testuser;
conn to testuser.
SQL> exec testdbauser.kill_session(1016,808);
BEGIN testdbauser.kill_session(1016,808); END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1204
ORA-06512: at "SYS.DBMS_SQL", line 323
ORA-06512: at "FXBLOTTER.KILL_SESSION", line 9
ORA-06512: at line 1
What am i doing wrong?
February 02, 2009 - 1:46 pm UTC
that needs alter system, not session.
Also, please change the code to:
ops$tkyte%ORA10GR2> create or replace procedure kill_session( p_sid in number,
2 p_serial# in number)
3 is
4 ignore pls_integer;
5 BEGIN
6 select count(*) into ignore
7 from V$session
8 where username = USER
9 and sid = p_sid
10 and serial# = p_serial# ;
11
12 if ( ignore = 1 )
13 then
14 execute immediate '
15 alter system kill session ''' ||
16 to_char(p_sid,'999999')||','||
17 to_char(p_serial#,'999999')||'''';
18 else
19 raise_application_error( -20001,
20 'You do not own session ''' ||
21 p_sid || ',' || p_serial# ||
22 '''' );
23 end if;
24 END;
25 /
Procedure created.
I had a cursor leak in there...
And there is a small chance of sql injection in the old code.
Thanks
marc, February 02, 2009 - 2:26 pm UTC
Thanks, it was the typo in the grant.
Also, Any reason for the change to EXECUTE IMMEDIATE
Using it on Grid
Balaji Chellappa, March 10, 2009 - 3:10 pm UTC
Tom,
Is it possible to Kill a specific INSTANCE session by logging into any instance in a RAC/Grid environment?
Or should I have to login into that particular instanace to kill it's session?
Thanks
Balaji
March 11, 2009 - 2:55 am UTC
http://docs.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_2013.htm#i2065117 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.
Not working in 11g?
Jichao Li, August 12, 2011 - 3:20 am UTC
Tom,
This approach doesn't seem to work in 11.2.0.2 and I'm trying to wrap ALTER SYSTEM FLUSH SHARED_POOL and ALTER SYSTEM FLUSH BUFFER_CACHE in a procedure created in SYSTEM and grant the execute privilege to a TEST user. But I got ora-01031. This is for developer to flush memory cache when tuning their SQLs.
SQL> show user
USER is "SYS"
SQL> CREATE OR REPLACE PROCEDURE system.dev_flush_cache AS
2 l_ddl VARCHAR2(100);
3 BEGIN
4 l_ddl := 'ALTER SYSTEM FLUSH SHARED_POOL';
5 dbms_output.put_line(l_ddl);
6 EXECUTE IMMEDIATE l_ddl;
7 l_ddl := 'ALTER SYSTEM FLUSH BUFFER_CACHE';
8 dbms_output.put_line(l_ddl);
9 EXECUTE IMMEDIATE l_ddl;
10 END dev_flush_cache;
11 /
Procedure created.
SQL> create user test identified by test;
User created.
SQL> grant create session to test;
Grant succeeded.
SQL> grant execute on system.dev_flush_cache to test;
Grant succeeded.
SQL> conn test/test
Connected.
SQL> exec system.dev_flush_cache;
BEGIN system.dev_flush_cache; END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYSTEM.DEV_FLUSH_CACHE", line 6
ORA-06512: at line 1
August 14, 2011 - 8:21 pm UTC
did you know that flushing the caches for "performance testing" is a really horribly bad, misleading, time wasting, not good for anything approach?
You are probably using a file system - a buffered file system. That means, the file system cache is already caching the stuff and just because we say we did a physical IO - it doesn't mean we did.
Search this site for "secondary sga" - to see what I'm talking about. Further - flushing the caches presents you with a situation you would NEVER SEE in real life.
I strongly encourage you to STOP THIS, do not do this, it is misleading, time wasting, not useful.
Secondly - DO NOT CREATE THINGS AS SYS. DO NOT USE SYS. sys is ours, sys is special, sys is magic, things work differently as sys than for other users. DO NOT USE SYS ever.
Thirdly - take the above and change SYS to SYSTEM, same applies. do not use thees accounts - use your OWN accounts.
ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> drop user util;
drop user util
*
ERROR at line 1:
ORA-01918: user 'UTIL' does not exist
ops$tkyte%ORA11GR2> create user util identified by util;
User created.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> grant create session, create procedure, alter system to util;
Grant succeeded.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> connect util/util;
Connected.
util%ORA11GR2>
util%ORA11GR2> CREATE OR REPLACE PROCEDURE dev_flush_cache AS
2 l_ddl VARCHAR2(100);
3 BEGIN
4 l_ddl := 'ALTER SYSTEM FLUSH SHARED_POOL';
5 dbms_output.put_line(l_ddl);
6 EXECUTE IMMEDIATE l_ddl;
7 l_ddl := 'ALTER SYSTEM FLUSH BUFFER_CACHE';
8 dbms_output.put_line(l_ddl);
9 EXECUTE IMMEDIATE l_ddl;
10 END dev_flush_cache;
11 /
Procedure created.
util%ORA11GR2>
util%ORA11GR2> grant execute on dev_flush_cache to scott
2 /
Grant succeeded.
util%ORA11GR2>
util%ORA11GR2> connect scott/tiger
Connected.
scott%ORA11GR2> exec util.dev_flush_cache;
ALTER SYSTEM FLUSH SHARED_POOL
ALTER SYSTEM FLUSH BUFFER_CACHE
PL/SQL procedure successfully completed.
A reader, August 15, 2011 - 1:07 am UTC
Tom,
Thank you. We'll seek other methods instead of flushing the caches on performance testing then. Anyhow it answered the question why the ORA-01031 was caused, that's because ALTER SYSTEM is not granted directly to SYSTEM.
Thank you again.
kill my session in RAC environment
aliyar, February 12, 2013 - 3:59 am UTC
HI Tom,
Thanks for your valuable informations.
can you please clarify below issue.
Database : 11gr2. 4 node RAC
Server : Exadata half rack.
O/s : Linux
i am writing a package for the developers. through which they can view all of their sessions using one function and they can kill their session using another procedure.
kill session procedure looks working fine. No issues.
but view sessions function is not showing the results properly.
suppose , i have only one session for the user " AELYAS " From
instance 01. no sessions from other other nodes. when executing this function , it shows one session additionaly from each nodes.
following is the code for viewing sessions
function List_My_Session return Kill_Table PIPELINED is
begin
for c1 in ( select inst_id,sid,serial#,username,osuser,sql_id from gv_$session
where username in sys_context('USERENV', 'SESSION_USER'))
loop PIPE ROW (Kill_Format(c1.inst_id, c1.sid,c1.serial#,c1.username,c1.osuser,c1.sql_id ));
end loop;
return;
end;
create or replace type Kill_Format
as object(f int,
a int,
b int,
c varchar2(20),
d varchar2(20),
e varchar2(100))
/
create or replace type Kill_Table
as table of Kill_Format
/
then i tested manually as follows:
first as sys user
SYSSQL> select count(*),inst_id from gv$session where username='AELYAS' group by inst_id;
COUNT(*) INST_ID
---------- ----------
1 1
SYSSQL>
it is fine.
now as normal user : granted select on gv_$session to this user
AELYASSQL> select count(*),inst_id from gv$session where username='AELYAS' group by inst_id;
COUNT(*) INST_ID
---------- ----------
2 1
1 2
1 3
1 4
AELYASSQL>
here we can see one addition session from each node apart from the actual one session from node1
i really confused what went wrong here. tried google as well. i could not find any solution
can you please help me here
Thanks
Aliyar
February 12, 2013 - 7:39 am UTC
the query against gv views is executed like a distributed query - we have to hit the SGA on each node.
so, you'll have a session on each node while the gv query itself is running.
kill session for RAC
aliyar, February 12, 2013 - 8:19 am UTC
Thanks tom for immediate reply.
when executing as sys user , we are seeing only one session.
so this behavior is only with non-SYS users ?
is there anyway to fix this issue?
Thanks
Aliyar
February 12, 2013 - 8:30 am UTC
as sys, the sessions would be created for sys, you are looking for user AELYAS, not SYS then.
first as sys user
SYSSQL> select count(*),inst_id from gv$session where username='AELYAS' group by inst_id;
:)
you could look at the current sql being executed in each session as well (join) and filter out the query that is currently running.
I am getting ORA-00031 error while running my procedure
Gaurang, October 18, 2019 - 5:13 pm UTC
I have created a prodedure to kill active session on a perticuler table. Procedure is created with no compilation error. While I was running that procedure to kill multiple active sessions I was getting below error message. what else I should add in my procedure to avoid this error?
ORA-00031: session marked for kill
ORA-06512: at "SYS.PROC_kill_SESSIONS", line 57
ORA-06512: at line 1
00031. 00000 - "session marked for kill"
*Cause: The session specified in an ALTER SYSTEM KILL SESSION command
cannot be killed immediately (because it is rolling back or blocked
on a network operation), but it has been marked for kill. This
means it will be killed as soon as possible after its current
uninterruptable operation is done.
*Action: No action is required for the session to be killed, but further
executions of the ALTER SYSTEM KILL SESSION command on this session
may cause the session to be killed sooner.
Status was not changing to KILL even after running this proc.
PS: I don't want to kill session through OS command and need to use oracle procedure only.
October 21, 2019 - 6:20 am UTC
When you kill a session, it is like *asking* the session to die, ie, "Hey, please stop".
Most of the time, the session will see this request and kill itself off. But if the session is totally hung/frozen then it might not be able to even do that.
Another possibility is that lets say your session has changed 1,000,000 rows and has not yet committed. Then when you kill it, then before it can be truly dead, it must rollback all those changes.
It is in situations like this, that you'll see things such as "session marked for kill". We *tried* to kill it, but it didn't sort itself out in 60 seconds.
For options, check out my killing sessions presentation
https://www.slideshare.net/hamcdc/oow19-killing-database-sessions