0

Oracle 数据库异常宕机错误分析:ORA-01092

2017-12-12
802

在数据库运维中,也许每一个DBA都很怕ORA-600,导致600错误的原因常常难觅踪迹,大部分情况下可能是由bug导致的,因此成为广大DBA的噩梦。

但是遇到ORA-600的机会并不会很高。根据Bethune智能诊断平台对于中国Oracle数据库用户使用现状分析报告,我们发现,实例异常宕机的相关错误总结如下:(图为2016年非完全统计结果,仅供参考)



从以上结果看出,I/O类报错和异常宕机相关性最⾼,内部错误(ORA-00600, ORA-07445)引发的实例异常宕机占⽐只有5%左右。


而很多错误,因其杀伤力不像600那么高,往往是被忽略的,也就导致了很多意料之外的故障。接下来我们一起来分析实例异常宕机的常见错误。


ORA-01092

官方文档描述为:

Description: ORACLE instance terminated. Disconnection forced

Cause:The instance this process was connected to was terminated abnormally, probably via a shutdown abort. This process was forced to disconnect from the instance.

Action:Examine the alert log for more details. When the instance has been restarted, retry action.


实例异常终止,连接断开。这个错误之所以占的比例最大,是因为与其说它是错误的原因,倒不如说是结果。因为各种原因都有可能会导致实例终止。


常见的场景有:数据库启动时;使用备份进行恢复时;使用resetlog跳过数据库的启动检查时;DBCA创建数据库的时候等。


导致实例异常终止的原因可能有很多种,这些原因可以大致分为两类。

  • 一类是外部原因,或者称为主动原因,比如人为地执行了shutdown abort导致,或者任何跟shutdown属性一样的动作,比如断电,断网,线路被挖断等。

这类原因一般可以很快找到根源,并且由于上述原因导致的问题一般影响面积较大,很少是单一系统或者单一实例。


  • 另一类原因就是内部原因,由于数据库本身的异常导致的实例终止。那么内部原因可能有哪些呢?根据我们的经验,导致ORA-01092错误引发实例终止的原因包含以下几种情况:

1、数据文件错误或异常离线
2、密码文件orapw错误

3、用旧版本的备份做数据库恢复

4、在使用Automatic Undo Management 时,undo表空间不存在或者类型错误


接下来,我们针对每一种原因进行深入分析:

1、数据文件错误或者异常离线

我们知道,数据文件的写入是由DBWn进程来完成的,但整个写入过程,涉及到的进程是很多的。


数据文件的写入过程是这样的:

当用户需要对数据做修改时,首先用户进程会从前端发出数据写入请求,之后要通过操作系统的信号量完成对数据库进程也就是DBWn的通知,通知完成以后,DBWn进程获取CPU资源进行写入,进入真正的物理IO的时间,写入完成后,DBWn进程被唤醒,并通知前台进程。


那么,假如需要写入数据的文件异常离线或者故障,总之不能正常写入数据的时候,DBWn进程可能不会被唤醒而出现异常,同时,前端的用户已进程迟迟接收不到DBWn的返回通知,也可能会出现异常。而我们知道,DBWn进程在数据库中是核心进程,这时候,很可能会导致数据库直接中断。


同时,在10g以后,引入的MMON进程用于监控数据库和实例的状态,当它发现DBWn进程可能出现故障的时候,会发出错误信号或通知,并将这些错误记录到alert.log当中。


因此,如果是数据文件异常离线或者写入错误引发的ORA-01092的话,一般在数据库中我们会发现以下一些错误信息:

  • 操作系统层面(OS日志)

Description 
USER DATA I/O ERROR 

Probable Causes 
ADAPTER HARDWARE OR MICROCODE 
DISK DRIVE HARDWARE OR MICROCODE 
SOFTWARE DEVICE DRIVER 
STORAGE CABLE LOOSE, DEFECTIVE, OR UNTERMINATED



操作系统进程的错误会同时被记录到数据库的trace文件当中。

Taking over instance termination because the instance terminator (ospid: 2191470) is dead 
kjzduptcctx: Notifying DIAG for crash event 
----- Abridged Call Stack Trace ----- 
ksedsts()+644<-kjzdssdmp()+444<-kjzduptcctx()+272<-kjzdicrshnfy()+96<-ksuitm()+1284<-ksuitr()+92<-ksu_dispatch_tac()+372<-kdifxs1()+468<-kdifxs()+28<-qerixtFetch()+940
<-qerilFetch()+276<-opifch2()+7136<-opifch()+60<-opiodr()+3608<-rpidrus()+536<-skgmstack()+208 
<-rpidru()+144<-rpiswu2()+1124<-rpidrv()+2892<-rpifch()+80 
----- End of Abridged Call Stack Trace ----- 

*** 2016-11-02 06:29:56.242 
USER (ospid: 643220): terminating the instance due to error 1092


  • 数据库进程

DBWn进程的写入错误,会被MMON进程监控到并写入到MMON进程的trace文件当中。

Unix process pid: 1949800, image: oracle@prdserver (MMON) 
*** 2016-11-02 06:23:43.879 
Taking over instance termination because the instance terminator (ospid: 2875438) is dead 
===> 2875438 is the OS PID of DBW0 process which encountered the I/O error and is dead.


  • 数据库告警日志

Wed Nov 02 06:23:51 2016
Non critical error ORA-00001 caught while writing to trace file "/opt/diag/rdbms/prd1/PRD1/trace/PRD1_arc1_2076702.trc"
Error message: IBM AIX RISC System/6000 Error: 5: I/O error
Additional information: 1
Writing to the above trace file iWed Nov 02 06:29:56 2016
USER (ospid: 643220): terminating the instance due to error 1092
Wed Nov 02 06:29:56 2016
ORA-1092 : opitsk aborting process
Instance terminated by USER, pid = 643220


在alert.log中则显示出由于前端用户进程的错误而导致的实例终止。


注:以上的错误信息会因操作系统不同,版本不同,文件管理方式不同有差异。


如果怀疑是数据文件异常导致,可以通过以下语句首先对数据文件的状态进行确认:

SQL>select file#,status,name from v$datafile where status not in ('system','online');


如果有数据文件处于offline状态,则首先修改数据文件的状态,并再次打开数据库。(数据文件离线的原因和解决办法涉及到的内容比较复杂,需要具体情况具体分析,此处不做展开)。


简单的处理方案:

1)将数据库开启到mount状态,将offline状态的数据文件修改为online:

SQL> startup mount;

SQL>alter database datafile n online;

2)恢复数据库:

SQL> recover database;

3)打开数据库到open状态:

SQL> alter database open;


2、密码文件orapw错误

Oracle密码文件是对sysdba和sysoper等高系统权限用户密码进行管理的一个载体。在文件系统中是一个封闭的二进制文件,一般是没有办法看到其中的数据的。


但通过视图v$pwfile_users,我们可以看到当前密码文件其中包括的超级用户。同时,如果我们显式地进行sysdba和sysoper权限的赋予,Oracle自动的将用户的信息添加到密码文件中。


我们知道,密码文件用于数据库用户连接数据库过程中的验证。 但用户进入数据库以后,一般是不会对数据库产生任何影响的。那么,什么时候会因为密码文件导致数据库的IO错误?


由于数据库中的密码文件是可以重置的,也就是可以在数据库使用一段时间后 通过工具或者脚本的方式进行重新配置和创建,比如orapwd工具。但是,创建密码文件的时候,其中只会包括sys用户的信息,其他所有sysdba、sysoper和sysasm权限的用户不会被添加到文件中,因此,重置密码文件以后,用户的sysdba、sysoper和sysasm权限被剥夺。


如果在用户执行某些操作的时候,数据库的密码文件被重置,此时失去权限的用户不能正常地进行操作,就极有可能发生故障。当然如果是由于密码文件重置导致的数据库故障,那么在告警日志中,很有可能出现"insufficient privileges"等信息。


另外一种情况,重置密码文件以后,如果我们删除了原来位置上的密码文件,当部分用户需要再次连接的时候,就看找不到对应的密码文件到引发ORA-01092的错误,当然此时还会伴随ORA-01990的错误:error opening password file $ORACLE_HOME/dbs/orapw.


处理方案:

重置密码文件之前,确认当前的配置,并手动赋予权限;重新生成的密码文件的位置保持不变,确保用户能够正常访问。


3、用旧版本的备份做数据库恢复


在使用旧版本的备份进行恢复的时候,可能会导致1092的错误。如果在数据库open的状态做恢复的操作,就会导致1092的错误,如果是非open的状态,很可能打不开。


遭遇该错误可能的错误代码如下:

ORA-00704: bootstrap process failure
ORA-39700: database must be opened with UPGRADE option
....
ORA-01092: ORACLE instance terminated. Disconnection forced

因此在做数据库升级的时候,在必要的步骤都要通过upgrade选项来应用旧版本中的数据。否则升级完成后数据库很可能不能以read-write的模式打开。


在这种情况下,做不完全恢复的语句为:

SQL>  alter database open resetlogs upgrade;


如果由于没有提供upgrade参数导致1092错误,处理步骤如下:

场景假设:在升级的过程中,没有进行upgrade恢复。在restore和recovery之后,直接尝试打开数据库:


SQL> alter database open resetlogs;

此时便会引发1092的错误。并且在alert.log日志中将会出现:

ORA-39700: database must be opened with UPGRADE option error.


首先我们尝试用upgrade选项打开数据库,由于之前发生1092错误,因此执行以下命令必须退出SQLplus并重新打开开启新的会话。

SQL> startup upgrade;


之后根据版本升级的readme文件,使用upgrade选项执行必要的恢复步骤。(也就是说,在升级的过程中使用upgrade选项是必须的,要使得数据库正常运行就必须要执行)


之后回到刚才的窗口,重启数据库:

SQL> shutdown immediate;
SQL> startup


4、在使用Automatic Undo Management 时,undo表空间不存在或者类型错误

在数据库启动的时候可能会遇到如下的情况:


    SQL> startup
    ORACLE instance started.

    Total System Global Area  252478536 bytes
    Fixed Size                   279624 bytes
    Variable Size             167772160 bytes
    Database Buffers           83886080 bytes
    Redo Buffers                 540672 bytes
    Database mounted.

    ORA-01092: ORACLE instance terminated. Disconnection forced

在最后从mount到open的过程出现错误而强行终止。

在数据库的启动过程中,当mount阶段就可以读取控制文件,控制文件中记录了数据文件的头部检查点信息,因此在open的时候,需要匹配控制文件中记录的数据文件头部SCN与控制文件中的记录信息,一致才可以打开数据库。


如果数据库的参数文件中将undo_management参数设置为AUTO,而此时找不到undo表空间对应的文件或者类型不属于undo的话,此时就会发生错误。


此时查看alert.log,可能会出现以下报错信息:

   SMON: enabling cache recovery
    Thu Aug  2 14:19:45 2001
    Errors in file ora/ora901/admin/V901/udump/v901_ora_21863.trc:
    ORA-30012: undo tablespace 'UNDO1' does not exist or of wrong type
    Thu Aug  2 14:19:45 2001
    Error 30012 happened during db open, shutting down database
    USER: terminating instance due to error 30012
    Instance terminated by USER, pid = 21863
    ORA-1092 signalled during: ALTER DATABASE OPEN...


针对不同的情况,有两种不同的解决方案:

1、如果undo 表空间是存在的,但undo_tablespace中指向不对,那么可以将参数重新设置使其指向到正确的undo tablespace,然后重启数据库。


注意此时数据库处于mount状态,如果参数文件正在使用状态,不要直接编辑参数文件避免出错。要将数据库退回到Nomount状态,然后执行 create pfile from spfile,修改完成之后再 create spfile  from pfile。


2、如果undo表空间不存在,首先通过上述建议方式将参数文件中的undo_management参数修改为 manual。之后当数据库open之后,创建undo 表空间,修改参数文件中undo tablespace的指向到正确的表空间,同时将undo_management修改为AUTO。重启数据库使其生效。





最后修改时间:2020-05-07 23:27:13
「喜欢文章,快来给作者赞赏墨值吧」
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论