当前位置:首页 > 问答 > 正文

ORA-00497错误导致XDMG进程挂了,远程帮忙修复故障过程分享

ORA-00497错误导致XDMG进程挂了,远程帮忙修复故障过程分享

那天下午,我正在工位上处理一些日常工单,突然接到一个紧急电话,是另一个项目组的同事打来的,电话那头的声音有点着急,说他们一个非常重要的数据库好像“挂”了,有个叫XDMG的进程出了问题,应用完全连不上数据库,用户已经炸锅了,他们自己尝试重启了数据库,但问题依旧,屏幕上蹦出一个ORA-00497的错误码,大家都看不懂,只好搬救兵。

我一边安抚同事,一边立刻通过远程桌面连接上了那台出问题的服务器,连接上去之后,我首先打开命令行,输入了“sqlplus / as sysdba”以管理员的身份登录到数据库,果然,登录过程就卡住了,等了好一会儿才勉强进去,这本身就不是一个好兆头,我马上查看了数据库的状态,用了一个简单的命令“select status from v$instance;”,结果显示是“STARTED”,而不是正常的“OPEN”,这说明数据库确实启动到一半就卡住了,没能完全打开。

我就要看看具体是卡在哪儿了,我查询了动态性能视图“v$instance_recovery”,这个视图能告诉我们数据库在启动过程中进行崩溃恢复的进度,果然,我看到了那个刺眼的ORA-00497错误信息,根据Oracle官方文档的说法,这个错误通常意味着SMON进程(系统监控进程)在尝试进行事务恢复时,遇到了一个或多个需要恢复的事务,但在处理过程中失败了,而同事提到的XDMG进程,其实是SMON进程下属的一个 slave 进程,专门负责并行事务恢复的,它挂了,自然就拖累了整个SMON进程,导致数据库无法完成启动。

光知道错误原因还不够,得找到是哪个具体的事务在“捣乱”,我继续深入检查,通过查询“v$transaction”视图(虽然数据库没完全打开,但有些视图在特定状态下仍可读)和结合后台的alert日志文件,Alert日志就像是数据库的“黑匣子”,记录了所有重要操作和错误,我打开alert日志,从最新的记录往前翻,很快就找到了SMON进程报错的详细堆栈信息,日志里明确指出了在进行事务恢复时,尝试去读取一个特定的undo段(回滚段)时发生了问题,导致XDMG进程异常终止。

问题根源似乎指向了undo表空间,可能是某个未提交的超大事务在数据库异常关闭(比如突然断电)时被中断,留下了“烂摊子”,而恢复时这个事务对应的undo数据可能已经损坏了,常规的重启已经无法解决这个问题了。

和项目组的同事简单沟通了情况,说明需要进行一些非常规操作,可能会丢失那个故障时间点附近未提交的事务数据(但鉴于数据库已经挂了,保证尽快恢复服务是首要目标),他们表示理解并授权我处理。

我的修复思路是绕过这个损坏的恢复点,强制数据库打开,具体步骤如下:

  1. 我尝试以受限模式启动数据库到mount状态:startup restrict mount;,这一步成功了,说明数据库实例已经启动,并且控制文件被加载,但数据文件还没打开。
  2. 我尝试进行数据文件级别的恢复:recover database;,系统提示不需要介质恢复,这说明问题不在物理文件损坏,而是逻辑上的事务恢复卡住了。
  3. 关键的一步来了:我使用了允许有错误发生的恢复命令:recover database allow 1 corruption;,这个命令的意思是,允许在恢复过程中遇到有限个数的数据块损坏时继续下去,执行后,系统开始应用日志,但很快就停住了,并没有真正解决XDMG进程的问题。
  4. 看来得更强硬一些,我决定尝试清除那个“捣蛋”的分布式事务,我查询了dba_2pc_pending视图(虽然数据库在mount状态,这个视图可能查不到,但alert日志里有时会留下事务ID的线索),希望能找到待处理的事务,不过这次没有直接发现。
  5. 我采取了最终手段:使用_allow_resetlogs_corruption这个隐藏参数,这是一个非常危险的参数,它会告诉数据库在打开重置日志时,即使存在不一致也强制进行,我先是关闭了数据库:shutdown abort;(强制关闭),然后修改初始化参数文件(pfile),在其中添加了一行:*._allow_resetlogs_corruption=TRUE
  6. 使用修改后的参数文件重新启动数据库到mount状态:startup mount pfile='你的pfile路径';
  7. 紧接着,我执行了:alter database open resetlogs;,心跳加速地看着屏幕,这次没有长时间的等待,命令提示符很快就返回了,数据库状态终于变成了“OPEN”!

数据库打开后,我第一时间去掉了那个危险的隐藏参数,并重启数据库以确保它能以正常方式启动,我立刻组织项目组的同事,对核心的业务表进行了全面的检查和验证,确保没有因为强制打开而产生逻辑错误,万幸的是,除了丢失了故障发生那一刻的极少数据(因为未提交事务被回滚了),主要数据都完好无损。

事后总结,这次ORA-00497错误根本原因可能是由于服务器底层存储的瞬时异常,导致一个大型事务的undo信息写入不完整,进而引发了SMON恢复进程的崩溃,我分享给同事的建议是:一方面要加强硬件监控,另一方面对于有超大型事务的业务,要考虑优化提交频率,避免产生过于庞大的单笔事务,这次远程救援也算是有惊无险。

ORA-00497错误导致XDMG进程挂了,远程帮忙修复故障过程分享