oracle程式異常中止時登入掛起問題的解決

space6212發表於2019-06-24

今天一個朋友找我處理幫忙處理一個oracle問題,原因是使用者不能登入了。
起因是這樣的:
因為業務推廣,訪問量大增,造成oracle壓力大增,系統IDLE幾乎為0。我那朋友情急之下,把使用者的連線都用kill -9的方式幹掉了。
然後,就發現,怎麼都登入不進去了,就掛在登入介面上,沒有任何提示。

我登入上去看了一下,乖乖,ps -ef|grep ora_一個程式都沒有了,也就是說,他把所有的連線包括oracle自身的關鍵程式都幹掉了。
這個問題後來得到解決。下面在我本機簡單模擬當時的場景,說說解決步驟和方法。


1、首先殺掉所有oracle程式:
[oracle@rep ~]$ ps -ef|grep ora|awk '{print $2}'|xargs kill -9

2、使用者登入
[oracle@rep ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on D??úáù 7?? 28 13:50:36 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

sys@REP>
sys@REP> exit
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

可見,用sys登入沒有問題。

[oracle@rep ~]$ sqlplus suk/suk

SQL*Plus: Release 9.2.0.4.0 - Production on D??úáù 7?? 28 13:52:44 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

用普通使用者suk登入就一直掛在這個介面了,後臺alert也沒有任何資訊。

用sys登入時是用作業系統認證,所以能順利登入。而用普通使用者登入需要透過資料庫驗證,而資料庫的相關程式是不存在的,所以不能完成驗證過程。
但是,一般情況下,如果資料庫是關閉的,用普通使用者登入是會報錯的,但在這裡為什麼不會報錯呢?

3、接著嘗試關閉資料庫
[oracle@rep ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on D??úáù 7?? 28 14:02:22 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

sys@REP> shutdown immediate

介面也一直停留在這裡,無法關閉。

透過sqlplus "/as sysdba"登入資訊我們可以知道,sqlplus認為oracle資料庫並沒有關閉。
oracle的程式都不存在了,但sqlplus為什麼認為oracle沒有關閉呢?它是根據什麼來判斷的?

4、檢視此時的共享記憶體段情況
[oracle@rep ~]$ ipcs -as

------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x91c11414 491531 oracle 640 142606336 10

------ Semaphore Arrays --------
key semid owner perms nsems
0xeddca300 360448 oracle 640 154

------ Message Queues --------
key msqid owner perms used-bytes messages

從上面的資訊可以看出,oracle之前佔用的共享記憶體段和訊號段都還在,而sqlplus是根據這些資訊來判斷資料庫是否關閉的。
我們雖然kill了oracle的程式,但是並沒有清除其對應的共享記憶體段和訊號段。
原因找到的,下面就是清除共享記憶體段和訊號段了。

清除共享記憶體段:
要清除oracle共享記憶體段,必須保證沒有任何連線連線到oracle資料庫上,否則清除共享記憶體段會失敗。
我們用暴力方法強制殺死連線到oracle的程式:
[root@rep ~]# ps -ef|grep ora|awk '{print $2}'|xargs kill -9
[root@rep ~]# su - oracle
[oracle@rep ~]$ ipcrm -m 491531

清除訊號段:
[oracle@rep ~]$ ipcrm -s 360448

檢視此時共享記憶體等資訊:
[oracle@rep ~]$ ipcs -as

------ Shared Memory Segments --------
key shmid owner perms bytes nattch status

------ Semaphore Arrays --------
key semid owner perms nsems

------ Message Queues --------
key msqid owner perms used-bytes messages

從上面資訊看到,共享記憶體段和訊號段已經被清除。

5、啟動oracle
清除完訊號段後,我們再用sys登入資料庫,就會發現,sqlplus已經認為資料庫是關閉的了。
此時我們可以正常啟動資料庫:
[oracle@rep ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on D??úáù 7?? 28 14:17:46 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to an idle instance.

idle> startup
ORACLE instance started.

Total System Global Area 135337420 bytes
Fixed Size 452044 bytes
Variable Size 109051904 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes
Database mounted.
Database opened.

其實這種情況下,我們只需要清除訊號段就可以正常啟動資料庫,但為了更徹底一點,我們選擇了把共享記憶體也一併清除。

一般遇到這種情況有兩種解決方法:
1、直接重啟OS
2、清除共享記憶體和訊號量

最後簡單總結一下:
1、oracle程式終止不代表資料庫關閉
2、oracle程式異常中止時要及時清除對應的共享記憶體段和訊號段
3、sqlplus是根據訊號段來判斷oracle資料庫是否是關閉的

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

相關文章