日期:2014-05-16  浏览次数:20525 次

How to log on when SYSDBA can't connect the db?
有时候应用打电话,数据库已经Hang了,我们以DBA角色去登录的时候都无法登录,这时候该怎么办。通常,比如当归档异常,普通用户或者具有DBA角色的用户都无法登录,
这是因为通常当新的session创建一个connection的时候,会产生审计记录,那么就需要更新SEQ$表。那么这时候任何DML都将被阻塞,除非归档异常被解决或者正常。
但是,SYSDBA用户是任然能够登录,这是因为SYSDBA连接在数据库表中不产生审计记录(也就是为什么audit_file_dest目录里面是SYSDBA审计文件被写入的地方)。
但有时候也有BUG,导致SYSDBA无法登录,忽略不论……
正常情况下我们以SYSDBA登录会发生以下情况:
1,建立新的oracle进程。
2,新的oracle进程attache共享内存结构在SGA中。
3,新的oracle进程分配进程和session的状态对象结构以及在SGA中初始化新session。
或许有时候在步骤3中,数据库要分配内存结构,如果某些mutex或者latch异常,就可能导致无法连接,oracle有类似的bug。

下面用这种方式登录:

$ sqlplus -prelim "/as sysdba"
SQL*Plus: Release 11.2.0.1.0 Production on Sat Jul 7 09:34:19 2012
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
SQL> 
登录选项-prelim意味着“preliminary connection”,也就是sqlplus登录其实只完成如上步骤的2,并不执行第三个步骤。
上次由于某库Hang(那个库是开放给用户的,没有规则,上面干啥的都有,所以Hang了就打算直接干掉一个节点),如果是RAC,那么以SYSDBA
无法登录,你也可以直接通过此命令:
srvctl stop instance -d zjcb -n zjcba1 -o abort 停掉某节点。
当我们以-prelim选项登录数据库后,如果执行查询,会出现神马情况:

SQL> select event,count(*) from v$session;
select event,count(*) from v$session
*
ERROR at line 1:
ORA-01012: not logged on
Process ID: 0
Session ID: 0 Serial number: 0

SQL> select count(*)from dba_objects;
select count(*)from dba_objects
*
ERROR at line 1:
ORA-01012: not logged on
Process ID: 0
Session ID: 0 Serial number: 0
看到没有,实际上我们没有真正的登录系统,因为没有完成第三个步骤,所以没有建立查询执行所需要的环境。
那么这时候,我们需要做的就是Hanganalyze和Systemstate,看如下操作:

Hanganalyze:
SQL> oradebug setmypid
Statement processed.
SQL> oradebug unlimit
Statement processed.
SQL> oradebug hanganalyze 3
Statement processed.
Systemstate:
SQL> oradebug dump systemstate 266 
Statement processed.
当然对于大内存的系统,systemstate还是要谨慎,因为很可能出不来结果,而且CPU超高。
最后说明下,-prelim选项是在Oracle 10g的sqlplus里提供的,当然我们可以使用Oracle 10g+的sqlplus远程连接到9i的库,
sqlplus -prelim "sys/password@service_name as sysdba"
当然以-prelim选项登录后,你可以执行shutdown之类的操作了……

SQL> shutdown abort
ORACLE instance shut down.