zoukankan      html  css  js  c++  java
  • 【实验】【LOCK】“锁等待”模拟、诊断及处理方法[转]

    前言:在您维护数据库的过程中一定听说过某位同事说:我的这条如此简单的SQL语句为什么20多分钟了还没有执行完成?在处理这类问题的时候记得把“锁等待”因素考虑进去。具体的实验如下。

    1.模拟“锁等待”现象
    1)开启一个终端创建测试表test_lock,插入一条数据,模拟更新该条数据,但不提交
    sys@orcl> conn sec/sec
    Connected.
    sec@orcl> create table test_lock ( a int );

    Table created.

    sec@orcl> insert into test_lock values ( 1 );

    1 row created.

    sec@orcl> commit;

    Commit complete.

    sec@orcl> select * from test_lock;

             A
    ----------
             1

    sec@orcl> update test_lock set a = 2;

    1 row updated.

    2)再另外开启一个终端,对同样的行进行另外的更新,随即出现锁等待的现象
    sys@orcl> conn sec/sec
    Connected.
    sec@orcl>
    sec@orcl>
    sec@orcl> update test_lock set a = 3;

    因为更新都是test_lock表中1这行的记录,第一个用户提交了修改但是没有提交,在这里会出现无法继续执行的现象,这种现象就是“锁等待”,千万不要再说这个现象是“死锁”啦,“死锁”Oracle是会自己处理的,有兴趣的朋友可以查询死锁产生的四个条件,我们这个实验只是讨论最容易出现的“锁等待”现象的处理方法。

    2.检测
    “锁等待”方法
    sys@orcl> @lock

    lock                      lock
    holder                  holder            lock                                lock   request               blocked
    username            session id    SERIAL# type           id1         id2      mode      mode      BLOCK session id
    ------------------ ----------- ---------- ------ ----------- ----------- --------- --------- ---------- ----------
    SEC                        148      23007 TM          303038           0         3         0          0
    SEC                        153      18219 TM          303038           0         3         0          0
    SEC                        153      18219 TX          262159      306200         6         0          1        148
                               165          1 TS               3           1         3         0          0
                               166          1 CF               0           0         2         0          0
                               166          1 RS              25           1         2         0          0
                               166          1 XR               4           0         1         0          0
                               167          1 RT               1           0         6         0          0

    8 rows selected.

    通过上面脚本的执行可以清楚的看出,首先,存在锁等待现象,因为最后一列存在不为空的会话id信息,其次,可以通过上面所列出来的锁的信息判断出因为153会话中执行的SQL语句导致148会话的SQL语句无法执行。

    3.
    “锁等待”处理方法
    1)温柔方法
    通过个人魅力找到153会话操作的弟兄,温柔的提醒他请将未提交的SQL语句做提交或回滚处理,以便释放相应的行级锁。
    2)暴力方法
    直接杀死153会话,方法如下:
    sys@orcl> alter system kill session '153,18219';

    System altered.
    到此,向你抱怨长时间未运行完成的SQL语句神奇般的恢复了本应有的速度。

    4.OK,是该隆重推出我用来检测
    “锁等待”的脚本的时候了,大家请看
    ---------------------------------------------------
    -- Script. Function: Query the lock info         --
    -- Script. Name:     lock.sql                    --
    -- Author:           secooler                    --
    -- Date:             2008.3.6                    --
    ---------------------------------------------------

    set pages 1000 lin 126
    col kaddr heading 'lock|address'
    col username heading 'lock|holder|username' for a18
    col sid heading 'lock|holder|session id' format 9999999999
    col type heading 'lock|type' format a6
    col id1 heading 'id1' format 9999999999
    col id2 heading 'id2' format 9999999999
    col lmode heading 'lock|mode' format 99999999
    col request heading 'request|mode' format 99999999
    col blocking_sid format 999999 heading 'blocked|session id'
    select /*+rule*/
    --     a.kaddr, --
         (select username from v$session where sid = a.sid) username,
         a.sid,
         (select serial# from v$session where sid = a.sid) serial#,
    --     (select ctime from v$lock where KADDR = a.kaddr) ctime, --
         a.type,
         a.id1,
         a.id2,
         a.lmode,
         a.request,
         a.block,
         b.sid blocking_sid
    from v$lock a,
         ( select * from v$lock
           where request > 0
           and type <> 'MR'
         ) b
    where a.id1 = b.id1(+)
      and a.id2 = b.id2(+)
      and a.lmode > 0
      and a.type <> 'MR'
    order by username,a.sid,serial#,a.type
    /

    column sid clear
    column type clear
    column request clear
    column username clear

    5.总结
    “锁等待”现象是一种常见的数据库问题,往往出现在多人(往往是技术支持人员)同时操作数据库的时候。在出现此类问题的时候,要沉着、认真、快速、准确的定位问题,排除故障。当然如果能采用非常严格的数据库操作制度以便防止此类问题的发生的话,那是最好不过的了,所以说七分管理三分处理。
    好运!

    -- The End --

     
     
     
     
     
     
     
  • 相关阅读:
    10 个深恶痛绝的 Java 异常。。
    为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
    推荐一款代码神器,代码量至少省一半!
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝。。
    hdu 3853 LOOPS(概率 dp 期望)
    hdu 5245 Joyful(期望的计算,好题)
    hdu 4336 Card Collector(期望 dp 状态压缩)
    hdu 4405 Aeroplane chess(概率+dp)
    hdu 5036 Explosion(概率期望+bitset)
    hdu 5033 Building (单调栈 或 暴力枚举 )
  • 原文地址:https://www.cnblogs.com/einyboy/p/2589717.html
Copyright © 2011-2022 走看看