最近实在实在是整个人超大负荷工作,非常非常累。早上还在睡梦中接到了公司电话,说有大量订单找在后台找不到订单资料。立刻简单洗漱直奔公司。
到 了公司,了解了一下情况,是由于昨天新增的修改导致的。因为zen cart的用户控制面板只是提供了一个订单列表,而没有对某个订单进行重新支付这个功能,而客户看账户中有订单又不愿意再下个订单或者担心重复下单,所以 让技术部同事给zen cart添加一个失败订单重新checkout的功能。问题就是因为这次简单的修改导致的。
这 个网站我们用的是zen cart.我们技术部花费了两个人力+1个半月的时间对zen cart的下单支付流程做了全面的优化,简化,修改是在一边修改一边使用的过程中进行的,因为公司实在有很多的网站要急需使用,加上前期经验的不足,大大 小小的BUG也修改了很多次,好不容易到了得出了一个相对稳定的版本。我们瓷壶zen cart的订单流程修改了,在客户前往支付网关chekcout前生成了订单,这样也不过是为了最大限度的保留客户的资料,同时为了方便识别订单来源(哪 个网站),引入了一个新的自定义的订单号(order_num)。问题就出现在这里。为了让客户能够对旧的订单重新进行checkout,而又不让客户觉 得有两个不同的订单,我们技术部的那个同事就将原订单的order_num修改成新的订单号,而在新生成 order_num时,没有控制后条件或者是处理时间。结果不管订单如何全部,只要客户进行了查看操作就会update掉原有的order_num。 order_num又是发给支付网关的唯一凭据,也就是业务是用这个来录单的。这样就造成了,支付网关那边成功的订单号有的在我们后台找不到对应的订单 号。
什 么办?头都大了!动员整个技术部一起试图从数据库中寻找一些蛛丝马迹,奈何这次是没招了。客户购物篮大部分被zen cart清空了,旧的order_num被修改了,没留下任何信息,唯一有点可寻的是order_num订单号是有时间的,如果通过时间比照加上金额或者 有点希望,但是不可靠,而且麻烦。真是汗,这意味所有的订单将不能出货。在一遍又一遍分析了zen cart的整个数据库后。
看来这次只能求助mysql本身的日志功能了。马上打开mysql手册,看到:
The general query log is a general record of what mysqld is doing. The server writes information to this log when clients connect or disconnect, and it logs each SQL statement received from clients. The general query log can be very useful when you suspect an error in a client and wAnt to know exactly what the client sent to mysqld .
The binary log contains all statements that update data or potentially could have updated it (for example, aDELETE
which matched no rows). Statements are stored in the form of “events ” that describe the modifications. The binary log also contains information about how long each statement took that updated data.
知 道这可能是最后的希望了。万幸我在配置的时候没有为了一点点的性能而关闭掉binary日志。马上查看了my.cnf,找到日志保存路径,复制出昨天今天 的日志,我不能直接操作啊,万一把日志弄坏了什么办,现在是非常小心翼翼的。备份了几次数据库。还要测试一下能不能用。然后开始使用mysqlbinlog读取binary日志并将结果重定向到一个文本文件中。然后再使用grep根据order_num中具有日期的特点进行二次过滤,分别导出这三天的所有insert,update sql语句。
mysqlbinlog mysqlbin0928-log
> a.txt
cat a.txt |grep 20090928 > 20090928.txt
cat a.txt |grep 20090929 > 20090929.txt
这样找出了所有数据库的数据的变化情况,自然也就解决了问题,虽然是比较笨重的方法,不过总比让这些单子付诸东流的好。