欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

达梦数据库如何解决sql卡住的问题

程序员文章站 2022-05-08 23:02:36
一次遇到一个表锁住了,导致对这个表的子表做相关的操作也被锁住的情况,但是当时只能查询到子表对应的sql的sess_id,找不到父表锁住的sql对应的sess_id,后来在付总等的帮助下成功解决了问题,下面把方法描述下。1、先select count(*) from v$lock where lmode = 'X' and table_id <> 0; 看看多不多,如果很多的话就要分开分析。a、知道被锁住的表,从sysobjects里面找到对应的table_id,select ......

 

一次遇到一个表锁住了,导致对这个表的子表做相关的操作也被锁住的情况,但是当时只能查询到子表对应的sql的sess_id,找不到父表锁住的sql对应的sess_id,后来在付总等的帮助下成功解决了问题,下面把方法描述下。

 

1、先select count(*) from v$lock where lmode = 'X' and table_id <> 0; 看看多不多,如果很多的话就要分开分析。

a、知道被锁住的表,从sysobjects里面找到对应的table_id,select id from sysobjects where name = '锁住表的表名';

   select trx_id,ltype,lmode,table_id from v$lock where table_id=锁住表的id;

   然后到v$sessions中找出对应的sess_id,select * from v$sessions where trx_id = trx1;(trx1上面的sql查询出来的事务ID);

   然后执行sp_close_session(sess_id);即可。(注意确认能否杀)

b、不知道被锁住的表,这个可以根据table_id找出阻塞的sql。

 

with locks as(

 

select o.name,l.*,s.sess_id,s.sql_text,s.clnt_ip

 

  from v$lock l,sysobjects o,v$sessions s

 

  where l.table_id=o.id and l.trx_id=s.trx_id ),

 

lock_tr as (

 

    select trx_id wt_trid,row_idx blk_trid from locks where blocked=1),

 

res as(

 

    select sysdate stattime,t1.name,t1.sess_id wt_sessid,s.wt_trid,t1.sql_text wt_sql,

 

     t2.sess_id blk_sessid,s.blk_trid,t2.clnt_ip

 

    from lock_tr s,locks t1,locks t2

 

    where t1.ltype='OBJECT'

 

     and t1.table_id<>0

 

     and t2.ltype='OBJECT'

 

     and t2.table_id<>0

 

     and s.wt_trid=t1.trx_id

 

     and s.blk_trid=t2.trx_id)

 

select * from res;

 

然后再杀掉锁住的会话;

2、select count(*) from v$lock where lmode = 'X' and table_id =0;然后根据这个里面的trx_id在v$sessions里面查询,如果发现查询到的是查询语句,

表明这个查询语句之前可能做了增删改,这里看不到了,那可以在v$sql_history里面找(这个需要enable_monitor>=2)

select top_sql_text from v$sql_history where trx_id = 可疑的事务id;

但是这个v$sql_history只保存最近的语句,如果session中,增删改之后,做了很多的查询语句,有可能也会被冲掉,查询不到结果的。

还有一种可能,就是引发卡住的增删改语句,被新的、不引发卡住增删改语句给冲掉了,

select count(*) from v$lock where lmode = 'X' and table_id =0;记录太多,不好分析时,可借助v$trxwait来分析,到底哪个事务才是真正的罪魁祸首。

执行select * from v$trxwait;(ID 事务 ID ;WAIT_FOR_ID  所等待的事务 ID)

比如trx1在t1上更新没提交,导致trx2也被卡住了,通过v$trxwait可以找到trx2的trx_id,

再通过v$session查trx2的sql,就知道是操作什么表被阻塞了。在v$sessions中不一定能找到trx1的导致卡住的SQL,但肯定能找到trx2的被卡住的SQL。

 

3、如果实在找不到SQL语句,利用sess_id或trx id,如果log_commit打开了,在log_commit里面应该也能找到sql,然后再针对具体的sql进行分析。

 

本文地址:https://blog.csdn.net/weixin_42447367/article/details/107675848