一、解锁

有可能在一个大事务中,对同一张表进行两次操作【可能是update和delete同时发生】,两个操作都在等其他释放锁,导致一直卡在那,查询的锁表语句,一般查询出来的锁表语句是后面的那个操作所形成的锁表语句,需要杀死锁表的操作,前面的操作就会持久到数据库,后面的操作就不会持久到数据库。

1 解锁语句【大部分人博客,比较着急】

SELECT l.session_id sid, s.serial#, l.locked_mode,l.oracle_username,
l.os_user_name,s.machine, s.terminal, o.object_name, s.logon_time
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid, s.serial# ;

ALTER SYSTEM KILL SESSION '2118,28870';

2 查找具体的锁表语句【这个最好本地连生产,比较方便看自己锁表的是哪几条记录】

--查看那张表锁了,以及SQL_HASH_VALUE

SELECT object_name 被锁表 , machine 所属机器, l.ORACLE_USERNAME 表所在用户,s.sid, s.serial# ,s.LOCKWAIT ,s.SQL_HASH_VALUE
FROM gv$locked_object l, dba_objects o, gv$session s 
WHERE l.object_id = o.object_id 
AND l.session_id = s.sid ;
--and o.Object_Name='QINTIAN_DATA_HEADER' ;

--SOL_HASH_VALUE 用查询出来的查询具体的锁表语句,查询程序原因

select * from v$sql a where a.HASH_VALUE = '2612866132'

方法一

万能解锁语句(没用过)

CREATE OR REPLACE PROCEDURE DB_KILL_LOCK_CLIENTS AUTHID DEFINER AS
BEGIN
    FOR REC IN
        (select distinct sid,serial#,inst_id from
        (SELECT object_name, machine, s.sid, s.serial#,s.inst_id,lo.lmode,lo.request,lo.ctime
         FROM gv$locked_object l, dba_objects o, gv$session s,gv$lock lo
         WHERE l.object_id = o.object_id
         AND l.session_id = s.sid
         AND l.session_id = lo.sid
         AND s.inst_id=lo.inst_id
         and lo.lmode=6
         and lo.ctime>10
         and s.username not in ('SYS','SYSTEM')
         AND lo.sid in (select final_blocking_session from gv$session where event='enq: TX - row lock contention' and final_blocking_session is not null)))
    LOOP
      execute immediate 'alter system kill session '''|| rec.sid || ', ' || rec.serial# || ',@'||rec.inst_id||''' immediate' ;
    END LOOP;
END DB_KILL_LOCK_CLIENTS;

方法二

--批量解锁语句生成

select a.object_name,b.session_id,c.serial#,'alter system kill session '''||b.session_id||','||c.serial#||'''; ' as a,c.program,c.username,c.command,c.machine,c.lockwait
from all_objects a,v$locked_object b,v$session c where a.object_id=b.object_id and c.sid=b.session_id;

二、查看什么语句导致锁表及相关参数

1 查询sql_hash_value

SELECT object_name 被锁表 , machine 所属机器, l.ORACLE_USERNAME 表所在用户,s.sid, s.serial# ,s.LOCKWAIT ,s.SQL_HASH_VALUE
FROM gv$locked_object l, dba_objects o, gv$session s 
WHERE l.object_id = o.object_id 
AND l.session_id = s.sid ;

2 什么sql 堵塞了  last_active_time  一长串的前面

select * from v$sql a where a.HASH_VALUE = '2612866132'

3 查询sql的参数

select b.name, b.datatype_string, b.value_string, b.last_captured
  from dba_hist_sqlbind b
 where b.sql_id ='0qnyc6fdvub2n' ORDER BY b.LAST_CAPTURED;