当前位置: 移动技术网 > IT编程>数据库>MSSQL > 达梦数据库如何解决sql卡住的问题

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

2020年07月30日  | 移动技术网IT编程  | 我要评论
一次遇到一个表锁住了,导致对这个表的子表做相关的操作也被锁住的情况,但是当时只能查询到子表对应的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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网