2023年5月31日 星期三

ORA-12547 造成 RAC DB 無法啟動

Oracle 版本: 11.2.0.4 , RAC

OS 版本: Linux 5.8


問題描述:

RAC DB 無法啟動並出現錯誤 :

ORA-01078: failure in processing system parameters

ORA-01565: error in identifying file '+DATA/ORCL/spfileORCL.ora'

ORA-17503: ksfdopn:2 Failed to open file +DATA/ORCL/spfileORCL.ora

ORA-12547: TNS:lost contact


檢查 DB alert log 出現以下錯誤 :

ORA-15055: unable to connect to ASM instance

ORA-12547: TNS:lost contact


問題分析:

這個訊息表示 DB 的 spfile 放置在 ASM ,啟動時 DB 無法存取 ASM 導致無法讀取 spfile ,檢查 ASM Instance 狀態是正常的 :

# ps -ef|grep pmon

grid      2953     1  0 08:03 ?        00:00:00 asm_pmon_+ASM1

root      3115  3090  0 08:08 pts/1    00:00:00 grep pmon


# ./crsctl stat res -t

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

NAME           TARGET  STATE        SERVER                   STATE_DETAILS                                        

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

Local Resources

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

ora.DATA.dg

               ONLINE  ONLINE       db11gr21                                                                       

ora.LISTENER.lsnr

               ONLINE  ONLINE       db11gr21                                                                      

ora.asm

               ONLINE  ONLINE       db11gr21                 Started  


解決方法:

連線時出現 ORA-12547 錯誤一般與權限有關, $GI_HOME/bin 以及 $ORACLE_HOME/bin 底下的oracle 執行檔的權限必須為 6751 ,並且 $GI_HOME/bin/oracle 的權限為 grid:oinstall ;而 $ORACLE_HOME/bin/oracle 的權限為 oracle:asmadmin 

$ ls -l $GRID_HOME/bin/oracle

-rwsr-s--x 1 grid oinstall 203974257 Mar 14 19:20 oracle


$ ls -l $ORACLE_HOME/bin/oracle

-rwsr-s--x 1 oracle asmadmin 232399431 Mar 14 19:20 oracle


這個問題很常發生在有設定 asmadmin 這個 group 的情況。



ORA-600 [spstp: ORACLE_HOME uid does not match euid]

Oracle 版本: 11.1.0.7

OS 版本: Linux 5.8


問題描述:

使用 sqlplus 連線時出現錯誤 ORA-12547 "TNS:lost contact" ,檢查 DB alert log 出現 ORA-00600 訊息:

ORA-00600: internal error code, arguments: [spstp: ORACLE_HOME uid does not match euid], [1001], [1003], [], [], [], [], [], [], [], [], []


問題分析:

這個訊息表示 oracle 執行檔的權限不對,檢查 $ORACLE_HOME/bin/oracle 的權限,發現為 755 :

$ ls -l $ORACLE_HOME/bin/oracle

-rwxr-xr-x 1 oracle oinstall 232399431 Mar 14 10:17 oracle


解決方法:

將 oracle 執行檔權限修正為 6751 :

$ chmod 6751 $ORACLE_HOME/bin/oracle

$ ls -l $ORACLE_HOME/bin/oracle

-rwsr-s--x 1 oracle oinstall 232399431 Mar 14 10:17 oracle



Listener hang on Windows Platform

Oracle 版本: 11.2.0.4

OS 版本: Windows 2012


問題描述:

AP 以及 client 端無法連線到 DB ,以 lsnrctl status 檢查 listener 狀態無法顯示出結果。


問題分析:

相關 Bug , Bug:9879101 THE CONNECT THROUGH LISTENER WAS SLOW WHEN LISTENER LOG GREW to 4GB 。


解決方法:

這是一個早期在 Windows 平台上的問題, Oracle 9i 、 10g 都有可能會碰到,當 listener log 達到 4G 時 listener 就無法正常運作,必須將 listener log 移除或重新命名才行 :

1. stop listener from windows service

2. rename or delete listener.log

3. start listener service


2023年5月26日 星期五

read mostly locking 造成 session 堵塞案例

Oracle 版本: 12.2 , RAC

OS 版本: Linux 7


問題描述:

使用者反映網頁無法正常回應,由 DB session 發現同時多個 active session 且等待事件皆為 enq: TX – row lock contention 。


問題分析:

一般來說, row lock contention 多數由於上層有尚未 commit 的 session 導致後續的 session 堵塞,由 blocking session 找到上層 sid 為 30098 為堵塞的源頭 :


 

30098 這個 session 並非是沒有 commit 造成堵塞,而是它本身被 gc flushed buffer 這個等待事件所影響,某個物件一直無法完成 gc flushed buffer 這個動作導致 30098 這個 session hang 住,進而影響後續 session。


解決方法:

我們必須解決 30098 卡在 gc flushed buffer 這個現象,由 incident trace 中,以 pkey 這個關鍵字找出正在 cache flushed 的 object :


得知 cache 中在 flushed 這個 pkey 0.10.157792 產生了未知的 lock 導致 flushed 無法完成,以 oradebug 命令強制解除這個 pkey 的 lock :

SQL> oradebug lkdebug -m dpkey_readmostly  157792  10


在解除 pkey 0.10.157792 的 lock 之後, gc flushed buffer 的等待事件消失,後續的 session 也就疏通了。


而這個 pkey flushed 的 lock 是由於 read mostly locking 的 bug 所引起的,另一種 workaround 的方法是 disable read mostly locking 這個功能 :

SQL> alter system set "_gc_persistent_read_mostly"=FALSE scope=spfile sid='*';

SQL> alter system set "_gc_read_mostly_locking"=FALSE scope=spfile sid='*';


$ srvctl stop database -d <database_name>

$ srvctl start database -d <database_name>