调程序差点调出信仰(2)

200934号。天气更加好转。阳光暖暖地照在身上,很有点阳春三月的感觉。上班路上,看见大群的麻雀聚拢在刚抽出新芽的柳树上,热闹地叫着,偶尔又为过往车辆的喧哗声所惊,扇着翅膀飞快地掠过马路,隐没在了树林的深处。林边的空地上,大朵大朵的山茶花开得鲜艳。面对此情此景,不禁想,春天来了,万物都在生长。同时苦笑一番。春天万物生长,而老子的神经却在渐渐石化。有了这几个月的经历之后,开始怀疑对这个世界的认识。而这两天调了这个bug之后,发觉面对这个世界,个人的努力可能真的是无能为力。

牛人zwm在《程序员的十层楼》的最后神秘又绝望地写道:“宿命论将在有时间的时间里永远统治着这个世界”。一开始看很不以为然,但是将他的分析考虑进去以后,就不寒而栗。如果一切都在宇宙诞生的那一瞬间匆匆决定,那人他妈活着还有什么意义?

《高效能人士的七个习惯》中信誓旦旦地引用梭罗的话说,“最令人鼓舞的事实,莫过于人类确实能主动努力以提升生命价值”。相信任何一个神智正常的人看到这句话,都会在深以为然同时,深受鼓舞。但是如果他又向我一样经历这两天匪夷所思的调试经历,可能就难免心情沮丧,情绪低落,怀疑主动努力的价值。

怀疑归怀疑,但是bug还是要继续调的,谁让老板付钱就是叫咱来干这个的呢。在陷入完全沮丧,彻底放弃之前,还是需要做最后一番努力。

于是乎我静坐下来,拿起铅笔,细细描绘出整个异步复制的流程,检查流程中各个环节的具体操作,检查各个数据对象产生,赋值和消亡的过程,试图从中找到一丝往日编程时所没有考虑到的漏洞,找到一个思考的方向。检查的结果是,我再一次发现,一切是那么地完善和有条理:各个环节忠实又准确地处理数据,数据对象按照预先的设定,该产生的产生,该改变的改变,该消亡的消亡。 这些消耗我过往一年时间的代码,每一条语句都充满过往一年的回忆,此时此刻显得比我老爸老妈还要可靠:苍天呐,你们为啥要这般可靠啊。

此时此刻真的有点神神道道了。接下来的做的事情已经完全不合逻辑,完全是在发泄郁闷的情绪:我先把异步复制时间间隔改成5秒,等待8秒;接着又恢复异步复制时间间隔为30秒,等待65秒;结果都没有重现问题。崩溃之下,将异步复制时间间隔从5秒开始,等待时间从8秒开始,每一次递增5秒,循环N次。最终的结果是,不管怎么测试,始终是第一次ok,第二次出错,留下4条该死的记录在sysasyncdrecs表中。

恍惚中我觉得,耶稣基督,穆罕默德,释迦摩尼在这个bug上灵魂附体;××大法的×××大师正在催运神功,要用这个bug将俺这个小程序员彻底逼疯。大师啊,虽然俺邮箱的垃圾箱里始终躺着贵法的几封垃圾邮件,即使我在青葱年少时对贵法在本村总代理根叔的劝诫给予坚定的置之不理,可也用不着麻烦你老人家亲自动手给我彻底的教育啊。

无奈之下只好主动发出一个信号量,唤醒wld的管理线程。我走到wld的位子旁边,说:“ld,我是搞不定那bug了,那玩意也太邪门了。”wld听后奋然起身,带着几年调试经历所积累出的对bug的不屑,亲自来调这个bug了。

趁着这个机会,我走到阳台上去放放风。时已下午,天气依然很好,虽然不如早上那般阳光明媚,但是站在5楼阳台上,风呜呜地刮在脸上,竟然没有感受到一丝寒意。“吹面不寒杨柳风”,看来春天真的是到了,在一个漫长的冬天过后。春天是个充满希望的季节,每当春天来到的时候,人们内心里面主动改变自己,改变生活的渴望,便会抑制不住地悄然滋长。但此时此刻的我感受着春天的气息,内心里却一片死灰般沉寂。

“宿命论将在有时间的时间里永远统治着这个世界”,世界上最悲惨的事,恐怕莫过于在经历连续几个月的压抑之后,听到有人以雄辩的语气说出这句话,而且还他妈给出了精巧的证明。《程序员的十层楼》告诉我,我现在的水平,离上帝还有8层楼的距离,但此时此刻我站在5楼阳台上,倒是觉得,我离上帝其实只有5层楼的距离……

一声凄厉的汽笛声将我从抑郁中带回现实。抬头远眺,靠,狭窄的川杨河上,几条运输船撞在了一起,整个河面顿时拥挤不堪,热闹非凡。在汽笛声的伴奏下,船员们站在各自的船板上互相指责和指挥着,没有丝毫相让的意思。看来天气一好转,人的脾气也见长了。

回到房间里面。Wld不在了,出现了更紧急的任务,将他调度走了。只留下我面对着这个整了3天的bug。此时时刻,我能做些什么呢?

牛人中的牛人,天才中的天才,真正的经济学家杨小凯生前在得知自己患有癌症之后,皈依了上帝,因此获得了继续活下去的信念和勇气,多活了几年。而此时此刻的我,是不是也要选择一份世俗的信仰?靠,那选择什么呢?基督教蛮横无理,佛教悲观消极,伊斯兰教又把生活搞得挺没情趣。罢了,还是老老实实调你的bug吧。

我决定再仔细跟踪一遍异步复制流程。处于心灰意懒的情绪,不想再按F5了,于是在关键的地方写了几条printf语句,打印一些调试信息,然后全速运行。我懒懒地靠在椅子上,盯着dos窗口上蹦出的一条条调试信息。

我主要关注的是打印出来的事务号。第一遍测试如预期那样,顺利通过,最后的事务是4978。第二遍测试,事务号从5016开始,屏幕上规整有序地打印出事务被提交,事务数据被放入到sysasyncdrecs表,表中数据被取出发送,发送完毕后别删除……。突然,屏幕上显示,“4978 trx async data send out and deletewait trx num-1事务4978的数据发送完毕并被删除,未发送的事务数减1)。靠,第二遍测试不是从5016开始吗,怎么跑出一个4978事务来了!?

大脑快速思考片刻后,恍然大悟。

其实出错的逻辑非常简单。我这几天的调试误区在于,看到第一次测试时,测试用例没有报错,就认为它完全没有问题,总是试图在第二次测试上面找到错原因。而事实真相是,正是由于第一次测试时出现了潜在的问题,导致在第二次测试时,测试用例直接报错:

1.第一次测试时,测试脚本在最后一个事务提交后,会等待35秒,验证主从服务器的相关表的数据是否一致,然后在主从服务器上清理环境。但是由于建立了对称复制,从服务器还需要再完主服务器发一遍数据,等主服务器返回“该事务已经做过”的消息后,才会把数据从sysasyncdrecs表中删除。结果在从服务器发送数据之前,环境就已经被清理了,导致复制关系被删除,异步复制的执行条件被破坏,从而数据没有发送到主服务器。

2. 第二次测试时,又重新建立了复制关系,于是异步复制的执行条件又被重新建立了,第一次测试时剩在sysasyncdrecs表中的那些数据,被得到复制。

3. 但是,此时异步复制第一次测试时剩下的数据,将导致第二次异步复制发生混乱:每次异步复制完毕后,都会将“未发送的异步复制事务数”减1。而“未发送的异步复制事务数”,在每次建立异步复制关系后,都初始化为0,每次事务提交时便将该值加 1 这样,异步复制第一次测试时剩下的数据,只对该事务数减了1,却没有加1 (加1操作在第一次测试就执行了)。 于是,第二次测试时,未发送的异步复制事务数便被多减了1,这就意味着第一次测试时的事务抢占了第二次测试时事务的被发送名额,导致第二次测试时有异步复制事务不能被发送成功,查询出错。

一切终于水落石出。看来在程序的世界里,一切都能够得到符合逻辑的解释,只要你足够仔细和耐心,以及主动思考。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值