错误解析关于ORA-4025错误

Posted SQLplusDB

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了错误解析关于ORA-4025错误相关的知识,希望对你有一定的参考价值。

概述

在使用Oracle数据库时,遇到过ORA-4025错误,导致程序使用时发生错误。
ORA-4025错误虽然不是很常见的错误,却对我们理解数据库有一定的意义。

首先,让我们看一下这个错误的一般定义:

$ oerr ora 4025
04025, 00000, "maximum allowed library object lock allocated for %s%s%s%s%s"
// *Cause: Too many active locks for the object has been allocated. This error
//         can be a result of too many cursors kept open per session.
// *Action: Close cursors, reduce session_cached_cursors value.

根据上面的描述,我们知道ORA-4025错误,通常可能由于打开的游标太多,导致某个库缓存对象上,加载的active locks 太多,因为library object lock的分配数量达到了上限时发生错误。
一般可以通过关闭游标或者 减少session_cached_cursors的值缓解这个问题。

以下是针对该错误描述的一些疑问:

1.Active lock是什么?什么时候会导致Active lock增多?
2.为什么减少参数session_cached_cursors的设定值能够缓解这个问题?

关于Active lock的增加原因

通常来讲,Active lock是Oracle数据库针对游标等库缓存对象(library cache object)分配的锁。
一般情况下对同一个对象,同时利用数增加时,Active lock数也会增加。

例如:
每一个打开的游标都会持有一个Active lock;有多个会话都同时利用某个游标(Cursor)时,打开的游标(open cursor)会增加,相应地Active lock也会增加。

下面我们看一个简单的说明Active lock增加的例子:

1.首先,我们在一个Session1中,执行某条SQL文:

--会话1
SQL> conn scott/tiger
Connected.
SQL> select count(*) from emp;

  COUNT(*)
----------
        14

然后,取一下System state dump.

SQL> conn /as sysdba
Connected.
SQL> alter session set tracefile_identifier='1session';

Session altered.

SQL> alter session set events 'immediate trace name systemstate level 266';

Session altered.

我们查看生成的System state dump关于这个游标相关的信息:

  LibraryObjectLock:  Address=0x8932bf98 Handle=0x891f6e58 Mode=N CanBeBrokenCount=1 Incarnation=1 ExecutionCount=1         

    User=0x9148c980 Session=0x9148c980 ReferenceCount=1 Flags=CNB/[0001] SavepointNum=579c0218 
  LibraryHandle:  Address=0x891f6e58 Hash=88cd1004 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD 
    ObjectName:  Name=select count(*) from emp ★★★库缓存对象
      FullHashValue=890202cf4a2f38d1f2a77f1688cd1004 Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=2295140356 OwnerIdn=83 
    Statistics:  InvalidationCount=0 ExecutionCount=1 LoadCount=2 ActiveLocks=1 TotalLockCount=1 TotalPinCount=1 ★★★★ActiveLocks
    Counters:  BrokenCount=1 RevocablePointer=1 KeepDependency=1 Version=0 BucketInUse=0 HandleInUse=0 HandleReferenceCount=0 
    Concurrency:  DependencyMutex=0x891f6f08(0, 1, 0, 0) Mutex=0x891f6f98(0, 20, 0, 0) 
    Flags=RON/PIN/TIM/PN0/DBN/[10012841] 
    WaitersLists:  
      Lock=0x891f6ee8[0x891f6ee8,0x891f6ee8] 
      Pin=0x891f6ec8[0x891f6ec8,0x891f6ec8] 
      LoadLock=0x891f6f40[0x891f6f40,0x891f6f40] 
    Timestamp:  Current=07-30-2016 10:25:44 
    HandleReference:  Address=0x891f7020 Handle=(nil) Flags=[00] 
    LibraryObject:  Address=0x875fe040 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000] 
      ChildTable:  size='16' 
        Child:  id='0' Table=0x875feef0 Reference=0x875fe930 Handle=0x8903f8a0 
    NamespaceDump:  
      Parent Cursor:  sql_id=g59vz2u4cu404 parent=0x875fe0e0 maxchild=1 plk=y ppn=n         

我们可以看到此时,对于【ObjectName: Name=select count(*) from emp 】这个对象的Active lock为1

Statistics:  InvalidationCount=0 ExecutionCount=1 LoadCount=2 ActiveLocks=1★ 

2.我们接着在其他的会话中执行相同的SQL。

SQL> conn scott/tiger
Connected.
SQL> select count(*) from emp;

  COUNT(*)
----------
        14

并再次取得System state dump.

SQL> conn /as sysdba
Connected.
SQL> alter session set tracefile_identifier='2session';

Session altered.

SQL> alter session set events 'immediate trace name systemstate level 266';

Session altered.

我们查看生成的System state dump关于这个游标相关的信息:

  LibraryObjectLock:  Address=0x8932bf98 Handle=0x891f6e58 Mode=N CanBeBrokenCount=1 Incarnation=1 ExecutionCount=1         

    User=0x9148c980 Session=0x9148c980 ReferenceCount=1 Flags=CNB/[0001] SavepointNum=579c0218 
  LibraryHandle:  Address=0x891f6e58 Hash=88cd1004 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD 
    ObjectName:  Name=select count(*) from emp ★★★★
      FullHashValue=890202cf4a2f38d1f2a77f1688cd1004 Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=2295140356 OwnerIdn=83 
    Statistics:  InvalidationCount=0 ExecutionCount=2 LoadCount=2 ActiveLocks=2 TotalLockCount=2 TotalPinCount=1 ★★★★
    Counters:  BrokenCount=1 RevocablePointer=1 KeepDependency=1 Version=0 BucketInUse=1 HandleInUse=1 HandleReferenceCount=0 
    Concurrency:  DependencyMutex=0x891f6f08(0, 1, 0, 0) Mutex=0x891f6f98(0, 24, 0, 0) 
    Flags=RON/PIN/TIM/PN0/DBN/[10012841] 
    WaitersLists:  
      Lock=0x891f6ee8[0x891f6ee8,0x891f6ee8] 
      Pin=0x891f6ec8[0x891f6ec8,0x891f6ec8] 
      LoadLock=0x891f6f40[0x891f6f40,0x891f6f40] 
    Timestamp:  Current=07-30-2016 10:25:44 
    HandleReference:  Address=0x891f7020 Handle=(nil) Flags=[00] 
    LibraryObject:  Address=0x875fe040 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000] 
      ChildTable:  size='16' 
        Child:  id='0' Table=0x875feef0 Reference=0x875fe930 Handle=0x8903f8a0 
    NamespaceDump:  
      Parent Cursor:  sql_id=g59vz2u4cu404 parent=0x875fe0e0 maxchild=1 plk=y ppn=n         

...

  LibraryObjectLock:  Address=0x91eb8338 Handle=0x891f6e58 Mode=N CanBeBrokenCount=1 Incarnation=1 ExecutionCount=1         

    User=0x91aad100 Session=0x91aad100 ReferenceCount=1 Flags=CNB/[0001] SavepointNum=579c041e 
  LibraryHandle:  Address=0x891f6e58 Hash=88cd1004 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD 
    ObjectName:  Name=select count(*) from emp ★★★★
      FullHashValue=890202cf4a2f38d1f2a77f1688cd1004 Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=2295140356 OwnerIdn=83 
    Statistics:  InvalidationCount=0 ExecutionCount=2 LoadCount=2 ActiveLocks=2 TotalLockCount=2 TotalPinCount=1 ★★★★
    Counters:  BrokenCount=1 RevocablePointer=1 KeepDependency=1 Version=0 BucketInUse=1 HandleInUse=1 HandleReferenceCount=0 
    Concurrency:  DependencyMutex=0x891f6f08(0, 1, 0, 0) Mutex=0x891f6f98(0, 24, 0, 0) 
    Flags=RON/PIN/TIM/PN0/DBN/[10012841] 
    WaitersLists:  
      Lock=0x891f6ee8[0x891f6ee8,0x891f6ee8] 
      Pin=0x891f6ec8[0x891f6ec8,0x891f6ec8] 
      LoadLock=0x891f6f40[0x891f6f40,0x891f6f40] 
    Timestamp:  Current=07-30-2016 10:25:44 
    HandleReference:  Address=0x891f7020 Handle=(nil) Flags=[00] 
    LibraryObject:  Address=0x875fe040 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000] 
      ChildTable:  size='16' 
        Child:  id='0' Table=0x875feef0 Reference=0x875fe930 Handle=0x8903f8a0 
    NamespaceDump:  
      Parent Cursor:  sql_id=g59vz2u4cu404 parent=0x875fe0e0 maxchild=1 plk=y ppn=n         

我们可以看到此时,对于【ObjectName: Name=select count(*) from emp 】这个对象的Active lock为2
由于被不同的会话持有相同的游标对象,所以Active lock增加了。

Statistics:  InvalidationCount=0 ExecutionCount=2 LoadCount=2 ActiveLocks=2 ★ 

另外,除了上面正常原因(如不同会话持有,不同子游标等)的影响以外,根据过去的经验,由于以下的原因,也可能导致Active lock的异常增加:

・数据库的Bug影响
・应用程序的问题,如应用程序中不断地打开游标却从来不进行游标关闭清理。

关于Active lock的上限

Active lock的上限通常为65536个。

session_cached_cursors作为解决方法的原因

为什么减少参数session_cached_cursors的设定值能够缓解这个问题?

首先,对于每一个打开的游标都会对相应的对象上持有一个Active lock;

参数SESSION_CACHED_CURSORS用来控制在每个会话中能够缓存的游标个数。

当SQL执行时,在客户端的内存中会保持的游标信息会在游标关闭时被清理。但是在Oracle中,通过SESSION_CACHED_CURSORS参数能够保存一定数量的游标信息不被关闭和清理。
因此,当减少参数session_cached_cursors的设定值时,能够使每个会话的客户端中保持的游标数减少,从而在某种程度上,降低了同一个游标的打开会话个数。
因此,减少参数session_cached_cursors的设定值能够缓解这个问题,减少ORA-04025错误的发生。

版权声明:本文为博主原创文章,转载必须注明出处,本人保留一切相关权力!http://blog.csdn.net/lukeunique

欢迎关注微信订阅号:TeacherWhat

以上是关于错误解析关于ORA-4025错误的主要内容,如果未能解决你的问题,请参考以下文章

Java如何设定二维数组的上限?

使用成员初始值设定项时 gcc 中可能存在的错误

这个深奥的泛型错误是编译器错误还是新限制? (推断类型不符合上限)

一道关于JavaScript解析器错误的面试题

一道关于JavaScript解析器错误的面试题

Python 幂律符合使用 ODR 的数据中的上限和不对称错误