Toad Oracle 10.5编译出现ORA-04021锁等待超时问题如何处理
[Error] ORA-04021 (0: 0): ORA-04021: timeout occurred while waiting to lock object ..(procedure name )
问题产生原因
- 目标对象被其他会话持有共享锁:编译存储过程属于DDL操作,需要获取对象的排他锁,如果该存储过程正在被业务会话调用、有未关闭的长事务持有锁、定时Job正在运行该过程,都会导致排他锁请求等待超时
- 数据库DDL锁等待阈值配置过低:
ddl_lock_timeout参数默认值为0,即无等待直接报错,若锁释放速度稍慢就会触发超时 - 数据库资源负载过高:近期CPU、IO、内存资源使用率达到瓶颈,会导致锁释放、调度逻辑变慢,延长锁等待时间触发超时
- 对象依赖链存在锁占用:待编译存储过程依赖的表、视图、其他存储过程被其他会话锁定,编译时需要连带获取依赖对象的锁,间接导致等待超时
- 本地Toad会话自身持有锁:Toad当前会话存在未提交的DML操作、之前调试该存储过程未正常终止会话,都会导致自身持有该对象的共享锁,编译时无法拿到排他锁
排查解决方法
- 第一步查询持有目标对象锁的会话,执行如下SQL:
SELECT s.sid, s.serial#, s.username, s.program, s.machine, l.mode_held, l.mode_requested FROM dba_ddl_locks l JOIN v$session s ON l.session_id = s.sid WHERE l.name = '替换为你的存储过程名称' AND l.owner = '替换为存储过程所属的Schema名';
如果查询到非核心业务的闲置会话,可以执行ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;释放锁后重新编译。如果是RAC部署的数据库,需要将视图替换为gv$session和gv$ddl_locks查询所有节点的会话。
- 临时调整当前会话的DDL锁等待时长,执行语句:
ALTER SESSION SET ddl_lock_timeout = 180;,将等待阈值调整为3分钟后再尝试编译,避免锁释放慢导致的误超时。 - 检查Toad本地会话状态:提交或回滚当前会话中未完成的事务,关闭所有调试窗口后重新发起编译请求,排除自身会话持有锁的问题。
- 排查依赖对象锁占用,执行如下SQL查询所有依赖对象:
SELECT name, type, referenced_name, referenced_type FROM dba_dependencies WHERE name = '替换为你的存储过程名称' AND owner = '替换为存储过程所属的Schema名';
根据返回的依赖对象列表,逐一检查是否有对象被其他会话持有锁,处理占用会话后再编译。
- 检查数据库整体负载,通过
v$session、v$sysstat视图确认是否存在高资源占用的长事务,优先结束异常高负载会话释放系统资源后再尝试编译。
内容的提问来源于stack exchange,提问作者Anouer Kassaa
相关产品推荐
相关产品推荐

