從一種強制停庫方法到Oracle NFS檔案鎖

realkid4發表於2012-02-22

 

今天在QQ技術群中,一個朋友介紹了一種快速停庫重啟的方法。筆者感覺有必要研究重演一下,供來日不時之需。

 

1、問題簡介

 

事情的起源是這樣,一個朋友需要修改processes引數,重新啟動資料庫。但是因為各種原因,不能登陸入sqlplus。他希望能有解決問題的方法。於是,QQ群中另一個朋友提出一種快速重新停止庫的方法。

 

簡單的說,在Linux/Unix環境下,將$ORACLE_HOME/dbs目錄下的lk檔案更名刪除。之後就可以重新啟動。

 

2、原理分析

 

這個lk檔案是什麼呢?在筆者虛擬機器環境下,也找到了相應的檔案。

 

 

[oracle@oracle11g dbs]$ cd $ORACLE_HOME/dbs

[oracle@oracle11g dbs]$ pwd

/u01/oracle/dbs

[oracle@oracle11g dbs]$ ls

hc_DBUA0.dat   init.ora        lkWILSON     peshm_DBUA0_0   snapcf_wilson.f

hc_wilson.dat  initwilson.ora  orapwwilson  peshm_wilson_0  spfilewilson.ora

 

 

強制開啟檔案,可以看到如下提示。

 

 

oracle@oracle11g dbs]$ cat lkWILSON

DO NOT DELETE THIS FILE![oracle@oracle11g dbs]$

 

 

MOS中,我們找到了一些關於lk檔案的資訊。

 

大部分和lk檔案相關的資訊都是和啟動資料庫時候獨佔檔案有關的。出現最多的問題就是在啟動過程中遭遇到ORA-01102錯誤。

 

 

[oracle@oracle11g ~]$ oerr ora 01102

01102, 00000, "cannot mount database in EXCLUSIVE mode"

// *Cause:  Some other instance has the database mounted exclusive or shared.

// *Action: Shutdown other instance or mount in a compatible mode.

 

 

資料庫在啟動的時候,預設是要以EXCLUSIVE獨佔的方式進行。我們在一臺資料庫伺服器上,一般也就安裝一個例項。如果在啟動過程報錯ORA-01102,通常的問題可能不是啟動模式,而是上次關閉系統時,一些資源物件沒有正確釋放掉。例如:

 

ü        早期的Oracle 7/8中,在$ORACLE_HOME/dbs目錄下的sgadef.dbf檔案不能釋放刪除;

ü        Oracle後臺活動程式,如pmon, smon, lgwrdbwr沒有釋放掉;

ü        雖然資料庫關閉,但是作業系統層面的共享記憶體和訊號量沒有釋放;

ü        Oracle 8之後版本中,$ORACLE_HOME/dbs目錄下的lk檔案沒有釋放;

 

其中,談到了sgadeflk檔案。這兩個檔案在Oracle中的作用是用於鎖定shared memory。如果該檔案存在,那麼即使沒有記憶體被分配,Oracle依然認為此時有記憶體空間被鎖定。

 

解決01102錯誤的方法其實也比較簡單,就是在OS層面刪除掉sgadeflk檔案。這樣Oracle就不會認為說此時有記憶體被分配出。

 

3Oracle NFS Lock

 

NFS裝置,Oracle每個版本都存在一個相容性列表。只有透過相容性列表測試(Oracle Storage Compatibility Test)的裝置,Oracle才承諾進行NFS支援。

 

Oracle啟動的過程中,NFS相關問題主要在Lock鎖定方面:

 

ü        OS層面鎖定

 

當資料庫啟動的時候,Oracle會對檔案設定OS級別的鎖定。在資料庫停止的時候,Oracle會釋放OS級別的鎖定。這個鎖操作,不同的資料庫版本具有不同的方式。在Oracle78時代,這個檔名稱為$ORACLE_HOME/dbs/sgadef。而之後的版本中,這個檔名稱為$ORACLE_HOME/dbs/lk

 

ü        NFS鎖定守護daemon程式

 

為了在OS層面上實現對檔案的鎖定,Oracle必須呼叫NFS鎖定守護程式。在大部分的Unix系統中,這兩個守護程式的名稱為:rpc.lockdrpc.statd

 

在實際啟動過程中,如果遇到mount資料檔案的問題,很可能就是daemon程式終止造成的。所以可以嘗試啟動該程式。

 

4、強制關庫實驗

 

下面我們實驗一下那個朋友的方法,以及如何處理。

 

 

--當前wilson例項存活

[oracle@oracle11g ~]$ ps -ef | grep pmon

oracle    5644     1  0 14:44 ?        00:00:00 ora_pmon_wilson

oracle    5779  5744  0 14:46 pts/0    00:00:00 grep pmon

 

 

進入lk檔案所在目錄。

 

 

[oracle@oracle11g ~]$ cd $ORACLE_HOME/dbs

[oracle@oracle11g dbs]$ pwd

/u01/oracle/dbs

[oracle@oracle11g dbs]$ ls

hc_DBUA0.dat   init.ora        lkWILSON     peshm_DBUA0_0   snapcf_wilson.f

hc_wilson.dat  initwilson.ora  orapwwilson  peshm_wilson_0  spfilewilson.ora

 

 

更名該檔案。

 

 

[oracle@oracle11g dbs]$ mv lkWILSON lkWILSON_bak

[oracle@oracle11g dbs]$ ls

hc_DBUA0.dat   init.ora        lkWILSON_bak  peshm_DBUA0_0   snapcf_wilson.f

hc_wilson.dat  initwilson.ora  orapwwilson   peshm_wilson_0  spfilewilson.ora

 

 

注意,此時我們依然可以登入,pmon核心程式依然存在。

 

 

[oracle@oracle11g dbs]$ ps -ef | grep pmon

oracle    5644     1  0 14:44 ?        00:00:00 ora_pmon_wilson

oracle    5799  5744  0 14:48 pts/0    00:00:00 grep pmon

 

SQL> conn / as sysdba

Connected.

SQL> startup force

ORACLE instance started.

 

Total System Global Area  414298112 bytes

Fixed Size                  1336904 bytes

Variable Size             327158200 bytes

Database Buffers           79691776 bytes

Redo Buffers                6111232 bytes

Database mounted.

Database opened.

SQL>

 

 

此時,資料庫例項沒有如同想象的那樣被立即停止。而是依然存在,可以登入入系統。重新啟動系統之後,依然可以看到lk檔案重新建立成功。

 

 

[oracle@oracle11g dbs]$ ls

hc_DBUA0.dat   initwilson.ora  orapwwilson     snapcf_wilson.f

hc_wilson.dat  lkWILSON        peshm_DBUA0_0   spfilewilson.ora

init.ora       lkWILSON_bak    peshm_wilson_0

 

 

證明:直接刪除該檔案似乎是不能起到立即終止例項執行的作用。

 

5、結論

 

過去在一些文章中介紹過一種快速關閉例項的方法。就是在os層面使用kill方法將oracle例項全部刪除,在強制釋放共享記憶體和訊號量。

 

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

相關文章