码上焚香

Yahocen

解决达梦v8数据库会话阻塞问题

7
2025-12-18

在使用 disql 工具操作达梦数据库时,若执行 INSERT语句后未提交事务(COMMIT)就直接断开会话,该事务会被回滚,但其占用的资源(如表锁)可能不会被立即释放。这会导致对应表被长时间锁定,进入阻塞状态。

在此之后,任何新开启的会话再尝试向该表执行 INSERT操作时,都会被挂起,SQL 语句无任何响应,处于持续等待的状态。如果此时有频繁的插入操作发起,这些新请求会依次进入一个阻塞队列。随着队列不断增长,最终可能导致系统资源耗尽,影响其他业务的正常运行。

首先,执行以下 SQL 查询,找出当前所有的阻塞会话。该语句会列出阻塞者(BLOCKER)和被阻塞者(BLCOKED)的信息,结果的第一个字段通常是会话ID(SESS_ID)

with sel_lock as
 (SELECT O.NAME, O.schid, o.pid, L.*
    FROM V$LOCK L, SYSOBJECTS O
   WHERE L.TABLE_ID = O.ID
     AND BLOCKED = 1),
locks as
 (select b.sess_id, b.sql_text, a.name, a.addr, a.schid, b.trx_id,b.appname,b.clnt_ip,b.sess_seq
    from sel_lock a, V$sessions b
   where a.trx_id = b.trx_id),
locks_wait as
 (select b.sess_id, b.sql_text, a.addr, b.trx_id
    from sel_lock a, V$sessions b
   where a.tid = b.trx_id)
select 'call sp_close_session('||b.sess_id||');' as sp_kill_session,
       a.sess_id 被阻塞会话,
       a.sql_text 被阻塞语句,
       b.sess_id 造成阻塞会话,
       b.sql_text 造成阻塞语句,
       a.name,
       (select name
          from sysobjects
         where ID = a.schid
           and type$ = 'SCH') 模式名,
           a.sess_id 会话ID,
           a.appname 链接来源,
           a.clnt_ip 链接地址,
           a.sess_seq 会话序列号
  from locks a, locks_wait b
 where a.addr = b.addr;

如果清理不干净使用第二种查询语句找出当前的阻塞者(BLOCKER)会话。这些会话是导致问题的根源,通常是那些开启了事务但未提交的会话。

在查询结果中,仔细甄别出这些“罪魁祸首”会话的 SESS_ID,然后仅对这些特定的 SESS_ID​ 执行 SP_CLOSE_SESSION()进行关闭。

SELECT * FROM V$SESSIONS where trx_id in (select id from  v$trx where statUS ='ACTIVE') and sess_id != sessid;