zoukankan      html  css  js  c++  java
  • 【熟能生巧】查看Oracle DB Lock及快速处理

    问题

    在开发时,遇到一个问题,我运行了一个简单的 update 语句如下:

    update table_a set column_b = 'something' where condition_c = 'blablabla';
    

    但是,执行了很久都没有完成。等了大概有 5 分钟,还在 run 。这个表不是很大,写入也不多,平时都是秒杀的。

    分析长时间运行的语句

    首先,看一下现在有没有 long running sql 。

    -- check long running sql
    select ses.osuser, nvl(ses.username,'ORACLE PROC')||' ('||ses.sid||')'
           username, sid, machine, replace(sql.sql_text,chr(10),'') stmt,
           ltrim(to_char(floor(ses.last_call_et/3600), '09')) || ':' ||
           ltrim(to_char(floor(mod(ses.last_call_et, 3600)/60), '09')) || ':' ||
           ltrim(to_char(mod(ses.last_call_et, 60), '09')) runt
      from v$session ses, v$sqltext_with_newlines sql
     where ses.status = 'ACTIVE'
       and ses.username is not null
       and ses.sql_address = sql.address
       and ses.sql_hash_value = sql.hash_value
       and ses.audsid <> userenv('SESSIONID')
     order by runt desc, 1,sql.piece;
    

    结果 ->

    OSUSER   USERNAME        SID    MACHINE        STMT                    RUNT
    oracle   SCEMA_A (1111)	 1111	machine.a.ip   update table_a ...;     10:00:00
    oracle   SCEMA_A (2222)	 2222	machine.b.ip   update table_a ...;     12:00:00
    

    果然有,而且,也是 update 这个 table_a ,且已经跑了10几个小时了。

    由此判断,应该是这个表被锁住了,所以 block 了其它想要 update 的语句。

    查看锁

    使用如下语句查看锁:

    -- check lock
    select
       (select username from v$session where sid=a.sid) blocker,
       a.sid,
       ' is blocking ',
       (select username from v$session where sid=b.sid) blockee,
       b.sid
    from
       v$lock a,
       v$lock b
    where
       a.block = 1
    and
       b.request > 0
    and
       a.id1 = b.id1
    AND
       A.ID2 = B.ID2;
    

    结果 ->

    BLOCKER   SID    ISBLOCKING     BLOCKEE   SID_1
    SCEMA_A	  3333   is blocking 	SCEMA_A	  1111
    SCEMA_A	  3333	 is blocking 	SCEMA_A	  2222
    

    果然,发现 SID 为 3333 的这个进程, block 住了 1111 和 2222 。

    进一步,我们来看看这个进程是谁跑的。

    SELECT SES.USERNAME, SES.OSUSER, SES.PROGRAM, SQL.SQL_TEXT 
    FROM V$SESSION SES, V$SQLTEXT_WITH_NEWLINES SQL
    WHERE SES.SID = 428
    AND SES.SQL_ADDRESS = SQL.ADDRESS
    AND SES.SQL_HASH_VALUE = SQL.HASH_VALUE;
    

    结果 ->

    USERNAME  OSUSER       PROGRM          SQL_TEXT
    SCEMA_A   user_aaa     SQL Developer   something
    SCEMA_A   user_aaa     SQL Developer   something
    SCEMA_A   user_aaa     SQL Developer   something
    

    可以看出,这个 3333 是 user_aaa 跑的。但是目前他并没有 run 相关的 update table_a 的 query 。

    解决

    和 user_aaa 讨论过后,知道,原来他之前跑了一句 update table_a ,但是没有 commit ,于是他的 session 一直拿着这个锁。

    让他 commit 一下就好了,锁马上被释放,其它的语句也可以顺利执行完成。

    如果 user_aaa 不在,联系不上咋办呢,把他的 session kill 掉,这个锁也会被释放。

    ALTER SYSTEM KILL SESSION '<3333, 36575>';
    

    参考

  • 相关阅读:
    实验四 决策树算法及应用
    实验三 朴素贝叶斯算法及应用
    实验二 K近邻算法及应用
    实验一 感知器及其应用
    实验三 面向对象分析与设计
    实验二 结构化分析与设计
    实验一 软件的开发文档与工具的安装与使用
    ATM管理系统
    举例分析流程图与活动图的区别与联系
    四则运算
  • 原文地址:https://www.cnblogs.com/maxstack/p/14005210.html
Copyright © 2011-2022 走看看