记一次library cache lock/library cache pin导致的函数编译hang住分析及处理过程
墨墨导读:业务在进行alter function my_function_name compile时,有两个函数编译无法通过,现象就是会hang住,这里分享处理的整个过程。
一、前言
二、问题排查
SQL> @block
no rows selected
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
---------- ---------- ----------
4994 0 0
SQL>alter function XXX compile;
SQL> select sid,seq#,event,wait_class from v$session_wait where sid=4994;
WAIT
SID SEQ# EVENT CLASS
---------- ---------- -------------------- ---------------
4994 41 library cache lock Concurrency
This event controls the concurrency between clients of the library cache. It acquires a lock on the object handle so that either:
One client can prevent other clients from accessing the same object.
The client can maintain a dependency for a long time (for example, so that no other client can change the object).
This lock is also obtained to locate an object in the library cache. Library cache lock will be obtained on database objects referenced during parsing or compiling of SQL or PL/SQL statements (table, view, procedure, function, package, package body, trigger, index, cluster, synonym). The lock will be released at the end of the parse or compilation. Cursors (SQL and PL/SQL areas), pipes and any other transient objects do not use this lock. Library cache lock is not deadlock sensitive and the operation is synchronous.
library cache pin/lock都会有三种模式:
NULL
SHARE
EXCLUSIVE
当修改一个数据库对象的时候,会话会获得一个Exclusive模式的lock/pin;
所有的DDL操作(包括对过程、函数、视图等编译)都会对访问对象请求exclusive模式的lock和pin;
因此,我们可以进一步查看,这个会话是否有其他会话阻塞:
这里可以通过多种方式来查看:
方法一:查看是否有其他会话访问这个函数:
select sid,owner,object,type from v$access where object='&function_name';
SQL> select sid,seq#,event,wait_class from v$session_wait where sid=4994; WAIT SID SEQ# BLOCKING_SESSIO EVENT CLASS---------- ---------- --------------- -------------------- --------------- 4994 41 368 library cache lock Concurrency
我们通过v$session也可以找到这个会话的sql_id,并查看该sql_id的sql_text:
select sql_id from v$session where sid=368;
=========================================================
71bwdwbbwsrx5
select sql_text from v$sql where sql_id='71bwdwbbwsrx5';
=========================================================
begin
-- Call the procedure
p_test_XXXXk(v_anid =>:v_anid);
end;
SELECT DBMS_METADATA.GET_DDL('PROCEDURE','P_TEST_FN_CHECK_XXXX','CHENGDU') FROM DUAL;================================================================================================ CREATE OR REPLACE PROCEDURE "RES_CL"."P_TEST_XXXX" (v_anid in varchar2) as v_result varchar2(100);begin v_result := chengdu.XXXXX(v_anid);end;
三、问题根源
1)session 368,调用了P_TEST_FN_CHECK_XXXX过程,而P_TEST_FN_CHECK_XXXX过程则会访问XXXX函数;此时,数据库在XXXX函数上获取了share的library cache的lock。
2)当新的session 4994,对函数XXXX进行编译的时候,则会尝试获取EXCLUSIVE的lock。
3)而share的lock会阻塞exclusive的lock。因此,session 4994的compile操作被阻塞住,无法正常执行。而在5分钟后,则会产生ORA-4021的错误,超时中断。
四、问题解决
五、总结
王鑫,近7年数据库服务经验,目前就职于云和恩墨西区交付团队,擅长Oracle、PostgreSQL数据库的迁移运维等工作,具有11g OCP、11g OCM、PGCA、PGCE等数据库认证。
先后为国家电网信息通信公司、成都人社局、四川电信进行Oracle、PostgreSQL、主机等驻场运维服务,参与成飞、甘肃电信、四川国土资源厅、成都房管局等大型oracle数据迁移项目。
墨天轮原文链接:https://www.modb.pro/db/40299(复制到浏览器中打开或者点击“阅读原文”立即查看)
赞 (0)