很多情况下,Oracle hang导致sqlplus无法连接,从而无法获得Oracle系统和进程状态,使得定位问题缺少强有力的依据。从 Oracle10g 开始, sqlplus 提供了-prelim选项,在系统已经hang的时候可以连接到 SGA 而不是数据库,也就是说没有 session 被创建。从而在Oracle挂起时依然能获得数据库状态。
一、 主要用法
sqlplus -prelim "/as sysdba"
在prelim模式下,不可以查询数据字典,但可以关闭数据库
SQL> select status from v$instance;
select status from v$instance
*
ERROR at line 1:
ORA-01012: not logged on
可以使用oradebug,对于系统诊断,已经足够了
dump系统状态
SQL> oradebug setmypid
Statement processed.
SQL> oradebug unlimit
Statement processed.
SQL> oradebug dump systemstate 266
Statement processed.
dump hanganalyze
SQL> oradebug hanganalyze 3
Hang Analysis in /oracle/app/oracle/admin/ora10g/udump/ora10g_ora_52642.trc
对于RAC
SQL> oradebug setmypid
SQL> oradebug setinst all
SQL> oradebug -g def hanganalyze 3
dump 进程状态
SQL> oradebug dump processstate 10
Statement processed.
强行关闭数据库
SQL> shutdown abort
ORACLE instance shut down.
二、 prelim 参数特点
1. 在数据库上启用10046事件
SQL> alter system set events ‘10046 trace name context forever’;
System altered.
2. 先用普通方式连接
sqlplus /nolog
SQL*Plus: Release 11.1.0.6.0 – Production on Tue Feb 23 13:21:59 2010
Copyright (c) 1982, 2007, Oracle. All rights reserved.
idle> conn / as sysdba
Connected
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
3. 加prelim参数连接
sqlplus -prelim /nolog
SQL*Plus: Release 11.1.0.6.0 – Production on Tue Feb 23 13:30:16 2010
Copyright (c) 1982, 2007, Oracle. All rights reserved.
idle> conn / as sysdba
Prelim connection established
ERROR:
ORA-01012: not logged on
Process ID: 0
Session ID: 0 Serial number: 0
idle> exit
Disconnected from ORACLE
从上面的信息可以看到,在使用 prelim 连接时,提示为“初级连接已建立”,退出 sqlplus没有显示 banner。
也可以通过下面的方式来用 prelim 方式连接数据库:
sqlplus /nolog
set _prelim on
connect / as sysdba
Prelim connection established
4. 查看数据库10046 trace
从trace文件中可以发现在正常连接时,连接上数据库后, sqlplus自动执行了下面的SQL:
ALTER SESSION SET NLS_LANGUAGE='SIMPLIFIED CHINESE' NLS_TERRITORY='CHINA' NLS_CURRENCY= '¥' NLS_ISO_CURRENCY='CHINA' NLS_NUMERIC_CHARACTERS='.,' NLS_CALENDAR='GREGORIAN' NLS_DATE_FORMAT='DD-MON-RR' NLS_DATE_LANGUAGE='SIMPLIFIED CHINESE' NLS_SORT='BINARY' TIME_ZONE='+08:00′ NLS_COMP='BINARY' NLS_DUAL_CURRENCY='¥' NLS_TIME_FORMAT='HH.MI.SSXFF AM' NLS_TIMESTAMP_FORMAT='DD-MON-RR HH.MI.SSXFF AM' NLS_TIME_TZ_FORMAT='HH.MI.SSXFF AM TZR' NLS_TIMESTAMP_TZ_FORMAT='DD-MON-RR HH.MI.SSXFF AM TZR'
select value$ from props$ where name ='GLOBAL_DB_NAME'
select SYS_CONTEXT('USERENV','SERVER_HOST'),SYS_CONTEXT('USERENV','DB_UNIQUE_NAME'),SYS_CONTEXT('USERENV','INSTANCE_NAME'),SYS_CONTEXT('USERENV','SERVICE_NAME'),INSTANCE_NUMBER,STARTUP_TIME,SYS_CONTEXT('USERENV','DB_DOMAIN') from v$instance where INSTANCE_NAME=SYS_CONTEXT('USERENV','INSTANCE_NAME')
select decode(failover_method,NULL,0,'BASIC',1,'PRECONNECT',2,'PREPARSE',4,0),decode(failover_type,NULL,1,'NONE',1,'SESSION',2,'SELECT',4,1),failover_retries,failover_delay,flags from service$ where name = :1
而使用prelim 连接上数据库后,没有生成 10046 trace 文件,没有执行SQL,也就是没有执行任何初始化动作和查询必要的信息。也许这就是称之为“初级连接”的原因吧。
由于使用prelim方式连接没有执行sql语句,所以在某些数据库hang住的情况下,能够连接上数据库。比如由于library cache latch被长时间持有不能释放,不能解析SQL语句引起的hang。有的人会说,我的应用刚连上去还没做任何操作就 hang 住了。这只是表面现象,连接上数据库后,一般都会做一些初始化的操作,如设定环境之类的。
以上来自《Oracle运维最佳实践》