Sybase杂记(二)

   上个星期我所在的项目出了两件大事,让我整整忙了一个星期,到今天才缓过来.这两件事都跟Sybase有关,其中一件已开始动摇我的理念。
   大事纪一
   五一节后,第一天上班刚到办公室就被数据库管理员叫住,说4月份的通行月表没有数据(我们现在维护的系统数据量大,所以我们采用按月存放数据的策略。每个月一号定时通过脚本将上个月结算数据从工作表放入对应的月表)。我听到这消息后立即查看了5月1日后台的日志文件,发现从工作表到月表的成功纪录为零,现有生产库中工作表纪录数也为零。我当时觉得这个事情很奇怪,客户的报表都是从这个月表和工作表所组成的试图中提取数据,而客户整整一个月都没有投诉系统发生异常。我当时以为数据库出了问题,就立即通知数据管理员帮我恢复4月31日生产库,再看看当时工作表的情况。我立即上VSS库查看升级清单上系统升级的情况,根据清单显示系统上个月没有升级情况。我跟其他开发人员沟通,问他们上个月是否处理过异常,他们的回答都是没有。我就觉得纳闷了,难道数据无缘无故的飞了不成。(本人一直有个信念,任何灵异事件都是有原因的,只要我们认真分析和思考,是可以重现和解决)这时数据库管理员通知我,4月31日的库已恢复完毕,而且他检查数据库中工作表的记录数也为零。我也过去检查了一下发现工作表的纪录的确是零。这时我想难道我们程序真的有Bug,造成数据丢失,但是心想程序三月份都没有出现问题怎么现在突然冒出来呢?难道数据库的备份时间比我后台脚本的时间提早了,想到这里我再叫数据库管理员帮我恢复月中的数据库,查看当时数据的情况。同时我也组织其他开发人员查看我们程序的代码,看是否存在这个Bug。代码查看整整一个下午,大家都没有发现问题。下班之前,4月中旬的库已恢复完毕,数据库管理员还是那句老话工作表还是空的。难道这次真的灵异事件,我觉得不可能,任何事情都有原因。我当时检查一下前几个月的月表情况是否也存在同样的情况,检查后发现4月份以前的月表的都有记录,消费金额跟第三方提供报表中消费金额一致,证明其他月没有数据丢失的情况发生。但在检查过程当中,我也发现一个奇怪的现象,今年3月份月表纪录数比2月份月表记录数多出约1.5倍。我当时觉得数据增长率和缺少两天的数据不会造成怎么大的差距。我查看了一下数据发现4月份的数据全部都在3月份的月表里。怎么会出现这个情况呢,我问了一下数据管理员3月份有什么异常发生,他说上个月脚本没有成功运行,是我们小组的开发人员手工进行的数据移植工作。我回去查找异常修改记录发现修改异常脚本如下:
     exec sp_rename  oldtablename ,newtablename
    
     create table  oldtablename(
      ......
      ......
      ......   
     )
    
     我问那位同事为什么不按照正规的先建立新表,在把数据转移从旧表转移到新表中,最后删除旧表中的数据。他说表中数据较大,整个过程耗时会很长,sp_rename更改表名很快不会对业务运行造成多大影响。听到这里我感到很奇怪,以前我用SQLserver 2000用sp_rename它也是先建表再转移数据,时间也快不了多少啊。难道Sybase的sp_rename实现方式有独特之处。我查阅了Sybase文档发现问题就出在这个sp_rename上。
     在官方文档中sp_rename 功能说明:更改当前数据库中用户创建对象或用户定义数据类型的名称。其中有段警告的内容解释了上面异常发生的原因。如果过程,触发器和试图依赖于名称已更改的对象,它们将继续有效,直到它们被删除并重新创建。同样,旧对象名一致会在查询结果中出现,直到用户更改并重新创建过程,触发器或视图。执行sp_rename时,应更改任何相关对象的定义。使用sp_depends可查找相关对象。我的同事只做了前面的步骤,并没有把旧表有关联的存储过程重建,造成这次异常的发生。
     异常发生原因找到后,我和同事一起去转移数据和重新建立更旧表相关的存储过程,触发器和试图,这次工作量比只转移数据的工作量增加很多。经过这件事情我感到程序员作技术活能偷"懒"是好事,但是应尽量用你所熟悉的技术,否则有些情况下回得不偿失。
     大事记二
    星期三凌晨三点钟,接到客户电话说系统月结后,数据核对发现发票数据和转帐数据少4千多万元,叫我马上赶过去。我当时以为我在做梦,自己掐了一下大腿,发现真TMD的痛,原来自己不是做梦。当时我赶快穿起衣服,洗了一下冷水脸就就以最快的速度赶往公司。在回公司的路上,我头脑里一直在想最近大半年都没有哪个动过月结的程序,我们系统也没有发生过丢失数据的异常。难道这次真的是big trouble吗?到达公司后,查看程序编译时间和相关存储过程创建时间都证明了程序在半年时间内没有变更过。经过分析现有数据,发现造成本次异常的原因出自一个存储过程,下面有该存储过程的造成异常SQL片断(由于涉及公司机密,以下代码我用伪码代替):

.
.
.

------>>SegmentA
   
    insert destationTable
    select  '01',a.c1,a.c2,b.c3  ......
     from  A a,B b
     where a.c1=b.c1   
       and a.flag in (1,2)
  
    if @@error<>0
      begin
         rollback  tran
         select @breakpoint=30001
         insert into error_log (procedure_name,getdate(),@error,@breakpiont)
         return(@breakpoint)
      end
     
------<<SegmentA

-------->>SegmentB


    insert destationTable
    select  '02',a.c1,a.c2,b.c3  ......
     from  A a,B b
     where a.c1=b.c1   
       and a.flag in ( 3,4)    
      
    if @@error<>0
      begin
         rollback  tran
         select @breakpoint=30001
         insert into error_log (procedure_name,getdate(),@error,@breakpiont)
         return(@breakpoint)
      end
--------<<SegmentB
.
.
.
 
  造成数据缺失的原因是SegmentA的数据没有成功获取,而我重新运行该过存储过程得到正确的数据.我当时以为在月结程序运行时,可能有其他脚本运行影响了,A表,B表中的数据,造成两表关联后没有符合条件数据.第二天,通过数据库管理员的帮助查看数据库的审计表,发现在月结开始到我修正数据之间时间段内没有对A表,B表有任何操作并且对destationTable表审查发现只有月结程序调用的存储过程和我手工脚本对其有操作。这就让我很纳闷为什么当时没有成功从A表,B表中提取数据呢???难道当时SeqmentA段内脚本执行有错误并且@@error=0吗???这个情况发生地概率应该接近于零吧。不是这个原因又究竟是什么造成了这个现象呢?就当我迷茫的时候,数据库管理员从数据库日志文件中发现了一个警告信息:“server WARNING:memory usage in procedure headers(2)  does not match memory usage count in pss(100) for server process id 88”而且警告中process id正是月结程序所使用的id且报警时间与发生异常存储过程结束时间一致。以为柳暗花明了终于找到异常发生的原因的时候,数据库管理员就从Sybase工程师那里得到这个警告不会对数据库产生任何影响的回复。
  我将当天月结的数据全部放入到测试库中,重新模拟当晚的月结。经过几次的试验,数据一切正常。现在整个线索都断了,这个异常到现在为止都没有找到发生的原因。这是我工作4年多第一没有找到原因的异常,郁闷阿!!!我还是坚信任何异常发生都是由其原因,只是这个异常发生的原因不是我们这些凡人的能找到!!!(现在我只能自我安慰了) 
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值