达梦数据库锁表问题

识别与定位阻塞

20260128_81222b

 

首先,你需要找出是哪个会话持有了锁,并阻塞了其他操作。

  1. 查询当前所有锁的状态:
    执行以下SQL,重点关注BLOCKED=1(表示该锁正在等待)以及LMODE='X'(排他锁,通常由未提交的UPDATEDELETE或DDL操作持有)的记录。

    sql
    SELECT * FROM V$LOCK;
  2. 精确定位阻塞源头:
    使用以下更精确的查询,可以直接找到阻塞其他事务的会话及其正在执行的SQL语句。这是解决问题最关键的一步。

    sql
    -- 查询1:直接关联等待与被等待的事务
    SELECT tw.*, ss.clnt_ip, ss.SQL_TEXT
    FROM V$TRXWAIT tw
    JOIN v$sessions ss ON ss.trx_id = tw.wait_for_id
    ORDER BY wait_time DESC[citation:1];
    
    -- 查询2:综合查询(推荐)
    -- 此查询能一次性展示会话、SQL、锁模式及对象名,信息最全[citation:3]
    SELECT s.sess_id,
           s.sql_text,
           lk.trx_id,
           lk.ltype,
           lk.lmode,
           lk.blocked,
           o.object_name
    FROM v$lock lk
    LEFT JOIN dba_objects o ON lk.table_id = o.object_id
    JOIN v$session s ON s.trx_id = lk.trx_id
    WHERE lk.blocked = 1 OR lk.lmode = 'X'
    ORDER BY lk.blocked DESC, lk.lmode DESC;

    通过以上查询,你将得到关键的 sess_id(阻塞方的会话ID) 和 SQL_TEXT(正在执行的SQL)。

⚡ 步骤二:解除阻塞

定位到阻塞源后,你有两种主流解决方法,请优先尝试第一种。

  • 方法一:提交或回滚产生阻塞的事务(首选)
    如果可行,联系执行该阻塞会话的用户或应用,让其提交(COMMIT)或回滚(ROLLBACK) 当前事务。这是最安全、最规范的方式,可以自然释放锁。

  • 方法二:强制结束阻塞会话
    如果无法联系用户,或者事务本身异常僵死,可以使用系统过程强制结束会话。此操作会导致该会话未提交的事务全部回滚,请务必谨慎评估影响。

    sql
    CALL SP_CLOSE_SESSION('这里填入查询到的sess_id');

    例如:CALL SP_CLOSE_SESSION(123456789);

✅ 步骤三:验证与后续

执行完上述操作后,再次运行步骤一的查询语句,确认BLOCKED=1的记录已消失,锁表问题已解决。  

✅ 步骤四:如果还是只能查询,不能修改,插入,删除,可以定位是否持有“强S锁”的会话

SELECT * FROM v$lock WHERE LMODE='s';

再根据上面查询的trx_id查询sess_id:  SELECT * FROM V$sessions WHERE trx_id='605445788';

最后一步关闭会话:CALL SP_CLOSE_SESSION('会话id');

posted on 2026-01-28 09:55  奔跑吧人生  阅读(0)  评论(0)    收藏  举报

导航