快速查出Oracle数据库中锁等待的方法(2)
此时,若发现该阻塞其它用户进程的进程是正常操作中,则可通知该用户对其进行提交,从而达到释放锁资源的目的;若为未正常操作,即,其状态为"inactive",且其last_call_et已为较多长时间,则可执行以下语句将该进程进行清除,系统会自动对其进行回滚,从而释放锁住的资源。
alter system kill session 'sid, serial#';
SQL 脚本如下:
set echo off set feedback off prompt '删除旧记录.....' truncate table my_session; truncate table my_lock; truncate table my_sqltext; prompt '获取数据.....' insert into my_session select a.username, a.sid, a.serial#, a.lockwait, a.machine,a.status, a.last_call_et,a.sql_hash_value,a.program from v$session a where nvl(a.username,'NULL')< >'NULL; insert into my_lock select id1, kaddr, sid, request,type from v$lock; insert into my_sqltext select hash_value , sql_text from v$sqltext s, my_session m where s.hash_value=m.sql_hash_value; column username format a10 column machine format a15 column last_call_et format 99999 heading "Seconds" column sid format 9999 prompt "正在等待别人的用户" select a.sid, a.serial#, a.machine,a.last_call_et, a.username, b.id1 from my_session a, my_lock b where a.lockwait = b.kaddr; prompt "被等待的用户" select a.sid, a.serial#, a. machine, a.last_call_et,a.username, b. b.type,a.status,b.id1 from my_session a, my_lock b where b.id1 in (select distinct e.id1 from my_session d, my_lock e where d.lockwait = e.kaddr) and a.sid = b.sid and b.request=0; prompt "查出其 sql " select a.username, a.sid, a.serial#, b.id1, b.type, c.sql_text from my_session a, my_lock b, my_sqltext c where b.id1 in (select distinct e.id1 from my_session d, my_lock e where d.lockwait = e.kaddr) and a.sid = b.sid and b.request=0 and c.hash_value =a.sql_hash_value;
以上思路也可用于其它大型数据库系统如 Informix, Sybase,DB2中。通过使用该脚本,可以极大地提高获取系统中当前锁等待的情况,从而及时解决数据库应用系统中的锁等待问题。而且,由于实际上已取出其 program 名及相应的 sql 语句,故可以在事后将其记录下来,交给其开发人员进行分析并从根本上得到解决。