案例:Troubleshooting library cache lock when concurrent insert

本案例来自南区某客户,数据库版本为rac 11.2.0.4,同事反馈在短短1分钟左右出现大量的活动会话,等待事件为library cache lock,并伴随着row cache lock。之后没有做任何调整就恢复了正常。客户需要知道异常的原因。

由于异常时段只持续了短短1分钟,分析awr的价值就没有那么大了,这个时候应该仔细分析ash,还好客户及时备份了gv$active_session_history,这样就不用去分析dba_hist_active_sess_history了。

从ash中可以发现,从2022-05-17 04:14:56开始,出现大量library cache lock等待,期间伴随着row cache lock,直到2022-05-17 04:15:24,大概1分钟故障消失。

对于library cache lock,它是属于为了维护libary cache handle的一种enqueue等待,队列的特点基本都一样,X阻塞S,并且S也阻塞X。

  • p1:handle address
  • p2:lock address
  • p3:100*mode+namespace

p3是非常需要关注的,首先可以定位到namespace,缩小排查范围,其次还有lock的请求模式,也就是S(共享)和X(排他),其实还有一种lockmode N,N主要是为了标记session cursor缓存的,软软解析就依赖这个N lock了。对于session缓存的cursor,cursor指向的library cache handle会加上一个N lock,即使flush shared pool也不会被清除。

继续分析ash,找最早出现异常的sample_id去分析

blocking_session都是on cpu,针对library cache lock的P3分析如下:

  • namespace:TABLE/PROCEDURE
  • mode:X

对于namespace:TABLE/PROCEDURE的前面那部分就是obj#的十六进制。

  • obj#:0x8dfc6=581574

通过这个对象号去查询obj$,居然没有查到记录。由于分析时间已经过了故障点,可能被删除了?疑点1。。。

此外,IN_PARSE,IN_HARD_PARSE,IN_BIND,IN_SQL_EXECUTION,IS_SQLID_CURRENT是ash中我比较喜欢关注的地方,可以明确直到当前活动会话的执行的sql处于哪个阶段,并且ash中的sql_id是不是当前会话正在执行的sql_id。这里可以看到所有会话的这些信息都是一致的。

  • IN_PARSE:N
  • IN_HARD_PARSE:N
  • IN_BIND:N
  • IN_SQL_EXECUTION:Y
  • IS_SQLID_CURRENT:N

session正在执行sql阶段,但是sql_id并不是当前session正在执行的sql。sql_id通过查询v$sql可以找到是一个非常简单的insert into table values语句。那肯定正在执行的是该insert的递归sql,到底是啥?疑点。。。

我们知道library cache lock通常是解析阶段才会遇到的,一个正在执行阶段的sql,居然还在等待library cache lock,session_state也是waiting。并且lock hanlde的对象并不是sql_id语句中涉及的对象,而是一个不存在的对象。瞬时对象?一般瞬时对象oracle为了避免obj#冲突都会把瞬时对象的obj#弄得很大,明显不是这个问题。触发器?查看了相应对象并没有触发器。疑点。。。

经过下一个查询,我更迷惑了。

同样都是那个insert语句,library cache lock的对象不但不是sql涉及对象,而且还是不同的obj#,并且都不存在。

百思不得其解,晚上洗澡的时候来了灵感,突然想到了一种也是我认为唯一的一种可能性,并发insert的时候,假如需要分配extent,但是表空间除掉回收站之外的可用空间如果不足以分配的话,会触发回收回收站空间。那么涉及回收站的对象。这种情况完全符合之前所提的疑点。

通过查看recylcbin$,发现有回收站存在大量的对象,但这并不足以证明故障当时去回收了回收站空间。还好客户备份了归档,使用logminer可以找到那些不存在的obj#。并且时间也与故障时间吻合。例如library cache lock p3中的obj#=581574。所有不存在的对象都可以从logminer中delete recyclebin$里找到。