维护之夜,说点故事和经验
人内心的默契就是这样,今天要写的标题和几年前一模一样,干脆在原来的基础上做一些补充。
今晚是一个维护之夜,出于蓄势待发状态,对于我来说,每到这个时候就会想起自己这些年熬的那些夜,还是蛮难忘的。
举几个自己印象深刻的维护之夜吧。
1)印象最深刻,压力最大的维护是多套Oracle数据库从10g升级到11g,在前期做了多轮测试,在实际操作还是碰到了不少ORA-00600的错误,不过前期的问题都成功化解,而在最后启动服务的关头,服务抛出了一个奇怪的错误,记得当时情况已经很紧急了,如果修复不了,所有的服务都要回退,当时是满世界的打电话求救,唤醒了全球的多个技术专家,有的定位是bug,然后在建议之下打了补丁,但是还是没有效果,还找了国内的一个前辈帮忙分析问题,最后戏剧性的是,修复的操作竟然是重新清空一下回收站,具体细节忘记了,但是这个神一样的操作让我们和原厂都感叹不已,因为在当时原厂已经紧急开了case。 接下来的第二波压力是关于业务异常,有些业务存在连接异常,导致数据库开启了5000连接依然连接池溢出,在这种情况下发挥了我的开发技能,快速写了释放连接的脚本,同时开始了代码分析,因为我有开发的代码权限,所以我从代码层面去做一些分析,没想到竟然很快找到了导致连接异常的代码片段,当发给泰国的开发团队时,他们还是很吃惊的。
2)有一次大型维护的时候,登录了一套准生产测试环境,做了下业务变更升级,没想到线上和测试环境的模板配置不一样,结果就想当然在线上环境点击了YES开始自动升级,没想到整个线上环境开始了一系列的不可控操作,于是乎整个业务系统全服回退,这个事情对我们造成了很深刻的教训,而我内心也是很煎熬的,在几个月的时间里都心神不宁。
3)在国内的一次大型维护,想想都是满满的使命感,差不多有13套环境是在1个多小时内完成,有切换的数据库,有做数据库升级的数据库,有做跨平台迁移的数据库,没想到预估的3个半小时结果在1个小时以内就全部完成了。但是戏剧性的一幕发生了,开服的时候,发现用户充值失败,结果留给我们的时间就很短了。当时记得气氛很紧张,领导拍板,如果10分钟内解决不了,就全服回退。当时看着同事在那里手工敲一些系统命令,带着压力还多次敲错,我赶紧在另一半开始拿出自己准备的脚本开始快速排查,所幸的是在最后的关头,定位到了问题,是一个db link的问题,本质上还是多套环境的关联变更导致,修复之后大家长舒了一口气。
4)最无聊的一次维护,就是在某国内客户现场值班,被抓壮丁安排去值班,主要就是过去充人数,记得自己在椅子上摆了各种姿势睡都不舒服,看着旁边的外国小哥估计还没有倒过来时差,他们在那里看《阿凡达》,后来才知道他们是特派过来的DBA,系统迁移之后,他们负责清理数据。
5)最带感的一次维护,是在一次大型迁移中,出现了性能瓶颈,导致服务回退,后来大家压力都很大,因为是一套全新的技术方案,也是在原来方案无法满足要求的前提下的改进,当然也受到了很多原厂的质疑,在压力中我们开始了地毯式排除测试,记得连续几天都是测试到后半夜,而在最后定位到问题之后,自己心里的疙瘩算是解除了,而在第二次升级的时候,记得客户的大boss也过来了,走进作战室看到一切都很顺畅,在第二天还发了表扬信。
6)这一次可能是很有特点的维护,如何摆脱常规的数据库维护影响,比如数据库需要重启,可能重启的操作需要15秒~1分钟,如何让业务的影响降低到2秒内即可恢复。看起来很普通的需求如何和业务密切配合来改进,对于运维同学来说,这种维护的意义是很特别的。
7)2年前的那次维护算是在公司内的一次练兵,算是MySQL方向的一次核心系统的切换,后端的运维操作是因为数据库bug需要重启实例,在方案设计上实现了整个集群的切换控制在5秒之内,过程都是有条不紊,可以用完满来解读。
除此之外,维护时间网络故障,DDL(rename操作)无法变更,业务脚本执行失败,服务启动失败,连接池异常等问题,数不胜数,这些都是平静表象下的风波。
当然在这之外也有几点老司机的告诫和建议:
1)维护时打开尽可能少的工作窗口,越是关键的操作,打开的窗口数量越要谨慎,这么考虑的一些因素主要还是跳转到错误的窗口,我一般建议是打开4个以内的窗口,而且最好是对称的模式,方便标记和辨别。
2)做好配置文件的备份,备份的工作在这里是重中之重,之前还碰到过一次服务异常导致中间件文件被刷的情况,所以有了备份才是救命稻草,另外有些备份需要注意不能太过于频繁,尽量不要提前很多,最好是备份操作和后续的流程都是一个人能够衔接起来,要不文件命名和备份细节会存在差异,这种差异很要命。
3)保持体力,在维护前的夜晚是很平静的,最好提前做好休息和能量补充,这个时候以能够休息保持体力为前提,尽量不要干坐在座位等到凌晨。
4)尽可能做到双人检查,凌晨的操作,如果很多同学实践过,会发现脑子不够使,有时候看到自己列的计划都感觉有些懵,所以计划内容要细,要明确,有些描述信息的描述就要增加的清晰准确,比如中间件的负载均衡,有一个操作步骤是把proxy3的服务做下变更,在这里最好把相应的服务IP端口之类的都给清晰,到了凌晨的时候再去找,去确认是很危险的,当然最怕的还是自己感觉,凭猜千万不可取。两个人能够做下检查,至少在关键操作的时候有个照应。
5) 对于不确定的操作,不要直接按回车,如果命令行窗口卡住或者是不确定的时候,不要先按回车,因为你不知道上一个命令是不是具有破坏力,或者是屏幕处于锁屏状态,良好的职业习惯应该是先按空格而不是回车。
6)通常维护操作是比较平稳的,但是一旦发生问题,那就是紧急且重要的,这种情况下一定要沉住气,同时也要做好最坏的打算和预案。
7)大维护变更前不接受额外的变更需求,这个举一个例子,在一次大维护前2小时,开发团队提交了一个紧急修复,当时没有在生产完整的测试就匆匆列入了维护清单,结果整个维护中最让人头痛的就是那个新增变更,新增的存储过程执行了2个小时,而在这2个小时内我们想了无数的补救方案,而事后的分析和优化方案可以把这个逻辑优化到1分钟以内。所以按照维护流程,我们有足够多的理由可以拒绝这种加塞需求。
8)仪式感是我认为自己在大维护中最最重要的一个环节了,有多重要呢,我觉得准备工作做到万事俱备只欠东风的状态,那么剩下的只能靠运气了。而这个运气就需要自己的一种仪式感或者默认的习惯规则。我在大维护的时候会去买一瓶饮料,哪怕不喝也会备着,这是在早些年维护中自己的一点潜意识暗示或者说是必备的一种仪式。
当然大多数的维护都是默默无闻的,一切正常就是最好的回答。我喜欢平静夜晚后的清晨,阳光照进来,感觉一切都敞亮了。