故障定义 一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking)。也就是说新的会话会被挂起,直到持有锁的会话放弃锁定的资源。大多数情况下,在一个交互式应用中被严重阻塞,即可表明应用逻辑有问题,这才是阻塞的根源。数据库中有5条常见的DML语句可能会阻塞,即:INSERT、UPDATE、DELETE、MERGE 和SELECT FOR UPDATE。 预判指标 1. 唯一性约束引起的阻塞: 该阻塞主要是由于有一个带主键的表,或者表上有惟一的约束,在两个会话试图用同样的值插入一行时引发阻塞。多表通过引用完整性约束相互链接时,在其依赖的父表正在创建或删除期间,对子表的插入可能会阻塞。 2. select for update: 对于UPDATE、DELETE、MERGE 和SELECT FOR UPDATE阻塞,只要有任一session使用这些操作已经锁定行,其余的必须处于等待状态。直到当前锁定行上的锁(排他锁)释放。 3. 外键和索引: l 主表有频繁修改操作。 l 主表有频繁删除操作。 l 主表和从表经常做关联查询。 主表会在从表创建锁定,以保证主表修改的数据不会导致从表的数据引用上出现问题。 如果主表经常做修改和删除操作,或每次操作的记录很多,那么从表就要被锁定很长时间,影响其他用户的正常操作。 预判处理 1、 大多数情况下,在一个交互式应用中被严重阻塞,即可表明应用逻辑有问题, 2、 对于该类情形,建议尽可能快速提交事务,或采用批量SQL方式提交。SELECT FOR UPDATE阻塞现象只需要加nowait; 3、 如果有主外键关系,可以考虑是否有必要给外键字段创建索引。 紧急处理方案 查询出造成数据库堵塞的sql语句及 sid,serial#。 select g.Inst_id,g.sid,g.serial#,g.event,g.username, g.sql_id from gv$session g,v$sql s where g.Wait_class <> 'Idle' and g.sql_hash_value=s.HASH_VALUE and g.event like '%T%'; select blocking_session,sid,serial#,wait_class,seconds_in_wait from v$session where blocking_session is not NULL and sid in(1056,1058); 2. alter system kill session 'SID,SERIAL#';