昨天写了一篇关于NOTAM系统故障的反思文章,实际上也是一个客户的领导给他们布置的作业,我帮他们思考了一下,做了个小总结。我个人感觉NOTAM的问题不在于运维规程的规范性,我想FAA如此重要的系统,其运维规程肯定不会太乱。从故障发生在一次例行检修说明系统虽然老旧但是维护还是规范的。
NOTAM故障的发生还是在于运维现场的技术管理方面出现了问题,计划外处置没有很好的管理,并且在故障处置过程中缺乏高水平专家的指导。在这些年的实际运维工作中,我也经常会遇到一些原本是小毛病,因为处置不当而造成大事故的案例。
这些年经历过不少这样的案例,大部分都与处置过程中不规范或者技术水平不足有关。哪怕有些企业运维管理十分严格,预案做的也比较完备,但是也很难在遇到运维故障时不犯错误。很多类似事情发生的原因是现场的运维人员在认知上的不足,或者考虑问题不够全面。当故障发生时,为了尽快恢复业务系统运行,运维人员顶着巨大的压力,很容易发生误操作。有时候操作一提交,自己就已经发现自己错了。我经常和我的同事说,遇到运维故障,凡是涉及到写的操作,一定要经过研判,同行沟通后再做决定,如果有可能,要做好备份以便回退,不过这依然不能避免事故的发生。
十年前,一个客户的的DSG复制死掉了,现场的运维人员重启DSG无效束手无策了。咨询了公司的远程三线专家后也没想到什么好办法,于是三线专家建议重启数据库服务器。没想到重启服务器之后不但DSG的问题没有解决,数据库也起不来了。实际上当时是AIX系统的一个共享VG出故障,有一块盘找不到了,从而导致数据库的200多个文件找不到了。现场的DBA水平一般,无法将现场情况准确的反馈到三线,三线专家对AIX系统也不熟悉,因此当时就没有正确定位故障。
当时RAC的另外一个节点还是正常的,业务没有受到影响,按照企业的规程,处于业务高峰期是不能随意操作的。于是等到6点下班后,现场DBA根据三线专家的建议把另外一个节点的数据库重启了,不过没有没有效果。于是重启了另外一个节点的服务器。经过一通折腾,终于两个节点都出现了同样的错误,整个数据库都宕了。
如果此时停止折腾,把问题分析清楚再继续处理,还是有办法快速恢复的,因为主要修复了存在问题的PV的卷头,卷组是能够恢复的。不过三线专家也是个半吊子,为了拉起数据库,居然建议现场DBA重建了控制文件,把有问题的文件全部去掉了,通过resetlogs强制打开了数据库。不过数据库是打开了,很多表一访问就报错,应用还是无法恢复。最终只能从备份数据中恢复数据库。十多个TB的数据,整整恢复了三十多个小时。
还有一些系统故障是因为系统中早就埋下了隐患,有句话说“一次事故中至少有七个以上的错误”。下面介绍的业是一个十多年前的案例,客户的一套数据库系统因为存储故障而出现SYSTEM表空间和数据表空间有大量的坏块,无法启动了,不过幸运的是这套是他们的次核心系统,搭建了DG。
我当时在远程指导他们的现场恢复,本以为在DG的保护下,这个系统恢复是很容易的,只要从DG侧拷贝文件过来,再RECOVER一下就可以了,和他们讨论完恢复方案后已经快一点了,于是我就睡觉了。没想早上不到6点我就被电话叫醒了,原来他们的恢复工作失败了。
现场DBA反馈说备库无法正常只读打开,他们尝试了多次也不成功,于是我让他们先把备库的ALERT LOG发过来。我看到DBA以MOUNT方式启动数据库实例,并且备份了控制文件,不过随后运维人员重建了控制文件,这个操作和我说的第一个例子有点类似,重建控制文件打开数据库是最容易被DBA错误使用的操作之一。重建完控制文件后,进行了一次SWITCHOVER。
这次SWITCHOVER是注定要失败的,因为这个数据库还没有完全恢复“END-OF-REDO",这种灾难情况下要运气十分好才有可能能END-OF-REDO。于是只能开始做recover database。
在recover的时候遇到了一个问题,找不到一个归档日志文件。客户觉得他们的归档日志保留周期是一周,不可能缺归档日志。此时DBA没有仔细分析报错信息,而是继续倔强的重建控制文件,并且加上了resetlog选项。
其实每次重建控制文件的时候都有警告消息:
此时数据库报错是当前控制文件与实际数据文件不符,需要执行下面的命令才能使之达到一致,不过当时运维人员并未深究其原因。而是直接把这些命令拷贝了下来执行了!如果说之前的错误还都不致命,一旦做了这个操作,那就是致命的了。不幸的是,这个操作被执行了。
执行了这些命令后,控制文件成功创建了,并且数据库也成功打开了。似乎一切都OK了。没想到,这个打开的数据库只是个样子货,大量的表无法访问,一访问就报错。
从v$datafile中可以看到,其中有不少OFFLINE的文件,甚至有很多文件的checkpoint scn都是0。说明这些文件从创建之后就一直没有数据写入。这又是什么原因产生的呢?
继续往前翻看ALERT LOG就会发现,原来那个重建控制文件还不是第一个错误,真正的错误在20多天前就造就了。从日志可以看出,DBA把standby 文件管理方式设置为manual,然后手工删除了一些名为UNNAMExxxxx的文件。然后把这些文件rename为一个裸设备名。
这种神操作是干什么的呢?现在的很多DBA都没有使用过裸设备了,在使用裸设备的情况下,为主库准备裸设备的时候,也一定要在备库上准备好。如果主库创建数据文件的时候,备库的裸设备不存在,这样在备库中就会生成一个UNNAMEDxxxxxx的文件。为了将这个文件重新迁移到裸设备上,DBA就做了上述操作。这种失误以前发生过多次,每次都是采用这种方式去解决的。备库上难免会遇到不小心忘记创建裸设备的情况,不过只要处置得当也是没问题的,采用这种方式处理数据文件缺少了一个步骤,就是执行alter database create datafile ... As '....'。
错误的处置方式导致此类数据文件一直处于未完成修改的状态,也就是说这条异步执行的命令并没有正确执行结束。因此虽然这些裸设备都已经存在了,DATAGUARD一直未对此文件进行REDO APPLY。并且在DATAGUARD中查看这些文件的状态是RECOVER状态。实际上这些文件大多数是空文件,里面从来没有应用任何数据。
由于DATAGUARD中的这些文件本身存在问题,导致这类文件处于非正常状态,这些文件最早的是1月份创建的,所以要恢复这些文件有些需要1月份以来的REDO LOG,有些需要4月7日以后的REDO LOG(DBA分别在1月份和4月份犯过忘记预先在DG库建裸设备的错误),那个1_87118.dbf就是1月份的归档日志,此时早就被清理了,当时已经无条件进行修复。
从上面的分析可以看出,虽然这个DG一直在跑着,实际上几个月前就已经是个样子货了。而DG有问题并不影响生产系统,因此这个问题也一直没有得到纠正,认为有DG保障的核心生产系统实际上一直在裸奔。
从今天举的这两个例子中可以看出,大部分的类似事故的发生都与运维团队在处置问题的过程中缺乏资深的专家支持有关。DBA在做超出其认知能力的操作时,往往就会因为考虑不周或者错误的认知而犯更大的错误,从而引发更大的问题。此类问题发生时,获得三线专家的支持尤为重要,因此在国外三线专家远程支撑服务的市场很大。而在国内大家更愿意为现场服务付费,而不愿意像买保险一样买一个远程的专家服务。而当系统真的出故障的时候,花上买专家服务十倍的价钱去请人搞定故障大多数客户还是愿意的。只不过这种临时参与的专家,对客户的系统并不了解,要想在短时间内准确的定位问题,正确的解决问题,也是要打折扣的。