NinGoo@Itpub

暂无签名

  • 博客访问: 563760
  • 博文数量: 364
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-29 20:11
个人简介

暂无介绍

文章分类

全部博文(364)

文章存档

2008年(5)

2007年(164)

2006年(149)

2005年(45)

2004年(1)

我的朋友

分类: Linux

2008-06-12 15:13:48

DBA未必是一个高薪的职业,但绝对是一个高压力的职业。

昨天晚上(2008-2-23),数据仓库一个4节点的RAC+ASM系统,在进行新加节点操作的时候,发现新节点的ASM实例无法mount diskgroup,报ORA-15042错误。后来尝试将整个库重启,结果所有节点的ASM实例都出现同样的问题了。这个教训告诉我们,在遇到问题没有搞清楚具体原因之前,千万不要轻易重启数据库。

但是问题既然已经发生,自然要想办法修复。这是一个将近7T的生产系统,虽然目前只供内部使用,也不可能接受长时间的停机,所以重建diskgroup然后从备份恢复的方案只能是最坏情况下的打算。那么,当务之急,是要尽快查出问题所在,对症下药。

工欲善其事,必先利其器。这次问题的解决,得益于oracle的kfed工具。从dump出来的结果看到,报错的两个disk的头信息确实已经损坏,另外一点比较奇怪的就是,正常disk header中记录的disk number和path信息,和从v$asm_disk查出来的已经不一致了。这个现象可能由于两个disk的头信息损坏,导致AMS Instance读取相关信息的整个机制出现了混乱。

首先将两个损坏的disk通过dd做一个完整的备份。另外一方面,流云也通过metalink开了一级tar,并且直接电话找oracle的相关支持人员调动资源帮助解决问题,事实证明,虽然对于紧急故障处理的速度可能不是足够快,因为他们不了解系统相关情况,需要花很多时间来问一些相关的问题等等。但是oracle拥有足够的文档资源,这也为最终解决问题打下了基础。当然,文档只是提供了方向和思路,而且往往不同的两个文档之间还会有矛盾之处,这些都需要根据情况来做出修正。

从oracle得到的一份文档记录了一个相似的案例,并且也是通过kfed工具修复了disk header而最终解决了问题,这给了我们足够的信心。拖雷和七公在家里也连上来和我们一起来分析如何修复损坏的disk header,根据dump出来的正常disk的头信息很快算出来两个异常disk的头信息,然后通过kfed将信息merge进去,满怀希望的重启ASM Instance,靠,问题依旧。

仔细比对文档,发现刚才没有去改时间截。时间截的信息,除了在每个disk header中保存,还会在集中保存在disk directory中。那么首先要找到这个disk directory。而disk directory的地址又保存在一个起始磁盘的某个AU上。所以就要找到这个file1block1的disk,也就是kfdhdb.f1b1locn 的值不为0的disk,通过一个个disk header的查找可以确定。当然,这次我们比较幸运,坏的两个disk不是f1b1,否则可恢复的机会就要大打折扣,时间上也会拉长很多,因为可能需要扫描整个disk去查到保存在disk其他位置的file directory信息,能找到还好,找不到就彻底没戏,只能重建了。

通过f1b1的AU2 block4中的指针(大多数情况下在这个位置,但并不保证),找到disk directory对应disk的时间截,当然,这个过程说起来一句话,实际上花了相当长的时间,其中还隐藏了很多细节,呵呵。处理这种问题,一个人真的很难搞定,因为基本都是internal的东西,之前从来都没有任何经验,只能靠一点点的蛛丝马迹去不同的猜测、验证,一个人的话就很容易走入死胡同,幸好我们是团队作战。

历经艰难找时间截信息,马上merge进去重试。My God,还是不行。这个时候已经是到凌晨了,从早上9点上班算起,已经连续工作了15个小时以上了,而且似乎坏事总是喜欢扎,中间还处理了另外一个备库文件创建失败的故障,还有个主机的一块盘也坏了,当然是镜像过的,问题不大,保修一下就好。到洗手间洗个脸,清醒一下。另外最坏的方案也开始做准备了,要是一两个小时内问题还是无法解决,就只能全库恢复了。

时间一点点过去,压力越来越大,脑子的运转也越来越慢。其实从dump出来的星期可以看到,disk header中的东西并不多,基本上就是四五处地方不一致需要修改的。那么为什么修改后还是不成功呢?再从头仔细的比对正常和修复过的disk header信息,发现check校验值是不一样的,而几个正常的disk都是同一个值。一般来说校验值应该是通过计算得到,所以check值没法通过 merge导入,那么只有手工强行更改了来试试是否可行了。事实证明,这是行不通的。但是,这次尝试也露出了一点点希望的曙光。之前merger后从v$ asm_disk.header_status看这两个盘的值一直都是INCOMPATIBLE,而这次终于有了变化,变成PROVISIONED。虽然 diskgroup依旧不能mount,心里还是觉得这条路是能走通的。

晚上原计划要将一个库rebuild几个索引到新的磁盘上以分布IO压力的,先把这个命令下了再说。回头再来想,为什么check会不正确呢?说明 check的计算,不但跟dump出来的那些值相关,跟头部中的其他一些位应当也是相关的,而这些位通过dump是看不到的。于是用od直接看16进制的值,通过比较发现很多在正常的disk header中全0的地方,在损坏的两个盘中都是有值的,莫非问题就出在这里?狠一点,将前面4k的头部全部用dd清零,然后重新merge。谢天谢地,diskgroup正常mount上了,oh,yeah!这个时候虽然已经凌晨4点了,因为持续的紧张和熬夜,我们都是面容疲倦,但是问题最终得到解决,还是相当的激动,流云同学甚至一拳打在椅背上将手都打出血来了^_^

做完一些善后工作,外面公交车在开始高叫“行人车辆请注意安全”了。再回头看这个晚上,其实中途好多次都想放弃了,一次次的失败真的让人非常的沮丧,而且周三的晚上才做了一次维护,疲劳状态下很多处理其实做得都不好,走了很都的弯路。也许很多事情都是这样,在你即将绝望放弃的时候,其实离最终的终点已经非常非常的接近,只要再坚持一下,但是这一下,又谈何容易呢。

Itpub在搞“Oracle DBA故事会”征文,想了想,4个月前的这次事故还是印象深刻,再翻出来看看吧,不知道旧文章算不算,呵呵,算的话也凑个数
阅读(1810) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册