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'; |