欢迎投稿

今日深度:

Oracle 阻塞(blocking blocked),blocking

Oracle 阻塞(blocking blocked),blocking


   阻塞是DBA经常碰到的情形,尤其是不良的应用程序设计的阻塞将导致性能严重下降直至数据库崩溃。对DBA而言,有必要知道如何定位到当前系统有哪些阻塞,到底谁是阻塞者,谁是被阻塞者。本文对此给出了描述并做了相关演示。

 

1、阻塞及其类型
a、什么是阻塞
   一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking)。也就是说新的会话会被挂起,直到持有锁的会话放弃锁定的资源。大多数情况下,在一个交互式应用中被严重阻塞,即可表明应用逻辑有问题,这才是阻塞的根源。
b、阻塞得类型
   数据库中有5条常见的DML语句可能会阻塞,即:INSERT、UPDATE、DELETE、MERGE 和SELECT FOR UPDATE。

 

2、几种不同类型阻塞的处理办法
a、INSERT阻塞主要是由于有一个带主键的表,或者表上有惟一的约束,在两个会话试图用同样的值插入一行时引发阻塞。多表通过引用完整性约束相互链接时,在其依赖的父表正在创建或删除期间,对子表的插入可能会阻塞。对于该类情形建议使用序列来生成主键/惟一列值。
b、对于UPDATE、DELETE、MERGE 和SELECT FOR UPDATE阻塞,只要有任一session使用这些操作已经锁定行,其余的必须处于等待状态。直到当前锁定行上的锁(排他锁)释放。对于该类情形,建议尽可能快速提交事务,或采用批量SQL方式提交。
c、对于一个阻塞的SELECT FOR UPDATE,解决方案很简单:只需增加NOWAIT 子句,它就不会阻塞了。

 

3、演示阻塞

--更新表,注,提示符scott@CNMMBO表明用户为scott的session,用户名不同,session不同。
scott@CNMMBO> update emp set sal=sal*1.1 where empno=7788;

1 row updated.

scott@CNMMBO> @my_env

SPID                SID    SERIAL# USERNAME        PROGRAM
------------ ---------- ---------- --------------- ------------------------------------------------
11205              1073       4642 robin           oracle@SZDB (TNS V1-V3)

--另起两个session更新同样的行,这两个session都会处于等待,直到第一个session提交或回滚
leshami@CNMMBO> update scott.emp set sal=sal+100 where empno=7788;

goex_admin@CNMMBO> update scott.emp set sal=sal-50 where empno=7788;

--下面在第一个session 查询阻塞情况
scott@CNMMBO> @blocker 

BLOCK_MSG                                               BLOCK
-------------------------------------------------- ----------
pts/5 ('1073,4642') is blocking 1067,10438                  1
pts/5 ('1073,4642') is blocking 1065,4464                   1
--上面的结果表明session 1073,4642 阻塞了后面的2个
--即session 1073,4642是阻塞者,后面2个session是被阻塞者

--Author : Leshami
--Blog   : http://blog.csdn.net/leshami

--下面查询正在阻塞的session id,SQL语句以及被阻塞的时间
scott@CNMMBO> @blocking_session_detail.sql

'SID='||A.SID||'WAITCLASS='||A.WAIT_CLASS||'TIME='||A.SECONDS_IN_WAIT||CHR(10)||'QUERY='||B.SQL_TEXT
-------------------------------------------------------------------------------------------------------
sid=1067 Wait Class=Application Time=5995
 Query=update scott.emp set sal=sal+100 where empno=7788

sid=1065 Wait Class=Application Time=225
 Query=update scott.emp set sal=sal-50 where empno=7788

--下面的查询阻塞时锁的持有情况 
scott@CNMMBO> @request_lock_type

USERNAME                              SID TY LMODE       REQUEST            ID1        ID2
------------------------------ ---------- -- ----------- ----------- ---------- ----------
SCOTT                                1073 TX Exclusive   None            524319      27412
LESHAMI                              1067 TX None        Exclusive       524319      27412
GOEX_ADMIN                           1065 TX None        Exclusive       524319      27412
--可以看到LESHAMI,GOEX_ADMIN 2个用户都在请求524319/27412上的Exclusive锁,而此时已经被SCOTT加了Exclusive锁

--查询阻塞时锁的持有详细信息
scott@CNMMBO> @request_lock_detail

       SID USERNAME             OSUSER          TERMINAL                  OBJECT_NAME          TY Lock Mode   Req_Mode
---------- -------------------- --------------- ------------------------- -------------------- -- ----------- --------------------
      1065 GOEX_ADMIN           robin           pts/1                     EMP                  TM Row Excl
      1065 GOEX_ADMIN           robin           pts/1                     Trans-524319         TX --Waiting-- Exclusive
      1067 LESHAMI              robin           pts/0                     EMP                  TM Row Excl
      1067 LESHAMI              robin           pts/0                     Trans-524319         TX --Waiting-- Exclusive
      1073 SCOTT                robin           pts/5                     EMP                  TM Row Excl
      1073 SCOTT                robin           pts/5                     Trans-524319         TX Exclusive 

文中涉及到的相关脚本下载:http://download.csdn.net/detail/robinson_0612/7607033    

更多参考

DML Error Logging 特性 

PL/SQL --> 游标

PL/SQL --> 隐式游标(SQL%FOUND)

批量SQL之 FORALL 语句

批量SQL之 BULK COLLECT 子句

PL/SQL 集合的初始化与赋值

PL/SQL 联合数组与嵌套表
PL/SQL 变长数组
PL/SQL --> PL/SQL记录

SQL tuning 步骤

高效SQL语句必杀技

父游标、子游标及共享游标

绑定变量及其优缺点

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划


如何查看oracle数据库中哪些session异常阻塞了系统?

时候需要找出造成异常阻塞session并清除oracle session通常具有三特征:(1)session能阻塞多session;(2)session多被session阻塞;(3)session阻塞关系会形成环路(环路即死锁oracle能自动解除)因此session阻塞关系棵树进而DB系统所有sessionBLOCK阻塞关系由若干session阻塞关系树构成森林而异常session定会故障爆发时成根(root)因此找寻异常锁表session过程找出异常root般认异常root有两特征:(1)block树规模过大阻塞树规模即被root层层阻塞session总数;(2)阻塞平均等待时间过长查找异常session方法:OEM—> performance—> Blocking Sessions查找异常session方法二:select r.root_sid, s.serial#,r.blocked_num, r.avg_wait_seconds,s.username,s.status,s.event,s.MACHINE,s.PROGRAM,s.sql_id,s.prev_sql_idfrom (select root_sid, avg(seconds_in_wait) as avg_wait_seconds,count(*) - 1 as blocked_numfrom (select CONNECT_BY_ROOT sid as root_sid, seconds_in_waitfrom v$sessionstart with blocking_session is nullconnect by prior sid = blocking_session)group by root_sidhaving count(*) > 1) r,v$session swhere r.root_sid = s.sidorder by r.blocked_num desc, r.avg_wait_seconds desc;该SQL语句即根据v$session字段blocking_session统计阻塞树根阻塞session计数及平均阻塞时间、并进行排序排名往往异常session

如何查看oracle数据库中哪些session异常阻塞了系统?

Oracle数据库运维过程有时会遇种异常情况由于错误操作或代码BUG造成session异常地持有锁释放并大量阻塞系统对时候需要找出造成异常阻塞session并清除
oracle session通常具有三特征:
(1)session能阻塞多session;
(2)session多被session阻塞;
(3)session阻塞关系会形成环路(环路即死锁oracle能自动解除)
因此session阻塞关系棵树进而DB系统所有sessionBLOCK阻塞关系由若干session阻塞关系树构成森林而异常session定会故障爆发时成根(root)因此找寻异常锁表session过程找出异常root
般认异常root有两特征:(1)block树规模过大阻塞树规模即被root层层阻塞session总数;(2)阻塞平均等待时间过长
查找异常session方法
OEM—> performance—> Blocking Sessions
查找异常session方法二:
select r.root_sid, s.serial#,
r.blocked_num, r.avg_wait_seconds,
s.username,s.status,s.event,s.MACHINE,
s.PROGRAM,s.sql_id,s.prev_sql_id
from (select root_sid, avg(seconds_in_wait) as avg_wait_seconds,
count(*) - 1 as blocked_num
from (select CONNECT_BY_ROOT sid as root_sid, seconds_in_wait
from v$session
start with blocking_session is null
connect by prior sid = blocking_session)
group by root_sid
having count(*) > 1) r,
v$session s
where r.root_sid = s.sid
order by r.blocked_num desc, r.avg_wait_seconds desc;
该SQL语句即根据v$session字段blocking_session统计阻塞树根阻塞session计数及平均阻塞时间、并进行排序排名往往异常session
另外需要注意持有锁时间长、或等待时间session都造成阻塞根源session

www.htsjk.Com true http://www.htsjk.com/shujukunews/1983.html NewsArticle Oracle 阻塞(blocking blocked),blocking 阻塞是DBA经常碰到的情形,尤其是不良的应用程序设计的阻塞将导致性能严重下降直至数据库崩溃。对DBA而言,有必要知道如何定位到当前系统有哪些阻...
评论暂时关闭