今天先总结一点,enqueue是一种保护共享资源的等待机制,enqueue内容在日常脚本设计和数据库管理中经常出现,也是我近期总结的重点,如有错误,还请各位看官给予批评指正!
对于oracle数据库lock的理解,lock一般总是由应用发起的对资源的争用
,在oracle中存在几个容易引起竞争的位置:1、log buffer 2、lib cache
3、buffer cache 4、磁盘user i/o。
对于数据库Enqueues事件,可以直接理解为locks即锁,在数据库中的waits可以大致分为以下几类
1、buffer cache 2、Disk i/o 3、Enqueue 4、Library cache 5、redo 6、SQL*Net
7、Undo
其中与latch比较起来,enqueue是最简单的,但是同时也是最棘手的,大量的队列等待
说明系统存在设计或应用瓶颈,需要处理,enqueue分类如下:
1、CI--Cross Instance 实例等待事件
2、TM--table modification 表ddl锁
3、TX-row lock contention 行竞争所
4、TX-allocate ITL entry 事物槽分配锁
5、TX-index contention 索引竞争锁
6、HW--high water 高水位等待
7、ST--space transaction 空间事务等待(比如等待空间分配等)
8、TS--Temporary space 临时空间事件
9、UL--user lock 用户锁(由用户加的锁,如lock table table_name
对于解决enqueue wait问题的解决,不经需要实时的监控信息,还需要ASH报告,
单纯的Statspack和AWR报告缺少队列相关的监控数据,难以判断处理。另外,目前
oracle提供的工具都无法单独提供等待场景出现时的blocking sql,需要综合去找
问题sql。
处理enqueue wait问题,有以下几个思路
1、statspack 报告,查看相关的等待信息
2、查看v$active_session_history视图,其blocking_session,blocking_session_status,blocking_session_serial#
能够帮助查找造成阻塞的session信息
在实时监控时可以联合查询v$lock、v$session、dba_waiters、
v$sqlarea、dba_blockers;
如下语句:
select c.SQL_TEXT, a.SID, a.ID1, a.ID2, a.LMODE, b.USERNAME, b.EVENT
from v$lock a, v$session b, v$sql c
where a.SID = b.SID
and b.SQL_ID = c.SQL_ID;
select c.SQL_TEXT, a.*, b.LAST_CALL_ET, b.USERNAME, b.EVENT
from dba_waiters a, v$session b, v$sql c
where a.waiting_session = b.SID
and b.sql_id = c.SQL_ID;
select c.SQL_TEXT, a.*, b.LAST_CALL_ET, b.USERNAME, b.EVENT
from dba_blockers a, v$session b, v$sql c
where a.holding_session = b.SID
and b.sql_id = c.SQL_ID;
另外oracle提供了RDBMS/ADMIN/utllockt.sql 工具可以查询出lock的详细内容
对于处理lock问题,需要弄清楚几点:
1、谁被阻塞
2、谁在制造阻塞
3、那些内容被阻塞,即目前争夺的资源是什么
4、为什么被阻塞,原因需要分析清楚,如是否索引创建有问题还是应用设计不合理,可否考虑表分区等方式
可以通过视图v$event_name查询队列等待事件种类
select * from v$event_name where name like '%enqueue%'