一、解锁
有可能在一个大事务中,对同一张表进行两次操作【可能是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;