Você está na página 1de 5

4 Best Ways to Find Blocking Sessions

in Oracle 11g
Blocking sessions occur when one sessions holds an exclusive lock on an object and
doesn't release it before another sessions wants to update the same data. This will
block the second until the first one has done its work. It mainly happens when a session
issues an insert, update or delete command that changes a row. When the change
occurs, the row is locked until the session either commits the change or rolls the change
back.

From the view of the user it will look like the application completely hangs while waiting
for the first session to release its lock. You'll often have to identify these sessions in
order to improve your application to avoid as many blocking locks as possible.

.You can see where problems might occur, for example a user might make a change
and then forget to commit it and leaves for the weekend without logging off the system.

Oracle provide views like, DBA_BLOCKERS and V$LOCK using which we can easily
find the blocking locks. Here, we will try to find blocking locks using V$LOCK view which
is faster to query and makes it easy to identify the blocking session.
SQL> select * from v$lock ;
ADDR KADDR
SID TY
ID1
ID2
LMODE REQUEST
BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------------------------------------------AF8E2C4C AF9E2C50
419 TX 141028
15289
0
6
0
ADDF7EC8 ADDF8EE0 542 TM 77529
0
3
0
0
ADDF7F74 ADDF7F8C 419 TM 77529
0
3
0

CTIME

675
687
675

0
ADEBEA20 ADEBEB4C 542 TX
1

141028

152899

687

Here we are interested in the BLOCK column. If a session holds a lock that's blocking
another session, BLOCK=1. Further, you can tell which session is being blocked by
comparing the values in ID1 and ID2. The blocked session will have the same values in
ID1 and ID2 as the blocking session, and, since it is requesting a lock it's unable to get,
it will have REQUEST > 0.
In the query above, we can see that SID 542 is blocking SID 419. SID 542 corresponds
to Session 1 in our example, and SID 419 is our blocked Session 2. To avoid having to
stare at the table and cross-compare ID1's and ID2's, put this in a query:
Query to find Blocking sessions using v$lock
SQL> select l1.inst_id,l1.sid, ' IS BLOCKING ',
l2.sid,l1.type,l2.type,l1.lmode,l2.lmode,l2.inst_id
from gv$lock l1, gv$lock l2
where l1.block =1 and l2.request > 0
and l1.id1=l2.id1
and l1.id2=l2.id2;

To Get Detailed information on blocking locks


SQL> SELECT 'Instance '||s1.INST_ID||' '|| s1.username || '@' || s1.machine
|| ' ( SID=' || s1.sid || ','|| s1.serial#||s1.status|| ' ) is blocking '
|| s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' ||s2.sql_id
FROM gv$lock l1, gv$session s1, gv$lock l2, gv$session s2
WHERE s1.sid=l1.sid AND
s1.inst_id=l1.inst_id AND
s2.sid=l2.sid AND
s2.inst_id=l2.inst_id AND
l1.BLOCK=1 AND
l2.request > 0 AND
l1.id1 = l2.id1 AND

l2.id2 = l2.id2 ;

Finding blocking sessions with v$session


set lines 1234 pages 9999
col inst_id for a10
col serial# for a10
col machine for a30
col username for a10
col event for a20
col blocking_session for 999999
col blocking_instance for 999999
col status for a10
col INST_ID for 9999
col SERIAL# for 999999
SQL> select inst_id,sid,serial#, machine, username, event, blocking_session,
blocking_instance, status, sql_id from gv$session where status ='ACTIVE'and
username is not null;
Finding SQL_ID from SID using v$session
SQL> select sql_id from v$session where sid=4120;
SQL_ID
-------------

SQL> select sql_fulltext from v$sql where sql_id ='xxxxx';

Killing Oracle Sessions


Be very careful when identifying the session to be killed. If you kill a session belonging
to a background process you will cause an instance crash.
There are a number of ways to kill blocking sessions both from Oracle sql prompt and

externally.
Identify the Session to be Killed
ALTER SYSTEM KILL SESSION
ALTER SYSTEM DISCONNECT SESSION
The Windows Approach
The UNIX Approach
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
This does not affect the work performed by the command, but it returns control back to
the current session immediately, rather than waiting for confirmation of the kill.
In a RAC environment, you optionally specify the INST_ID, shown when querying the
GV$SESSION view. This allows you to kill a session on different RAC node.
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id';
SQL> ALTER SYSTEM DISCONNECT SESSION 'SID,SERIAL#' IMMEDIATE;
The DISCONNECT SESSION command kills the dedicated server process, which is
equivalent to killing the server process from the operating system
kill -9 spid
To identifying blocked objects
The view v$lock we've already used in the queries above exposes even more
information. There are differnet kind of locks - check this site for a complete list:
http://download.oracle.com/docs/cd/B13789_01/server.101/b10755/dynviews_1123.htm
#sthref3198
If you encounter a TM lock is means that two sessions are trying to modify some data
but blocking each other. Unless one sessions finished (commit or rollback), you'll never
have to wait forever.
The following queries shows you all the TM locks:

SELECT sid, id1 FROM v$lock WHERE TYPE='TM'


SID
ID1
92
20127
51
20127
The ID you get from this query refers to the actual database object which can help you
to identify the problem, look at the next query:
SELECT object_name FROM dba_objects WHERE object_id=20127
These queries should help you to identify the cause of your blocking sessions!

Você também pode gostar