情景:Oracle EBS系统批量付款
现象:Oracle EBS系统批量付款卡死
环境:Oracle EBS R12.1.1
取名“一条数据引发的血案”是因为这次事件把自己的第二次通宵奉献出来了。
直接进入主题:2016年4月21日周四,客户在财务系统内批量付款,这次付款从表面上看与往常的批量付款并无差异,92笔付款,量不算大,结果在最后一次鼠标点击确认的时候导致系统直接崩溃(只针对此功能页面,其他功能还是能正常操作)。如下图所示:
一般涉及到付款的操作,一直都是需要十分谨慎的,要是因为付款抽盘数据错误,导致网银付款错误致使公司多付账款,将会造成不可挽回的错误。客户(刚进入公司的新同事)在第一时间找到我,焦急的心情从客户的表述中可以窥见一二。自己也是第一次遇到这样的错误,第一反应就是数据库表被锁了,因为之前也遇到过类似的错误,直接从后台解锁后即可解决问题。但是这次似乎并没有那么简单,后台并未锁表。于是,找到客户的纯数据库DBA检测,从后台的常规日志中可以看到“timeout”的描述,于是通过各种sql命令和linux命令穿梭于PLSQL和操作系统中(幸而能有同事提供生产环境的数据库)。然而,并没有解决,知道下班也并未有任何实质性的进展。于是,为了客户能在周五将今天的付款付出去,在已经格式化付款的状态,一条一条在付款撤销界面点击停止付款,大概统计了一下,这个步骤会超过500次鼠标点击(oracle做得太不智能了,吐槽一下),而且在这个过程中,还出现如下图所示的囧地,无法停止付款(后台解决,IBY_PAYMENTS_ALL表字段update).
由于感觉到事情的严重性,当天晚上到10点多仍然没有解决,于是乎觉得在办公室继续奋战,做到大概12点多,实在熬不起了,很久没有一直工作持续那么长时间,而且是脑袋一直不停的高速运作,在这过去的几个小时内,问过很多同行,大多都是没有好的建议,都建议再向EBS DBA咨询求助。晚上接近一点,睡觉(幸好办公室有张折叠床)。早上6点过几分,起床。继续查找问题,此时已经将昨天留下的92条中的78条数据付款(每次5条左右的数据批付款,也是倒霉,每次都没有碰到那天错误数据)。现在这个时候,最怕的就是客户的追问,不过第二天一早,客户的邮件就来了。客户希望在下午两点之前能解决问题。压力山大。为了能尽快解决问题,向公司申请EBS DBA资源,于是,公司提供一位DBA远程协助。经过20多分钟的排除,得出两个结论:第一,TCP SOCKET超时严重,排列超时第一位;第二,行级锁超时严重,排名超时第二位。DBA也只能做到这里了,但是此时时间已经是下午2点多,于是只能去跟客户解释,目前正在全力排查问题。客户也还好,也只能如此(其实我相信客户内心是崩溃的,两天时间已经积压了好几百万款项待付)。
接下来是周六,本来是该好好休息的时间,结果因为这个事情,觉都睡不好,早上7点多就起来接着查问题。一上午还是没有比较实质性的进展,中午叫了外卖,下午还是继续排查。这之前跟领导甚至商议过如果找不出问题要怎么样先暂时解决问题(具体什么方法就不在此透露)。默默耕耘,必有回响。在晚上11点多的时候,也就是逐条付款的时候,界面上出现了一个比较直接的错误提示,违反唯一约束条件。如下图所示:
于是,能80%确定是应用数据问题,结果果然发现,其中一个供应商的地点层竟然在失效后还多生成了一条付款数据,然后这在界面上看起并没有其他异样,结果从后台查看数据才发现此异象。表现如下图所示:
此时,感觉修复此数据即可解决问题,于是对比正确的数据后,修复数据完成(具体修复方式,如果人遇到,可直接留言交流或者邮件),再次去付款,正常!!!此时想想一条错误数据,竟然能使系统到如此崩溃的地步,也是醉了。
总结:这个问题告诉自己,很多事情并不只是表面上看起的那样,需要更深层次去发掘问题的根源所在。在解决这个问题的过程中,自己也学到了很多东西,对session的理解,查找效率低下的SQL方法,甚至一些很高级的操作系统层report方法。同时,要感谢在这个解决问题的过程中,客户的理解及各位同事的帮助。此文谨以记录此事。