2024年6月24日 星期一

mount point 權限造成的安裝問題

Oracle 版本: 19.3.0.0

OS 版本: AIX 7.2


問題描述:

在 AIX 7.2 搭配 vxfs 的環境下安裝 19.3 grid ,執行 gridSetup.sh 後出現以下錯誤 :

/u01/19.0.0/grid $ ./gridSetup.sh 

Exception in thread "Attach API initializer" java.lang.ExceptionInInitializerError

        at java.lang.J9VMInternals.ensureError(J9VMInternals.java:146)

        at java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:135)

        at java.nio.file.FileSystems.getDefault(FileSystems.java:187)

        at java.nio.file.Paths.get(Paths.java:95)

        at com.ibm.tools.attach.target.IPC.checkOwnerAccessOnly(IPC.java:142)

        at com.ibm.tools.attach.target.TargetDirectory.createMyDirectory(TargetDirectory.java:90)

        at com.ibm.tools.attach.target.AttachHandler.createFiles(AttachHandler.java:207)

        at com.ibm.tools.attach.target.AttachHandler.initialize(AttachHandler.java:306)

        at com.ibm.tools.attach.target.AttachHandler.run(AttachHandler.java:239)

Caused by: java.lang.RuntimeException: default directory must be absolute


由 java Initialize Error ,懷疑是否 java 的問題,執行 find . -name java 產生了權限錯誤 :

/u01/19.0.0/grid $ find . -name java

fch: The file access permissions do not allow the specified action.


檢查了 /u01 權限,看起來是沒有問題的 :

# ls –ld /u01

drwxr-x---   67 grid   oinstall       8192 Jun 05 16:32 /u01


問題分析:

在 AIX 環境上不僅要檢查目錄的權限,還要檢查 underlying mount point permissions ,將 /u01 umount 之後再檢查權限 :

# umount /u01

# ls –ld /u01

drwxr-x---   67 root  root       8192 Jun 05 16:32 /u01


發現原本 /u01 的權限為 root ,這邊導致問題所在。


解決方法:

更改 /u01 的權限之後再重新 mount 即可 :

# chown grid:oinstall /u01

# ls –ld /u01

drwxr-x---   67 grid  oinstall       8192 Jun 05 16:32 /u01

# mount /dev/vx/dsk/oradg/oravol /u01


2024年5月27日 星期一

foreign key 造成 TM contention 案例

Oracle 版本: 12.1.0.2.0

OS 版本: AIX 7.1


問題描述:

對 Table 進行 delete 動作時卡住無法成功執行。

SQL> SQL> delete regions where region_id=7; 

(毫無反應)


問題分析:

從 v$session 可以發現等待事件為 enq: TM – contention 且被 sid 為 80 的 session 咬住 :


不過 sid 為 80 的 session 當前狀態為 SQL*Net message from client ,是一個 idle 的事件,無法確定 sid 80 是執行了什麼導致 TM – contention ,進一步使用 hanganalyze 分析 :

SQL> oradebug setospid 5436

Oracle pid: 52, Unix process pid: 5436, image: oracle@orcl (TNS V1-V3)

SQL> oradebug hanganalyze 3


由 trace 當中發現等待的是 mode 4 的 TM lock :


mode 4 的 TM lock 一般與 foreign key 有關,當具有 primary key 的 table 進行 update / delete 操作時,需要先確認此筆資料是否存在於 child table ,此時若 child table 上的 foreign key 欄位沒有建立 index ,則會對 child table 進行 Share mode 的 DML lock ,也就是 mode 4 lock ,由 trace 顯示無法完成 mode 4 lock ,所以整個語法無法完成,有可能此時 child table 進行了尚未 commit 的 DML 操作所以發生了 TM – contention 。


檢查 reference 到 REGIONS 的所有 table :


檢查 COUNTRIES 與 PEO 的 foreign key 欄位是否缺少 index :


CONTRIES 與 PEO 作為 foreign key 欄位的 REGION_ID 都沒有建立 index 。


解決方法:

將所有 foreign key 欄位建立 index 即可 :

SQL> create index ix_countries on countries(region_id);

SQL> create index ix_peo on peo(region_id);



2024年4月23日 星期二

新增 Listener 造成 ORA-12547 錯誤案例

Oracle 版本: 19.14 , RAC

OS 版本: Linux 7.7


問題描述:

當前 RAC 架構下,對外 Service 所使用的網段為 192.168.49.0/24 ,並以 1521 Port 作為 Service 連線所用,在同樣網段新增一個 Listener 使用 1528 Port 作為 Data Guard 所用 :

[grid@rac19c1 ~]$ srvctl add listener -listener listener_dg -endpoints TCP:1528


在新增完 listener_dg 之後,原本 Client 透過 scan 的連線產生異常,有時候可以正常連線,有時候則產生 ORA-12547: TNS: lost contact 錯誤 :


問題分析:

開啟 SQL Net Trace 對 Client 連線進行 Trace ,於 sqlnet.ora 設置參數如下 :

TRACE_UNIQUE_CLIENT = ON

TRACE_LEVEL_CLIENT = 16

TRACE_DIRECTORY_CLIENT = /tmp

TRACE_FILE_CLIENT = sqlnettrace.trc

TRACE_TIMESTAMP_CLIENT = ON

DIAG_ADR_ENABLED = OFF


檢視連線異常時的 trace ,發現使用了 1528 Port 進行連線 :


由於 1528 Port 並沒有開通 Firewall 給 Service 連線所用,因此產生了 ORA-12547 錯誤。


檢視 tnsnames.ora 設定,是使用 scan 連線並且指定 1521 Port ,為何 SQL Net Trace 出現了 1528 Port 的連線 ?


檢查資料庫的 local_listener 參數,發現 1528 Port 被註冊到 local_listener 了 :


由於 local_listener 註冊了 1528 Port ,因此透過 scan 連線時就有可能重新導向為 1528 Port 來連線。


在沒有手動設定 local_listener 的情況下, CRS 自動會將 DB 註冊至 network 1 的網段上,因此在新增一個 1528 Port 的 listener_dg 之後, DB 的 local_listener 也自動將 1528 Port 註冊上去,導致透過 scan的連線異常。


解決方法:

手動設定 local_listener 參數,只綁定 1521 Port ,這樣另一個 1528 Port 就不會自己加進來了 :

SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.49.193)(PORT=1521))' sid='orcl19c1';

SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.49.194)(PORT=1521))' sid='orcl19c2';