透过现象看现象(SQL501N错误处理)
来源:互联网 发布:超星雕刻机怎么编程 编辑:程序博客网 时间:2024/06/05 07:14
某日一直运行比较正常的报表系统,突然报存储过程执行失败,查看DB2 错误返回码为sql501n,查看此错误原因如下:
[db2inst1@limt ~]$ db2 ? sql501n
SQL0501N The cursor specified in a FETCH statement or CLOSE statement
is not open or a cursor variable in a cursor scalar function
reference is not open.
Explanation:
The program attempted to do one of:
* FETCH using a cursor at a time when the specified cursor was not
open.
* CLOSE a cursor at a time when the specified cursor was not open.
* Reference a cursor variable in an OPEN statement and the cursor
variable is not open.
* Reference a cursor scalar function, such as CURSOR_ROWCOUNT function,
and the cursor variable is not open.
1 存储过程结构比较清晰,代码比较简单,在存储过程中调用了另一个存储过程
2 在存储过程中打开了一个游标,并且在代码后面也CLOSE了游标,在FETCH阶段也没有提前CLOSE游标
3 在嵌套的存储过程中也打开了游标,并且合理的关闭了游标
4 在嵌套的存储过程中也没有COMMIT操作(任何一个commit操作会导致所有的游标被关闭)
从代码上看不出来问题,那么回到系统整体上来分析:
1 此存储过程每天执行一次,以前从来没失败过
2 目前也不是每天都失败,偶尔也有成功的时候
3 每次失败的时候,在重新执行一次必然成功
4 此数据库前几天刚从V9.5.0.5升级到V9.5.0.10(V9.5.0.5 在linux系统上有内存泄露,导致SWAP空间被耗尽)
从上面两方面分析可以基本确定两点:
1 应该不是代码问题,如果是游标使用不当,那么为什么第二次调用就会成功
2 应该是数据库版本升级导致的存储过程执行错误,在数据库升级之前从来没失败过
那么怎么解决这个问题,不可能回退到V9.5.0.5版本,初步分析可能是V9.5.0.10对游标使用发生了某些变化,
随后做了一下两个尝试:
2 如果失败的话,一般都是和另外一个存储过并行运行,如果成功的话都是在串行运行
3 此数据库的锁超时设置为3分钟
至此可以基本判定是锁超时导致的存储过程失败,于是在系统上部署了db2cos捕获锁超时,果然第二天捕获到了锁超时,并且与
存储过程的失败时间一致,之后的连续几天都捕获到了关于此存储过程的锁超时,在分析造成锁超时的表与上述的两个存储过程所涉
及的表一致,最后通过调整两个存储过程的执行关系,调整为串行执行后,在没有出现sql501n错误
[db2inst1@limt ~]$ db2 ? sql501n
SQL0501N The cursor specified in a FETCH statement or CLOSE statement
is not open or a cursor variable in a cursor scalar function
reference is not open.
Explanation:
The program attempted to do one of:
* FETCH using a cursor at a time when the specified cursor was not
open.
* CLOSE a cursor at a time when the specified cursor was not open.
* Reference a cursor variable in an OPEN statement and the cursor
variable is not open.
* Reference a cursor scalar function, such as CURSOR_ROWCOUNT function,
and the cursor variable is not open.
通过上述描述可以看出程序在FETCH 或者CLOSE 游标的时候,游标没有打开。
随后导出存储过程源码查看,此存储过程特点如下:1 存储过程结构比较清晰,代码比较简单,在存储过程中调用了另一个存储过程
2 在存储过程中打开了一个游标,并且在代码后面也CLOSE了游标,在FETCH阶段也没有提前CLOSE游标
3 在嵌套的存储过程中也打开了游标,并且合理的关闭了游标
4 在嵌套的存储过程中也没有COMMIT操作(任何一个commit操作会导致所有的游标被关闭)
从代码上看不出来问题,那么回到系统整体上来分析:
1 此存储过程每天执行一次,以前从来没失败过
2 目前也不是每天都失败,偶尔也有成功的时候
3 每次失败的时候,在重新执行一次必然成功
4 此数据库前几天刚从V9.5.0.5升级到V9.5.0.10(V9.5.0.5 在linux系统上有内存泄露,导致SWAP空间被耗尽)
从上面两方面分析可以基本确定两点:
1 应该不是代码问题,如果是游标使用不当,那么为什么第二次调用就会成功
2 应该是数据库版本升级导致的存储过程执行错误,在数据库升级之前从来没失败过
那么怎么解决这个问题,不可能回退到V9.5.0.5版本,初步分析可能是V9.5.0.10对游标使用发生了某些变化,
随后做了一下两个尝试:
1 重新rebind存储过程 db2 rebind xxxx,在做完此操作后,刚好遇到十一长假,竟然连续十几天没有报错,以为问题解决了,可是没过几天就
又开始报错了,看来问题没有解决;
2 然后就在网上百度,资料甚少,看来用DB2人还是太少了,点了几个链接后,看到一个类似讨论sql501n错误的帖子,大致提到在V9.7后,
DB2的游标规则做了改变,在游标OPEN阶段如果发生错误,是不会返回错误,在FETCH和CLOSE阶段会暴露错误,看到这里顿时感觉有
点思路,虽然目前V9.5.0.10而非V9.7,但是根据某些传闻,IBM的低版本软件的高FIX补丁相当于高版本,在回去分析这个存储过程,发现此
存储过程运行有以下:
1 如果失败的话,一般都是运行3分钟多失败,如果成功的话就不到三分钟,2 如果失败的话,一般都是和另外一个存储过并行运行,如果成功的话都是在串行运行
3 此数据库的锁超时设置为3分钟
至此可以基本判定是锁超时导致的存储过程失败,于是在系统上部署了db2cos捕获锁超时,果然第二天捕获到了锁超时,并且与
存储过程的失败时间一致,之后的连续几天都捕获到了关于此存储过程的锁超时,在分析造成锁超时的表与上述的两个存储过程所涉
及的表一致,最后通过调整两个存储过程的执行关系,调整为串行执行后,在没有出现sql501n错误
0 0
- 透过现象看现象(SQL501N错误处理)
- 透过现象看本质。。。
- 透过现象看本质
- 透过现象看本质(一)
- 从ORA-01752的错误,透过现象看本质
- 透过现象看本质(轻松一下学哲理)
- 学会透过现象看本质,即使现象有时…
- 透过现象看本质 - 壮志未酬的BPEL
- 大道至简:透过现象看本质
- 透过现象看本质(二)-数据拟合
- 透过几种现象看学术不端
- 大道至简之八:透过现象看本质(房价推手)
- 淘宝刷钻为何屡禁不止 透过现象看本质
- 程序人生之一 MVC——透过现象看本质
- 透过现象看问题Cisco交换机状态灯全解
- poj-3013 透过现象看本质,其实都一样
- 透过现象看本质:如何真正实现数据可视化?
- 大道至简之四:透过现象看本质
- FatMouse' Trade(贪心算法)
- ECC加密算法入门介绍
- 通过cmd命令来导出Oracle数据库
- Canvas类的使用
- poj 3683 Priest John's Busiest Day 2-sat
- 透过现象看现象(SQL501N错误处理)
- 20141215bj+++++++++++++++++
- fiddler抓包数据分析
- js接收Json字符串
- KinFu中的ICP算法
- C++ 指向类成员函数指针的用法
- 1215
- android fagment 重叠问题
- BigDecimal转换为int和long