Oracle运维之lock

1.查看是否有死锁

select * from v$lock where block=1

查出锁表语句的 sid 后,可通过如下命令查询对应的 sql:
–根据 sid 查出 sql

select username, sql_text, machine, osuser
  from v$session a, v$sqltext_with_newlines b
 where DECODE(a.sql_hash_value, 0, prev_hash_value, sql_hash_value) =
       b.hash_value
   and a.sid = &sid
 order by piece;

select username, sql_text, machine, osuser
  from v$session a, v$sql b
 where DECODE(a.sql_hash_value, 0, prev_hash_value, sql_hash_value) =
       b.hash_value
   and a.sid = &sid

2.查看当前是否有锁表语句

select * from v$session t1, v$locked_object t2 where t1.sid = t2.SESSION_ID;

3.查看当前被锁对象(非死锁)

select b.owner, b.object_name, a.session_id, a.locked_mode
  from v$locked_object a, dba_objects b
 where b.object_id = a.OBJECT_ID;

SELECT l.session_id sid,  
       s.serial#,  
       l.locked_mode 锁模式,  
       l.oracle_username 登录用户,  
       l.os_user_name 登录机器用户名,  
       s.machine 机器名,  
       s.terminal 终端用户名,  
       o.object_name 被锁对象名,  
       s.logon_time 登录数据库时间  
FROM v$locked_object l, all_objects o, v$session s  
WHERE l.object_id = o.object_id  
   AND l.session_id = s.sid  
ORDER BY sid, s.serial#;

SELECT a.sid, a.serial#, a.username, c.os_user_name
 , a.program, a.logon_time, a.machine, a.terminal
 , b.object_id, substr(b.object_name,1,40) object_name
 , DECODE(c.locked_mode,1, 'No Lock',
                        2, 'Row Share',
                        3, 'Row Exclusive',
                        4, 'Shared Table',
                        5, 'Shared Row Exclusive',
                        6, 'Exclusive') locked_mode
from v$session a, dba_objects b, v$locked_object c
where a.sid = c.session_id
and b.object_id = c.object_id;

SELECT l.session_id sid,
    s.serial#,
    l.locked_mode 锁模式,
    l.oracle_username 登录oracle用户,
    l.os_user_name 登录OS用户名,
    --s.username,
    s.status,
    s.schemaname,
    s.machine 机器名,
    s.terminal 终端用户名,
    s.program,
    s.type,
    s.logon_time 登录数据库时间,
    s.seq#,
    s.event,
    o.object_type,
    o.object_name 被锁对象名,
    c.ctime       "被锁时间(S)"
 FROM v$locked_object l, all_objects o, v$session s ,v$lock c
 WHERE l.object_id = o.object_id
 AND l.session_id = s.sid 
 AND l.session_id = c.sid
 ORDER BY sid, s.serial#;

SELECT l.sid         "会话ID",
       s.serial#     "会话序列号",
       p.spid        "会话进程号",
       l.type        "锁类型",
       s.username    "所属用户",
       s.machine     "客户端",
       o.object_name "被锁对象",
       o.object_type "被锁对象类型",
       l.ctime       "被锁时间(S)"
  FROM v$lock      l, -- addr
       v$session   s, -- saddr 
       dba_objects o, -- object_id 
       v$process   p -- addr 
 WHERE s.sid = l.sid
   AND o.object_id = l.id1
   AND p.addr = s.paddr
   AND l.type IN ('TM', 'TX')  -- 只需要关注 TM / TX 锁即可
-- AND s.username = ''
-- AND l.sid=768
-- AND l.block=1
;

SELECT /*+ rule */
       S.USERNAME,
       DECODE(L.TYPE, 'TM', 'TABLE LOCK', 'TX', 'ROW LOCK', NULL) LOCK_LEVEL,
       Decode(L.LMode,0,'[0] none',
                      1,'[1] null 空',
                      2,'[2] Row-S 行共享(RS):共享表锁,sub share ',
                      3,'[3] Row-X 行独占(RX):用于行的修改,sub exclusive ',
                      4,'[4] Share 共享锁(S):阻止其他DML操作,share',
                      5,'[5] S/Row-X 共享行独占(SRX):阻止其他事务操作,share/sub exclusive ',
                      6,'[6] exclusive 独占(X):独立访问使用,exclusive ',
                      '['||L.LMode||'] Other Lock') LockMode,
       O.OWNER,
       O.OBJECT_NAME,
       O.OBJECT_TYPE,
       S.SID,
       S.SERIAL#,
       S.TERMINAL,
       S.MACHINE,
       S.PROGRAM,
       S.OSUSER,
       S.sql_address,
       S.sql_hash_value
  FROM V$SESSION S, V$LOCK L, DBA_OBJECTS O
WHERE L.SID = S.SID
   AND L.ID1 = O.OBJECT_ID(+)
   AND S.USERNAME IS NOT NULL
   AND owner='WCINSTALL'

4.查看谁锁了谁

SELECT s1.username || '@' || s1.machine || ' ( SID=' || s1.sid ||
       ' ) is blocking ' || s2.username || '@' || s2.machine || ' ( SID=' ||
       s2.sid || ' ) ' AS blocking_status
  FROM v$lock l1, v$session s1, v$lock l2, v$session s2
 WHERE s1.sid = l1.sid
   AND s2.sid = l2.sid
   AND l1.BLOCK = 1
   AND l2.request > 0
   AND l1.id1 = l2.id1
   AND l2.id2 = l2.id2;

5.查看锁信息综合(简化版)

SELECT A.OWNER 用户名,

A.OBJECT_NAME 被锁对象名,

C.SID,

C.SERIAL#,

C.STATUS,

D.ctime  "被锁时间(S)",

--B.XIDUSN 回滚段号,

--B.XIDSLOT 槽号,

--B.XIDSQN 序列号,

--B.SESSION_ID 锁表SESSION_ID,

--B.ORACLE_USERNAME 锁表Oracle用户名,

D.type 锁类型,

decode(D.type,'XR','NULL','RS','SS(Row-S)','CF','SS(Row-S)','TM','TABLE LOCK','PW','TABLE LOCK','TO','TABLE LOCK','TS',
'TABLE LOCK','RT','ROW LOCK','TX','ROW LOCK','MR','S(Share)',NULL) 锁定方式,

C.MACHINE,

--C.TERMINAL 机器名,

B.OS_USER_NAME 系统用户名,

--B.PROCESS 系统进程id,

DECODE(C.STATUS,'INACTIVE','不活动','ACTIVE','活动') 活动情况,

--C.SERVER,

C.PROGRAM 连接方式,

C.LOGON_TIME,

E.sql_text

--,'alter system kill session '''||C.SID||','||C.SERIAL#||''''

FROM ALL_OBJECTS A,

V$LOCKED_OBJECT B,

v$SESSION C,

v$lock D,

v$sql E

WHERE ( A.OBJECT_ID = B.OBJECT_ID )

AND (B.PROCESS = C.PROCESS )

AND C.sid = d.sid

AND B.LOCKED_MODE = D.LMODE

AND DECODE(C.sql_hash_value, 0, prev_hash_value, sql_hash_value) =E.hash_value 

ORDER BY 6 desc;

6.查看锁信息综合

SELECT A.OWNER 用户名,

A.OBJECT_NAME 被锁对象名,

C.SID,

C.SERIAL#,

C.STATUS,

D.ctime  被锁时间,

B.XIDUSN 回滚段号,

B.XIDSLOT 槽号,

B.XIDSQN 序列号,

B.SESSION_ID 被锁SESSION_ID,

B.ORACLE_USERNAME 被锁Oracle用户名,

D.type 锁类型,

decode(D.type,'XR','NULL','RS','SS(Row-S)','CF','SS(Row-S)','TM','TABLE LOCK','PW','TABLE LOCK','TO','TABLE LOCK','TS',
'TABLE LOCK','RT','ROW LOCK','TX','ROW LOCK','MR','S(Share)',NULL) 锁定方式,

C.MACHINE 用户组,

C.TERMINAL 机器名,

B.OS_USER_NAME 系统用户名,

B.PROCESS 系统进程id,

--DECODE(C.STATUS,'INACTIVE','不活动','ACTIVE','活动') 活动情况,

C.SERVER,

C.PROGRAM 连接方式,

C.LOGON_TIME,

E.sql_text

--,'alter system kill session '''||C.SID||','||C.SERIAL#||''''

FROM ALL_OBJECTS A,

V$LOCKED_OBJECT B,

v$SESSION C,

v$lock D,

v$sql E

WHERE ( A.OBJECT_ID = B.OBJECT_ID )

AND (B.PROCESS = C.PROCESS )

AND C.sid = d.sid

AND B.LOCKED_MODE = D.LMODE

AND DECODE(C.sql_hash_value, 0, prev_hash_value, sql_hash_value) =E.hash_value 

--ORDER BY 1,2;
ORDER BY 6;

查出阻塞链条

select * 
from (select a.inst_id, a.sid, a.serial#, 
a.sql_id, 
a.event, 
a.status, 
connect_by_isleaf as isleaf, 
sys_connect_by_path(a.SID||'@'||a.inst_id, ' <- ') tree, 
level as tree_level 
from gv$session a 
start with a.blocking_session is not null 
connect by (a.sid||'@'||a.inst_id) = prior (a.blocking_session||'@'||a.blocking_instance)) 
where isleaf = 1 
order by tree_level asc;

7.查看当前会话中引起行锁竞争的语句

select sw.event,
       sw.sid,
       sw.p1,
       sw.p2,
       sw.p3,
       s.ROW_WAIT_OBJ#,
       s.ROW_WAIT_FILE#,
       s.ROW_WAIT_BLOCK#,
       s.ROW_WAIT_ROW#,
       o.OWNER,
       o.OBJECT_NAME,
       o.OBJECT_ID,
       o.DATA_OBJECT_ID,
       o.OBJECT_TYPE,
       st.sql_id,
       st.sql_text
  from v$session_wait sw, v$session s, dba_objects o, v$sql st
 where sw.sid = s.sid
   and o.object_id = s.ROW_WAIT_OBJ#
   and (st.sql_id = s.sql_id or st.sql_id = s.prev_sql_id)
   and sw.event = 'enq: TX - row lock contention';

8.kill lock语句

ALTER SYSTEM KILL SESSION ’sid,serial#’; 
--例:
--ALTER SYSTEM KILL SESSION '2210,2769';

–查看被锁对象并生成 kill 语句

SELECT c.owner,
       c.object_name,
       c.object_type,
       b.sid,
       b.serial#,
       b.inst_id,
       b.status,
       b.osuser,
       b.machine,
       'alter system kill session ''' || b.sid || ',' || b.serial# || ',@' ||b.inst_id || ''';'
     --'alter system kill session ''' || b.sid || ',' || b.serial# || ',@' ||b.inst_id || ''';' RAC架构
  FROM gv$locked_object a, gv$session b, dba_objects c
 WHERE b.sid = a.session_id
   AND a.object_id = c.object_id
   and a.inst_id = b.inst_id;

SELECT 'alter system kill session ''' || SID || ',' || s.serial# || ',@' ||
       inst_id || ''';',
       sid,
       username,
       serial#,
       process,
       NVL(sql_id, 0),
       sql_address,
       blocking_session,
       wait_class,
       event,
       p1,
       p2,
       p3,
       seconds_in_wait
  FROM gv$session s
 WHERE blocking_session_status = 'VALID'
    OR sid IN (SELECT blocking_session
                 FROM gv$session
                WHERE blocking_session_status = 'VALID');

–查看会话阻塞并生成kill语句

SELECT vs.username,
       vs.osuser,
       vh.sid locking_sid,
       vs.status status,
       vs.module module,
       vs.program program_holding,
       jrh.job_name,
       vsw.username,
       vsw.osuser,
       vw.sid waiter_sid,
       vsw.program program_waiting,
       jrw.job_name,
       'alter system kill session ' || '''' || vh.sid || ',' || vs.serial# ||
       ''';' "Kill_Command"
  FROM v$lock                     vh,
       v$lock                     vw,
       v$session                  vs,
       v$session                  vsw,
       dba_scheduler_running_jobs jrh,
       dba_scheduler_running_jobs jrw
 WHERE (vh.id1, vh.id2) IN (SELECT id1, id2
                              FROM v$lock
                             WHERE request = 0
                            INTERSECT
                            SELECT id1, id2
                              FROM v$lock
                             WHERE lmode = 0)
   AND vh.id1 = vw.id1
   AND vh.id2 = vw.id2
   AND vh.request = 0
   AND vw.lmode = 0
   AND vh.sid = vs.sid
   AND vw.sid = vsw.sid
   AND vh.sid = jrh.session_id(+)
   AND vw.sid = jrw.session_id(+);

–查杀根锁sql(为了防止查错dba的会话,多了一个过滤sqlplus的进程的条件)

SELECT distinct 
'alter system kill session '''||A.sid||','||A.serial#||',@'||A.inst_id||''' immediate;' 
FROM GV$SESSION A,GV$SESSION B 
WHERE A.SID=B.FINAL_BLOCKING_SESSION 
AND A.USERNAME IS NOT NULL 
AND A.INST_ID=B.INST_ID 
AND A.AUDSID<>B.AUDSID 
--and a.program not like '%sqlplus%' and 
;

–生成 kill 掉大于300秒的会话语句

SELECT 'kill -9 ' || p.spid,
       s.username,
       'alter system kill session ''' || SID || ',' || s.serial# || ''';'
  FROM v$session s, v$process p
 WHERE s.paddr = p.addr(+)
   AND s.SID IN (select sid
                   from v$sql_monitor
                  where status = 'EXECUTING'
                    and elapsed_time / 1000000 > 300
                    and username in ('MEHMET', 'SALIH'));

9.查看执行时间较久的SQL

SELECT USERNAME,
       SID,
       OPNAME,
       ROUND(SOFAR * 100 / TOTALWORK, 0) || '%' AS PROGRESS,
       TIME_REMAINING,
       SQL_TEXT
  FROM V$SESSION_LONGOPS, V$SQL
 WHERE TIME_REMAINING <> 0
   AND SQL_ADDRESS = ADDRESS
   AND SQL_HASH_VALUE = HASH_VALUE;

9.查看历史阻塞会话和锁信息

select v.sql_text, v.sql_fulltext, sub.*
  from v$sql v,
       (select sample_time,
               s.sql_id sql_id,
               session_state,
               blocking_session,
               owner || '.' || object_name || ':' ||
               nvl(subobject_name, '-') obj_name,
               s.program,
               s.module,
               s.machine
          from dba_hist_active_sess_history s, dba_objects o
         where sample_time between
               to_date('27/02/2019 07:30:02', 'DD/MM/YYYY HH24:MI:SS') and
               to_date('28/02/2019 15:10:02', 'DD/MM/YYYY HH24:MI:SS')
           and event = 'enq: TX - row lock contention'
           and o.data_object_id = s.current_obj#
         order by 1 desc) sub
 where sub.sql_id = v.sql_id;

10.从历史会话中查看引起行锁竞争的语句

select ash.sample_time,
       ash.instance_number,
       ash.user_id,
       u.username,
       ash.session_id,
       ash.session_serial#,
       ash.current_obj#,
       o.owner,
       o.object_name,
       o.object_type,
       ash.sql_id,
       ash.sql_opname,
       ash.wait_class,
       ash.program,
       ash.module,
       ash.blocking_session_status,
       ash.blocking_session,
       ash.blocking_session_serial#,
       ash.blocking_inst_id,
       st.inst_id,
       st.sql_text
  from dba_hist_active_sess_history ash,
       dba_users                    u,
       dba_objects                  o,
       gv_$sql                      st
 where to_char(ash.sample_time, 'YYYY-MM-DD hh24:mi:ss') between  '2022-03-22 13:30:00' and '2022-03-22 15:30:00'
   and ash.time_waited > 0
   and ash.session_state = 'WAITING'
   and ash.user_id = u.user_id
   and ash.current_obj# = o.object_id
   and st.sql_id = ash.sql_id
   and ash.event = 'enq: TX - row lock contention';

11.查看RAC环境的会话阻塞

SELECT DISTINCT S1.USERNAME || '@' || S1.MACHINE || ' ( INST=' ||
                S1.INST_ID || ' SID=' || S1.SID || ' ) IS BLOCKING ' ||
                S2.USERNAME || '@' || S2.MACHINE || ' ( INST=' ||
                S1.INST_ID || ' SID=' || S2.SID || ' ) ' AS BLOCKING_STATUS
  FROM GV$LOCK L1, GV$SESSION S1, GV$LOCK L2, GV$SESSION S2
 WHERE S1.SID = L1.SID
   AND S2.SID = L2.SID
   AND S1.INST_ID = L1.INST_ID
   AND S2.INST_ID = L2.INST_ID
   AND L1.BLOCK > 0
   AND L2.REQUEST > 0
   AND L1.ID1 = L2.ID1
   AND L1.ID2 = L2.ID2;

–RAC环境的会话阻塞和对象信息

SELECT DISTINCT S1.USERNAME || '@' || S1.MACHINE || ' ( INST=' ||
                S1.INST_ID || ' SID=' || S1.SID || ' ) IS BLOCKING ' ||
                S2.USERNAME || '@' || S2.MACHINE || ' ( INST=' ||
                S1.INST_ID || ' SID=' || S2.SID || ' ) OBJ_ID:' || L1.ID1 ||
                ' OBJ_NAME:' || O.OBJECT_NAME AS BLOCKING_STATUS
  FROM GV$LOCK L1, GV$SESSION S1, GV$LOCK L2, GV$SESSION S2, DBA_OBJECTS O
 WHERE S1.SID = L1.SID
   AND S2.SID = L2.SID
   AND S1.INST_ID = L1.INST_ID
   AND S2.INST_ID = L2.INST_ID
   AND L1.ID1 = OBJECT_ID
   AND L1.ID1 = O.OBJECT_ID
   AND L1.BLOCK > 0
   AND L2.REQUEST > 0
   AND L1.ID1 = L2.ID1
   AND L1.ID2 = L2.ID2;

–查看RAC环境的会话阻塞,针对某个具体的对象

SELECT DISTINCT S1.USERNAME || '@' || S1.MACHINE || ' ( INST=' ||
                S1.INST_ID || ' SID=' || S1.SID || ' ) IS BLOCKING ' ||
                S2.USERNAME || '@' || S2.MACHINE || ' ( INST=' ||
                S1.INST_ID || ' SID=' || S2.SID || ' ) OBJ_ID:' || L1.ID1 ||
                ' OBJ_NAME:' || O.OBJECT_NAME AS BLOCKING_STATUS
  FROM GV$LOCK L1, GV$SESSION S1, GV$LOCK L2, GV$SESSION S2, DBA_OBJECTS O
 WHERE S1.SID = L1.SID
   AND S2.SID = L2.SID
   AND S1.INST_ID = L1.INST_ID
   AND S2.INST_ID = L2.INST_ID
   AND L1.ID1 = OBJECT_ID
   AND L1.ID1 = O.OBJECT_ID
   AND L1.BLOCK > 0
   AND L2.REQUEST > 0
   AND L1.ID1 = L2.ID1
   AND L1.ID2 = L2.ID2
   AND object_id in (SELECT OBJECT_ID
                       FROM DBA_OBJECTS
                      WHERE OWNER = 'XXX'
                        AND OBJECT_NAME = 'XXX');

参考文章:
https://www.cnblogs.com/annez/p/15380150.html


相关文章:
Oracle 锁(lock)详解

一文搞懂Oracle 0 至 6 级锁(附案例详解)

Oracle未提交事务引起的锁

你可能感兴趣的:(Oracle,oracle,数据库)