关于等待多长时间会引发ORA-04021: timeout occurred while waiting to lock object错误的猜测

本文详细探讨了Oracle数据库中遇到的等待超时问题,包括超时原因、实验环境设置、具体操作步骤以及如何通过SQL查询分析锁定对象的持有者和等待者,最后推测超时计数是否在阻塞关系变化时清零。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文的实验环境为:

[oracle@rhel63single ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Wed Jun 10 07:18:11 2015

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

 

--- session 71

SQL> set timing on
SQL>  alter procedure lc0019999.dummy11gR2 compile;
 alter procedure lc0019999.dummy11gR2 compile
*
ERROR at line 1:
ORA-04021: timeout occurred while waiting to lock object


Elapsed: 00:15:00.09
SQL> show parameter lock

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_block_buffers                     integer     0
db_block_checking                    string      FALSE
db_block_checksum                    string      TYPICAL
db_block_size                        integer     8192
db_file_multiblock_read_count        integer     128
ddl_lock_timeout                     integer     0
distributed_lock_timeout             integer     60
dml_locks                            integer     1088
lock_name_space                      string
lock_sga                             boolean     FALSE
SQL> select * from v$mystat where rownum<2;  

       SID STATISTIC#      VALUE
---------- ---------- ----------
        71          0          0

Elapsed: 00:00:00.02
SQL> 


 

从上面可以看出,等待15分钟后,由于timeout而失败,不过这个15分钟我没有找到对应的数据库初始化参数。


而在另外的一个实验中,在22分钟之后,才报出的ORA-04021: timeout occurred while waiting to lock object。见如下的实验。


--如下脚本来自:How to Analyze Library Cache Timeout with Associated: ORA-04021 'timeout occurred while waiting to lock object %s%s%s%s%s.' Errors (文档 ID 1486712.1)
--若是lock or pin的 session比较多,如下脚本不太容易看出来哪个是持有者(即:阻塞者)

SQL> select /*+ ordered */ w1.sid  waiting_session,
  2           h1.sid  holding_session,
  3           w.kgllktype lock_or_pin,
  4           w.kgllkhdl address,
  5           decode(h.kgllkmod,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
  6              'Unknown') mode_held,
  7           decode(w.kgllkreq,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
  8            'Unknown') mode_requested
  9     from dba_kgllock w, dba_kgllock h, v$session w1, v$session h1
 10    where
 11     (((h.kgllkmod != 0) and (h.kgllkmod != 1)
 12        and ((h.kgllkreq = 0) or (h.kgllkreq = 1)))
 13      and
 14        (((w.kgllkmod = 0) or (w.kgllkmod= 1))
 15        and ((w.kgllkreq != 0) and (w.kgllkreq != 1))))
 16     and  w.kgllktype      =  h.kgllktype
 17     and  w.kgllkhdl =  h.kgllkhdl
 18     and  w.kgllkuse     =   w1.saddr
 19     and  h.kgllkuse     =   h1.saddr
 20   /

WAITING_SESSION HOLDING_SESSION LOCK ADDRESS          MODE_HELD MODE_REQU
--------------- --------------- ---- ---------------- --------- ---------
            198              71 Lock 00000000976AE938 Exclusive Exclusive
             14              71 Lock 00000000976AE938 Exclusive Exclusive
             71             136 Pin  00000000976AE938 Share     Exclusive

SQL> /---->此时sid为71的(见本文的最上边)session由于ORA-04021而失败,然后重新执行查询后,构成如下的阻塞者和持有者关系:198变成了持有者。

WAITING_SESSION HOLDING_SESSION LOCK ADDRESS          MODE_HELD MODE_REQU
--------------- --------------- ---- ---------------- --------- ---------
            198             136 Pin  00000000976AE938 Share     Exclusive
             14             198 Lock 00000000976AE938 Exclusive Exclusive



---另外一个session 198

SQL> select * from v$mystat where rownum<2;

       SID STATISTIC#      VALUE
---------- ---------- ----------
       198          0          0

Elapsed: 00:00:00.00
SQL> alter procedure lc0019999.dummy11gR2 compile;
alter procedure lc0019999.dummy11gR2 compile
*
ERROR at line 1:
ORA-04021: timeout occurred while waiting to lock object


Elapsed: 00:22:28.64 ----->请注意,消耗了22分钟之后,才报出ORA-04021
SQL>


 

因此,我猜测,session 198由等待者变为持有者的时候,Library Cache Timeout 的时间计数会清零。

 

<think>好的,我现在需要解决用户遇到的Oracle数据库登录问题,具体是ORA-04021超时等待锁定对象和ORA-01017无效用户名或密码的错误。首先,我应该分别分析这两个错误,看看它们各自可能的原因,然后再结合起来考虑用户的情况。 首先处理ORA-04021错误。根据用户提供的引用资料,这个错误通常发生在等待对象锁超时的时候。引用[1]提到在编译存储过程时可能出现这个问题,引用[2]和[3]也提到类似的情况,可能是由于某个会话正在锁定对象,导致其他会话无法访问。用户可能需要检查是否有长时间运行的事务或者未提交的DDL操作,比如编译存储过程、函数等。根据引用[4],可以通过查询v$db_object_cache视图来查看被锁定的对象和持有锁的会话。而引用[5]建议杀死引起锁定的会话,这可能是一个解决方法。 接下来处理ORA-01017错误。这个错误通常是因为用户名或密码不正确,或者是数据库的大小写敏感设置问题。比如,如果用户密码包含特殊字符或者数据库使用区分大小写的密码,而用户在连接时没有正确输入,就会导致这个错误。需要确认用户输入的凭据是否正确,尤其是密码部分,可能需要用双引号括起来或者转义特殊字符。 现在,用户同时遇到这两个错误,可能的情况是:用户尝试登录时,可能因为多次尝试错误的密码导致账户被锁定(虽然ORA-01017通常不是锁定账户的错误,但需要确认),或者是在登录过程中,数据库正在处理某些对象,导致锁定超时。但这两个错误同时出现的情况比较少见,可能需要分步骤处理。 可能的解决步骤是: 1. 首先解决ORA-01017错误,确保用户名和密码正确。可以尝试使用SQL*Plus或者其他客户端工具,用相同的凭据登录,检查是否输入错误,尤其是密码的大小写和特殊字符。可能需要重置密码。 2. 如果ORA-01017解决后,再处理ORA-04021错误。这时候需要检查数据库中的锁情况,找出持有锁的会话并终止,或者等待其释放。可以通过查询v$session和v$locked_object等视图,找到相关的会话ID,然后使用ALTER SYSTEM KILL SESSION命令终止会话。 需要注意这两个错误是否有相关性。比如,用户可能在多次登录失败后,触发了一些内部机制导致对象被锁定,但更可能的是这两个错误是独立发生的。需要分步骤处理。 另外,引用[3]提到重启数据库可能解决锁定问题,但这是最后的手段,因为会影响其他用户。应该先尝试找到并终止相关会话。 总结处理步骤: 对于ORA-01017: - 确认用户名和密码正确,注意大小写和特殊字符。 - 检查数据库是否区分大小写,可能需要用双引号括起用户名或密码。 - 尝试重置用户密码。 对于ORA-04021- 查询当前锁定的对象和会话,找到阻塞的会话并终止。 - 避免在高峰时段执行DDL操作,检查是否有未提交的事务。 - 如果无法找到会话,考虑重启数据库实例。 此外,用户可能需要同时处理这两个错误,比如在解决登录问题后,再处理锁定问题,或者两者同时处理,比如在正确的凭据下登录后,执行查询和终止会话的操作。 需要确保用户有足够的权限执行这些操作,比如SYSDBA权限才能终止会话或重启数据库。</think>### 分步解决 Oracle ORA-04021ORA-01017 错误 #### **一、解决 ORA-01017 "无效用户名/密码"** 1. **验证用户名和密码** - 检查输入的用户名和密码是否与数据库中的定义完全一致。注意: - Oracle 12c 及以上版本默认密码区分大小写[^1]。 - 若密码包含特殊字符(如`@`、`$`),需用双引号包裹,例如: ```sql CONNECT "user"@"password_with_$ymbol" ``` - 使用 SQL*Plus 或工具(如 SQL Developer)直接测试连接。 2. **重置用户密码** 以管理员身份登录后执行: ```sql ALTER USER <用户名> IDENTIFIED BY <新密码>; ``` 3. **检查用户状态** 确保用户未被锁定或过期: ```sql SELECT username, account_status FROM dba_users WHERE username = '<用户名>'; ``` 若状态为`LOCKED`,使用`ALTER USER <用户名> ACCOUNT UNLOCK;`解锁。 --- #### **二、解决 ORA-04021 "等待对象锁超时"** 1. **定位锁定对象和会话** 执行以下查询找到持有锁的会话: ```sql SELECT s.sid, s.serial#, s.username, o.owner, o.object_name, o.object_type FROM v$locked_object l JOIN dba_objects o ON l.object_id = o.object_id JOIN v$session s ON l.session_id = s.sid WHERE o.owner = '<对象所属用户>'; ``` 2. **终止阻塞会话** 使用查询结果中的`sid`和`serial#`终止会话: ```sql ALTER SYSTEM KILL SESSION '<sid>,<serial#>'; ``` 若会话无法终止,尝试在操作系统层面结束进程(需 DBA 权限)[^5]。 3. **重启数据库(最后手段)** 若无法定位问题,重启数据库实例: ```sql SHUTDOWN IMMEDIATE; STARTUP; ``` --- #### **三、关联性分析与预防** - **场景关联**:频繁登录失败可能导致会话堆积,间接触发资源争用。建议先解决 ORA-01017,再处理 ORA-04021- **预防措施**: - 避免在业务高峰期编译存储过程或执行 DDL 操作[^1]。 - 定期检查长时间未提交的事务。 - 使用 `DBMS_LOCK.SLEEP` 在重试逻辑中添加延迟。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值