How to Kill a Running Select Statement

How to kill a running SELECT statement

As you keep getting pages of results I'm assuming you started the session in SQL*Plus. If so, the easy thing to do is to bash ctrl + break many, many times until it stops.

The more complicated and the more generic way(s) I detail below in order of increasing ferocity / evil. The first one will probably work for you but if it doesn't you can keep moving down the list.

Most of these are not recommended and can have unintended consequences.


1. Oracle level - Kill the process in the database

As per ObiWanKenobi's answer and the ALTER SESSION documentation

alter system kill session 'sid,serial#';

To find the sid, session id, and the serial#, serial number, run the following query - summarised from OracleBase - and find your session:

select s.sid, s.serial#, p.spid, s.username, s.schemaname
, s.program, s.terminal, s.osuser
from v$session s
join v$process p
on s.paddr = p.addr
where s.type != 'BACKGROUND'

If you're running a RAC then you need to change this slightly to take into account the multiple instances, inst_id is what identifies them:

select s.inst_id, s.sid, s.serial#, p.spid, s.username
, s.schemaname, s.program, s.terminal, s.osuser
from Gv$session s
join Gv$process p
on s.paddr = p.addr
and s.inst_id = p.inst_id
where s.type != 'BACKGROUND'

This query would also work if you're not running a RAC.

If you're using a tool like PL/SQL Developer then the sessions window will also help you find it.

For a slightly stronger "kill" you can specify the IMMEDIATE keyword, which instructs the database to not wait for the transaction to complete:

alter system kill session 'sid,serial#' immediate;

2. OS level - Issue a SIGTERM

kill pid

This assumes you're using Linux or another *nix variant. A SIGTERM is a terminate signal from the operating system to the specific process asking it to stop running. It tries to let the process terminate gracefully.

Getting this wrong could result in you terminating essential OS processes so be careful when typing.

You can find the pid, process id, by running the following query, which'll also tell you useful information like the terminal the process is running from and the username that's running it so you can ensure you pick the correct one.

select p.*
from v$process p
left outer join v$session s
on p.addr = s.paddr
where s.sid = ?
and s.serial# = ?

Once again, if you're running a RAC you need to change this slightly to:

select p.*
from Gv$process p
left outer join Gv$session s
on p.addr = s.paddr
where s.sid = ?
and s.serial# = ?

Changing the where clause to where s.status = 'KILLED' will help you find already killed process that are still "running".

3. OS - Issue a SIGKILL

kill -9 pid

Using the same pid you picked up in 2, a SIGKILL is a signal from the operating system to a specific process that causes the process to terminate immediately. Once again be careful when typing.

This should rarely be necessary. If you were doing DML or DDL it will stop any rollback being processed and may make it difficult to recover the database to a consistent state in the event of failure.

All the remaining options will kill all sessions and result in your database - and in the case of 6 and 7 server as well - becoming unavailable. They should only be used if absolutely necessary...

4. Oracle - Shutdown the database

shutdown immediate

This is actually politer than a SIGKILL, though obviously it acts on all processes in the database rather than your specific process. It's always good to be polite to your database.

Shutting down the database should only be done with the consent of your DBA, if you have one. It's nice to tell the people who use the database as well.

It closes the database, terminating all sessions and does a rollback on all uncommitted transactions. It can take a while if you have large uncommitted transactions that need to be rolled back.

5. Oracle - Shutdown the database ( the less nice way )

shutdown abort

This is approximately the same as a SIGKILL, though once again on all processes in the database. It's a signal to the database to stop everything immediately and die - a hard crash. It terminates all sessions and does no rollback; because of this it can mean that the database takes longer to startup again. Despite the incendiary language a shutdown abort isn't pure evil and can normally be used safely.

As before inform people the relevant people first.

6. OS - Reboot the server

reboot

Obviously, this not only stops the database but the server as well so use with caution and with the consent of your sysadmins in addition to the DBAs, developers, clients and users.

7. OS - The last stage

I've had reboot not work... Once you've reached this stage you better hope you're using a VM. We ended up deleting it...

How to kill/stop a long SQL query immediately?


What could the reason be

A query cancel is immediate, provided that your attention can reach the server and be processed. A query must be in a cancelable state, which is almost always true except if you do certain operations like calling a web service from SQLCLR. If your attention cannot reach the server it's usually due to scheduler overload.

But if your query is part of a transaction that must rollback, then rollback cannot be interrupted. If it takes 10 minutes then it needs 10 minutes and there's nothing you can do about it. Even restarting the server will not help, it will only make startup longer since recovery must finish the rollback.

To answer which specific reason applies to your case, you'll need to investigate yourself.

How can I stop a running MySQL query?


mysql> show processlist;
+----+------+-----------+-----+---------+------+---------------------+------------------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+-----------+-----+---------+------+---------------------+------------------------------+----------+
| 14 | usr1 | localhost | db1 | Query | 0 | starting | show processlist | 0.000 |
| 16 | usr1 | localhost | db1 | Query | 94 | Creating sort index | SELECT `tbl1`.* FROM `tbl1` | 0.000 |
+----+------+-----------+-----+---------+------+---------------------+------------------------------+----------+
2 rows in set (0.000 sec)

mysql> kill 16;
Query OK, 0 rows affected (0.004 sec)

mysql> show processlist;
+----+------+-----------+-----+---------+------+----------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+-----------+-----+---------+------+----------+------------------+----------+
| 14 | usr1 | localhost | db1 | Query | 0 | starting | show processlist | 0.000 |
+----+------+-----------+-----+---------+------+----------+------------------+----------+
1 row in set (0.000 sec)

Is it possible to kill a single query in oracle without killing the session?

I found a trick. I have no idea how safe this is to play with, but it does work. There is an Oracle event, 10237, which is described as "simulate ^C (for testing purposes)".

You have to have the SID and SERIAL# of the session you want to interrupt.

Call SYS.DBMS_SYSTEM.SET_EV( sid, serial#, 10237, 1, '' ) to activate the event in the target session. Any currently executing statement should be interrupted (receiving "ORA-01013: user requested cancel of current operation"). As long as the event is set, any further statements the session attempts to execute will immediately terminate with the same error.

To deactivate the event, make the same call with the fourth parameter set to "0". The session will then be able to execute statements again.

Note that the target session has to detect that the event is set, which may take time, or may never happen, depending on what it is doing. So you can't just quickly toggle the event on and off. You would need to turn it on, verify that the statement in question has stopped, then turn it off.

Here's some sample code. This is meant to be run as an anonymous block in SQLPlus, with substitution variables "sid" and "serial" defined appropriately. You could turn it into a stored procedure with those as its parameters.

DECLARE
l_status v$session.status%TYPE;
BEGIN

dbms_system.set_ev( &sid, &serial, 10237, 1, '');

LOOP
SELECT status INTO l_status FROM v$session
WHERE sid = &sid and serial# = &serial;
EXIT WHEN l_status='INACTIVE';
END LOOP;

dbms_system.set_ev( &sid, &serial, 10237, 0, '');
END;

How to stop a running query?

I've just stumbled upon the odbc package. It allows to interrupt a query at any time.

Basic usage goes like this:

library(DBI)

myconnection <- dbConnect(odbc::odbc(),
driver = "SQL Server",
server = "my_server_IP_address",
database = "my_DB_name",
uid = "my_user_id",
pwd = "my_password")

dbGetQuery(myconnection, myquery)

I don't have a deep understanding of what happens behind the scenes, but for what I've seen so far in my personal use this package has other advantages over RODBC:

  • really faster
  • get the column types from the DB instead of guessing them (see here)
  • no stringsAsFactors and as.is arguments necessary

How to kill running sessions of a user in oracle with single sql query?

Simply put (as far as I can tell), you can't do that.

Sessions are killed one-by-one, not all-sessions-for-user.

If you want to do that using a single line of code (as a final result), create a stored procedure which will do the job for you.

Connected as user which has privileges to do that (such as SYS, unless you created your own user for such purposes):

SQL> set serveroutput on;
SQL> create or replace procedure p_kill (par_username in varchar2) is
2 l_str varchar2(100);
3 begin
4 for cur_r in (select s.sid, s.serial#
5 from v$session s
6 where s.username = par_username
7 )
8 loop
9 l_str := 'alter system kill session ' || chr(39) ||
10 cur_r.sid || ', '|| cur_r.serial# || chr(39);
11 dbms_output.put_line(l_str);
12 execute immediate l_str;
13 end loop;
14 end;
15 /

Procedure created.

I have two sessions (opened in two separate SQL*Plus windows) for user MIKE and I want to kill them all:

SQL> exec p_kill ('MIKE');
alter system kill session '12, 133'
alter system kill session '139, 265'

PL/SQL procedure successfully completed.

SQL>

How does it reflect to MIKE? Like this:

SQL> select * From tab;
select * From tab
*
ERROR at line 1:
ORA-00028: your session has been killed


SQL>

So, as you can see, at the end this is all you need:

exec p_kill ('MIKE');

How to stop a running command in oracle 11g DBMS

In 11g, you need to kill the session on which that procedure is running.

You can select the sessions with below query then find out the one you want to kill/stop.

select sid, serial#, status from v$session where USERNAME='NAME';

Then kill it with below command

ALTER SYSTEM KILL SESSION 'SID,SERIAL#';

In 18c+, you can cancel the currently running statement associated with a session:

ALTER SYSTEM CANCEL SQL 'SID, SERIAL#';

Automatically kill session of some specific task

Sometimes I use this old query to get rid of sessions with specific description:

declare @t table (sesid int)

--Here we put all sessionid's with specific description into temp table
insert into @t
select spid
from sys.sysprocesses
where dbid = db_id()
and spid <> @@SPID
and blocked <> 0
and lastwaittype LIKE 'LCK%'

DECLARE @n int,
@i int= 0,
@s int,
@kill nvarchar(20)= 'kill ',
@sql nvarchar (255)

SELECT @n = COUNT(*) FROM @t
--Here we execute `kill` for every sessionid from @t in while loop
WHILE @i < @n
BEGIN
SELECT TOP 1 @s = sesid from @t
SET @sql = @kill + cast(@s as nvarchar(10))

--select @sql
EXECUTE sp_executesql @sql

delete from @t where sesid = @s
SET @i = @i + 1
END

How to find MySQL process list and to kill those processes?

Here is the solution:

  1. Login to DB;
  2. Run a command show full processlist;to get the process id with status and query itself which causes the database hanging;
  3. Select the process id and run a command KILL <pid>; to kill that process.

Sometimes it is not enough to kill each process manually. So, for that we've to go with some trick:

  1. Login to MySQL;
  2. Run a query Select concat('KILL ',id,';') from information_schema.processlist where user='user'; to print all processes with KILL command;
  3. Copy the query result, paste and remove a pipe | sign, copy and paste all again into the query console. HIT ENTER. BooM it's done.


Related Topics



Leave a reply



Submit