轉至老熊三分地--inside sqlplus prelim

wengtf發表於2012-01-26
在Oracle 10g中,如果資料庫例項hang住了,應用及sqlplus都不能連線時,可以用sqlplus -prelim連線資料庫。那麼sqlplus連線時,加上-prelim這個引數有什麼特別的地方呢?下面,讓我們來研究一下:

測試環境:Linux AS4上的Oracle 10.2.0.1,客戶端(sqlplus)版本為Windows 2003下的10.2.0.1。

首先在資料庫上啟用10046事件:

SQL> alter system set events ‘10046 trace name context forever’;

System altered.

先用普通的方式連線:

D:\>sqlplus /nolog

SQL*Plus: Release 10.2.0.1.0 - Production on 星期六 11月 15 15:36:02 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

SQL> conn sys/manage@xty as sysdba
已連線。
SQL> exit
從 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options 斷開

再看看加prelim引數時的情況:

D:\>sqlplus -prelim /nolog

SQL*Plus: Release 10.2.0.1.0 - Production on 星期六 11月 15 15:36:34 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

SQL> conn sys/manage@xty as sysdba
初級連線已建立
SQL> exit
從 ORACLE 斷開

從上面的資訊可以看到,在使用prelim連線時,提示為“初級連線已建立”,退出sqlplus沒有顯示banner。
也可以通過下面的方式來用prelim方式連線資料庫:

[oracle@xty ~]$ sqlplus /nolog

SQL*Plus: Release 10.2.0.3.0 - Production on Tue Dec 2 07:04:28 2008

Copyright (c) 1982, 2006, Oracle. All Rights Reserved.

SQL> set _prelim on
SQL> connect / as sysdba
Prelim connection established

再看看資料庫的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

而sqlplus使用prelim連線上資料庫後,沒有生成10046 trace檔案,看起來沒有執行SQL,也就是沒有執行任何初始化動作和查詢必要的資訊。也許這也就是稱之為“初級連線”的來歷吧。

由於使用prelim方式連線,沒有執行sql語句的,所以在資料庫的某些hang住的情況下,能夠連線上資料庫。比如由於library cache latch 被長時間持有不能釋放,不能解析SQL語句引起的hang。有的人會說,我的應用剛連上去還沒做任何操作就hang住了。這只是表面現象,連線上資料庫後,一般都會做一些初始化的操作,如設定環境之類的。

sqlplus -prelim能夠在資料庫hang住的情況下連線資料庫,但只能說是連線,並不代表能夠做很多操作。比如執行SQL查詢。這種情況下,可能最有用的就是使用oradebug。

本文只是簡單地“inside”,其實並不很深入,Oracle還會有其他的跟prelim有關的東西,是我們還沒發現的。有興趣的朋友,可以進一步研究。比如通過抓取tns包進行分析等等。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22907091/viewspace-715190/,如需轉載,請註明出處,否則將追究法律責任。

相關文章