由于cursor leak导致的SQL Server内存问题

SQL Server 2000开始,如果SQL Server遇到了内存不足的问题,我们会在SQL Server的error log中看到相关的信息和对当前memory分配和使用情况的打印信息.

2009-05-06 16:20:22.38 spid215 BPool::Map: no remappable address found.

2009-05-06 16:20:22.46 spid241 BPool::Map: no remappable address found.

2009-05-06 16:20:22.50 spid8 BPool::Map: no remappable address found.

2009-05-06 16:20:22.52 spid242 Buffer Distribution: Stolen=190614 Free=196 Procedures=271

Inram=0 Dirty=104759 Kept=0

I/O=0, Latched=35, Other=664125

2009-05-06 16:20:22.52 spid242 Buffer Counts: Commited=960000 Target=960000 Hashed=768919

InternalReservation=529 ExternalReservation=1426 Min Free=256 Visible= 191224

2009-05-06 16:20:22.52 spid242 Procedure Cache: TotalProcs=67 TotalPages=271 InUsePages=197

2009-05-06 16:20:22.52 spid242 Dynamic Memory Manager: Stolen=190767 OS Reserved=2584

OS Committed=2542

OS In Use=2538

Query Plan=156155 Optimizer=0

General=15253

Utilities=401 Connection=4046

2009-05-06 16:20:22.52 spid242 Global Memory Objects: Resource=9815 Locks=16467

SQLCache=76 Replication=2

LockBytes=2 ServerGlobal=28

Xact=5011

2009-05-06 16:20:22.52 spid242 Query Memory Manager: Grants=11 Waiting=15 Maximum=1512 Available=0

[@more@]

当前这个例子中,遇到问题的SQL Server是32bit的SQL Server 2000.

Commited=960000 Target=960000 这里commited的和target都是960000个page,我们知道SQL Server的memory里面,一个page是8K。所以当前的buffer pool是7500MB。一个32bit的SQL Server 2000使用了7500MB内存,那么肯定是打开了AWE选项。commited表示当前已经使用的内存部分。

对于一个32bit的SQL Server来说,即使我们使用了AWE选项来扩展内存,依然还是有内存限制的。AWE扩展的部分,只能给data cache部分使用。即:用来存放table和index的数据页。

我们知道,一个数据库的内存部分,除了data 的cache之外,还有execution plan,statement,security context,lock ,cursor,optimizer,connection以及一些DLL和provider的内容。那么在32bit的SQL Server下,以上这些部分依然收到2GB内存的限制。

这就是说,即使我们给一个32bit的SQLServer无限制的增加内存,它还是可能遇到memory 不足的情况。

在这里,我们看到Hashed=768919,这个hashed部分指的就是data 和index的cache,这些数据使用hash链表的方式存放的。

接下来我们查看这个部分:

2009-05-06 16:20:22.52 spid242 Dynamic Memory Manager: Stolen=190767 OS Reserved=2584

OS Committed=2542

OS In Use=2538

Query Plan=156155 Optimizer=0

General=15253

Utilities=401 Connection=4046

这个stolen的部分,可以理解为不在AWE扩展中的内存,也就是需要受到2GB限制的内存部分。这里总得stolen的内存在1500MB左右。其中绝大部分被Query Plan消耗了。

Query Plan指的是存放SQL 语句的plan的缓存部分。为什么语句的plan会占用如此多的内存呢?

1.客户有非常多的ad-hoc的语句。导致不能重用已经的plan而要不断的生成新的plan。或者由于某些原因,导致本可以重用plan的语句没有办法重用plan,必须生成新的。

2.这些plan没有办法从内存中清除掉。

通过以下命令可以验证我们的猜测:

Dbcc memorystatus --显示目前SQL server的内存使用和分配状况

Dbcc freeproccache --用来手动清除内存里面的plan cache

Dbcc memorystatus

DBCC ACTIVECURSORS --用来显示当前有多少没有关闭的游标

在这个系统中,我们发现执行完”Dbcc freeproccache“之后SQL plan cache的部分没有减少。这个说明这些plan都是正在使用中的active状态。这种情况下,通常是因为应用程序中有很多没有关闭的游标。

果然,”DBCC ACTIVECURSORS“返回了1万多行。

至此,我们可以得出结论,由于应用程序中的cursor leak,导致很多open的cursor在数据库端,这些open的cursor所引用的sql plan是不能被清除也不能被重用的,这个就是memory问题的原因了。

如果应用程序是使用的JDBC的driver,SQL Server 2000 JDBC SP3 修正了一些由于provider本身导致的cursor leak。但是本文中遇到的问题确是由于应用程序本身没有关闭cursor导致的。所以在处理server side cursor还是要格外小心。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23623/viewspace-1026719/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23623/viewspace-1026719/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值