一則資料庫無法啟動的奇怪案例分析

dbhelper發表於2016-04-27

關於資料庫的啟停,以前一直認為是最簡單,最沒有技術含量的任務,但是接手的環境越多,越來越證明我最初的想法是錯誤的。資料庫的啟停是一個敏感操作,重啟一定是有著特定的原因和需求。而且這個過程中存在這太多的可能性,很可能在同一會話視窗中,停掉資料庫再次啟動就會報錯;很可能硬體擴容,也會導致資料庫例項無法啟動;這個時候重啟前的準備和分析就尤為重要。

在此大體把啟停中的問題歸為三類,資料庫無法啟動,資料庫無法登入,資料庫當機。我們在此主要討論資料庫無法啟動的場景。

看起來很簡單的一件事情,重啟的過程中總是可能節外生枝,總是感覺資料庫例項有時候不是那麼配合,總是在啟動過程中會發牢騷。從我的經歷來看,我碰到的絕大多數問題都發生在open階段。

對於資料庫無法啟動的原因大體有以下幾個方面需要考慮。

1)      系統核心引數設定不當,比如當前的核心引數設定在需要增加資料庫級的配置的情況下是否能夠滿足,或者在硬體擴容的情況下,現有的核心引數是否需要做相應的調整。舉個例子,之前看到一個資料庫環境中的記憶體為16G,但是實際上process只設定了150,很明顯可以充分利用這部分資源, 在申請維護視窗重啟的過程中,發現調整了process大小之後,資料庫例項無法啟動,根本原因就是核心引數shmmax設定過低導致。

2)      資料庫引數變數設定不當,資料庫引數或者變數的一些設定可能會和現有的資源使用情況衝突,在這種情況下,資料庫引數的設定很可能過高或者過低,導致硬體資源的使用無法滿足。比如資料庫層面的process大小還是需要和系統核心引數有一個對映,設定不能太高。

我們以一個真實的案例來說明,這是我接手的一套測試環境。這是一套11gR2的環境。

當我準備連線到環境的時候,首先檢視資料庫的程式情況。

可以看到目前的環境存在兩個資料庫例項newtesttest04,在此我們需要連線newtest.

$ ps -ef|grep smon

oracle    1451     1  0 Feb02 ?        00:00:30 ora_smon_newtest

oracle    9133     1  0 Feb03 ?        00:00:58 ora_smon_test04

oracle   24734 24596  0 17:36 pts/0    00:00:00 grep smon

但是使用sqlplus登入的時候卻碰到了一個非常奇怪的問題。

$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Wed Feb 17 17:36:08 2016

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

Connected to an idle instance.

SQL>

按理說應該直接使用sys使用者連線到了資料庫例項,但是在此卻顯示是一個空例項。這到底是哪裡出了問題呢。首先排除了ORACLE_SID大小寫,亂碼的問題。

檢視資料庫日誌也沒有發現任何異常資訊,例項還是active的。

在此我們先賣個關子,繼續往下看。

因為是測試環境,所以也可以做一些簡單的嘗試,於是我就嘗試啟動資料庫例項。

Nomount階段竟然沒有報出任何的錯誤。

SQL> startup nomount

ORACLE instance started.

Total System Global Area 4993982464 bytes

Fixed Size                  2261808 bytes

Variable Size            1006636240 bytes

Database Buffers         3976200192 bytes

Redo Buffers                8884224 bytes

這個時候都有些懷疑是否之前的分析是正確的。

繼續把例項置為mount階段,這個時候就丟擲了下面的問題。

SQL> alter database mount;

alter database mount

*

ERROR at line 1:

ORA-00205: error in identifying control file, check alert log for more info

這個時候,檢視日誌就是一個很好的辦法,在11g中可以使用adr的方式來檢視,或者使用下面的方式來直接找到日誌所在目錄。

SQL> show parameter background_dump_dest

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

background_dump_dest                 string      /U01/app/oracle/diag/rdbms/new

                                                 test/newtest/trace

得到的日誌如下:                                                 

MMNL started with pid=16, OS id=24683

starting up 1 dispatcher(s) for network address '(ADDRESS=(PARTIAL=YES)(PROTOCOL=TCP))'...

starting up 1 shared server(s) ...

ORACLE_BASE from environment = /DATA/app/oracle

Wed Feb 17 17:36:21 2016

alter database mount

ORA-00210: cannot open the specified control file

ORA-00202: control file: '/U01/app/oracle/fast_recovery_area/newtest/control02.ctl'

ORA-27086: unable to lock file - already in use

Linux-x86_64 Error: 11: Resource temporarily unavailable

Additional information: 8

Additional information: 1449

ORA-00210: cannot open the specified control file

ORA-00202: control file: '/U01/app/oracle/oradata/newtest/control01.ctl'

ORA-27086: unable to lock file - already in use

Linux-x86_64 Error: 11: Resource temporarily unavailable

Additional information: 8

Additional information: 1449

ORA-205 signalled during: alter database mount...

透過上面的錯誤資訊可以很清晰看到控制檔案已經被佔用了。

這個時候檢視資料庫例項的情況,發現結果讓人大跌眼鏡,竟然有兩個例項為newtest.

[oracle@BX_133_45 trace]$ ps -ef|grep smon

oracle    1451     1  0 Feb02 ?        00:00:30 ora_smon_newtest

oracle    9133     1  0 Feb03 ?        00:00:58 ora_smon_test04

oracle   24677     1  0 17:36 ?        00:00:00 ora_smon_newtest

oracle   24734 24596  0 17:36 pts/0    00:00:00 grep smon

那麼這個問題該怎麼解釋呢,Unix,Linux系統中,SIDORACLE_HOME在一起雜湊後會得到一個唯一的值作為SGAkey

oracle例項啟動時,在作業系統上的fork程式會根據Oracle_SID來建立相關後臺程式。

Oracle 11g 支援Oracle_SID的長度為12位,db_name的長度為8位。而在很早的版本中ORACLE_SID只支援4位,這也就是我們經常看到ORCL,PROD這樣的資料庫的一個原因吧。

在這個場景中,ORACLE_SID沒有任何問題,那麼仔細來品味上面的話,另外一個可能就是ORACLE_HOME了。 

我們首先把剛剛沒有啟動的例項先停掉,避免有更多的干擾。

檢視共享記憶體段的情況如下,可見資料庫例項還是沒有受到影響。                                           

$ ipcs -m

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status     

0x00000000 1114113    oracle     640        33554432   23                     

0x00000000 1146882    oracle     640        4982833152 23                     

0x849f1498 1179651    oracle     640        2097152    23                     

0x00000000 3211268    oracle     640        33554432   23                     

0x00000000 3244037    oracle     640        4982833152 23                     

0x9d2300b0 3276806    oracle     640        2097152    23                     

這個時候再次觀察例項的smon程式,發現原來的程式依然存在。

$ ps -ef|grep smon

oracle    1451     1  0 Feb02 ?        00:00:30 ora_smon_newtest

oracle    9133     1  0 Feb03 ?        00:00:58 ora_smon_test04

oracle   24779 24596  0 17:37 pts/0    00:00:00 grep smon

再次確認ORACLE_SID

$ echo $ORACLE_SID

newtest

確認ORACLE_HOME

$ echo $ORACLE_HOME

/DATA/app/oracle/11.2.0.4

好了,我們來開始分析,

找到系統級所在的控制程式碼,根據smon程式對應的程式號1451/proc/1451下面,檢視environ的設定情況,可以使用下面的方式來檢視這個程式對應的環境變數ORACLE_HOME

$ cat /proc/1451/environ|xargs -0 -n1 |grep ORACLE_HOME

ORACLE_HOME=/U01/app/oracle/product/11.2.0.2/db_1

這個時候真相浮出水面,原來是ORACLE_HOME設定不同。

手工指定ORACLE_HOME,然後再次嘗試

$ export ORACLE_HOME=/U01/app/oracle/product/11.2.0.2/db_1

$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Wed Feb 17 17:49:00 2016

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

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

這個時候就達到了預期的效果

SQL> select database_role from v$database;

DATABASE_ROLE

----------------

PRIMARY

透過這個案例可以發現,在環境維護中需要遵循一定的規範,如果不嚴謹不規範,就會出現一些看似奇怪的問題;對於資料庫例項的啟動過程需要有深刻的理解,需要不斷的反問自己為什麼,怎麼求證,能夠說服自己才能讓別人信服。

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

相關文章