Migration Error

上周六着手把生产环节从一台有硬件故障的机器迁移到另一台。

生产环境的架构比较简单,应该不会遇到太大问题,但还是遇到了不可逆的数据损失!

生产环境中的所有服务都在一台物理主机上,也就是说在一台物理主机上包含了逻辑web、逻辑db、逻辑worker等服务,他们被LXC管理着,彼此隔离但又可以很方便的连接。

为何会放到一台物理主机上,除了目前我们访问量不那么大之外,我们很关系的一个问题就是共享存储,因为不想搞出一个像S3那样的庞然大物,而有时我们又很想有一个集中化的存储,于是就放到了同一个物理服务器上,这样可以在LXC中把需要的磁盘挂载进去。

首先在另一台服务器上部署当前的代码,其中包括codebase和依赖的安装等等。得益于我们良好的工程化,使得我们可以用一行命令就把整套环境部署到完全空白的服务器上。接着我们把这个服务停掉,把生产环境前天晚上的备份恢复回去(也是一行命令),这样我们就有了两个比较接近的环境。

然后就是停掉生产环境,把当前环境的数据恢复到新环境,之后再启动新环境,切换域名的DNS指向,在老环境中用iptables把剩余流向转到新环境中。

看起来简单,实际操作也有些手忙脚乱,比如我们让新老环境并行运行了一段时间,但接受请求的是老环境,可是我们的系统并不只是被动接受请求,还有同步其他系统的订单服务,例如每15分支会同步天猫、京东的订单到系统中,这些订单在半小时后会下到ERP中等等。

因为新环境的数据最终被老环境覆盖了,对于数据的损失仅限于从日志中找到一些线索。目前唯一能够确定的是有几个订单在老环境中被同步到了本地,并下到了ERP中,但后来因为被老环境的数据覆盖,这些订单在我们系统中消失了,可在ERP中能找到,后续就出了一些问题,比如有几个订单发了两次货,相应的有几个订单没有发货。

出了这样的问题,我们从日志中得到的信息很有限,对于结果的分析不够完善,但最终也找到了一个比较有说服力的问题原因。

问题发生后,我们还考虑过是不是在停掉相关服务后有些数据在系统缓存中并没有写入磁盘,因为我们用的是rsync来同步两台服务器的数据文件(数据库文件),之后如果再做迁移要执行几次sync命令(也许LXC已经够好能为我们处理好这些,但做了总没错吧)。

另外需要主要的是迁移online系统需要把外围接口或者服务都停掉,以免出现我们遇到的这种问题。