最近在做新系統的建置,結果在測試資料庫連線時,遇到一些問題,筆記一下,也提供有緣人未來遇到時可以縮短處理的時間。
在Oracle連線中,我們常會透過tnsnames.ora來設定client 連線Oracle各個資料庫的連線資訊,
有時候會遇到ora-12154 與 ora-12545的錯誤,這邊分別說明可能遇到的原因:
ORA-12154 could not resolve the connect identifier specified
中文:
ORA-12154: TNS: 無法解析指定的連線 ID
這個問題通常跟tnsnames.ora內的設定值有關,我們來看一下tnsnames.ora中對資料庫連線的寫法(這邊以11g為例):
X_test =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST=drx10db-scan.xxx.com.tw)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = TEST_ROX)
)
)
先來tnsping 一下:
tnsping X_test
TNS Ping Utility for 64-bit Windows: Version 21.0.0.0.0 - Production on 16-1月 -2025 13:33:29
Copyright (c) 1997, 2021, Oracle. All rights reserved.
已使用的參數檔案:
D:\app\client\submarine\product\21.0.0\client_1\network\admin\sqlnet.ora
使用 TNSNAMES 轉接器來解析別名
正在嘗試聯繫 (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST=drx10db-scan.xxx.com.tw)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = TEST_ROX)))
OK (40 msec)
我們會發現tnsping 測試連線是成功的,但透過sqlplus連線卻會顯示ORA-12154的錯誤,我們來用tnsnames.ora中的參數來透過sqlplus直接測式連線一下:
sqlplus username/passworde@X_test
連線是失敗,顯示
ORA-12154 could not resolve the connect identifier specified
這個可能有下面幾個可能:
1.client端的TNS_ADMIN的環境變數沒設定好(應該要指向tnsnames.ora檔的所在)
2.tnsnames.ora中的資訊有誤。
我們直接把連線資訊中幾個必要欄位直接寫在sqlplus連線上測試一下,如下:
sqlplus username/passworde@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=drx10db-scan.xxx.com.gov.tw)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=TEST_ROX)))
連線前先確認一下dns解析drx10db-scan.xxx.com.gov.tw 是否能解出正確的ip來。
這個連線測試可以跳過tnsnames.ora檔,如果這樣可以順利連線,那表示tnsnames.ora內有寫錯。
然後修正後tnsnames.ora檔內容後,
sqlplus username/passworde@X_test
這時候換了一個錯誤訊息:
ORA-12545 could not resolve the connect identifier specified
這時候換成透過vip連線,tnsnames.ora內的連線資訊如下:
X_test1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = drx10db01-vip.xxx.com.tw)(PORT = 1527))
)
(CONNECT_DATA =
(SERVICE_NAME = TEST_ROX)
(INSTANCE_NAME = TEST1)
)
)
發現透過vip單獨連線特定instance是可以的,但換成透過scan ip連線就會秀ORA-12154的錯誤,
上網找了一些文件,最後找到一篇有提到可能跟scan中的資料庫參數有關,我們來檢查一下:
SQL> show parameter local_listener
NAME TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
local_listener string
(ADDRESS=(PROTOCOL=TCP)(HOST=
drx10db01-vip)(PORT=1527))
我們發現這個參數是寫了短名稱,而這個短名稱沒有辦法讓cline透過dns做IP解析,所以導致了ORA-12545 的錯誤
SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=drx10db01-vip.xxx.com.tw)(PORT=1527))' sid='test1';
SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=drx10db02-vip.xxx.com.tw)(PORT=1527))' sid='test2';
SQL> show parameter local_listener
NAME TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
local_listener string
(ADDRESS=(PROTOCOL=TCP)(HOST=
drx10db01-vip.xxx.com.tw)(PORT
=1527))
然後在測試一下
sqlplus username/passworde@X_test
順利連線成功!!!
總結:
oracle RAC有所謂的scan來做連線的分派與load balance,
當client透過scan連線到oracle時,透過scan_listener將連線導到local database,這時候會將local database上的參數 local_listener內的值與port號傳遞到client端,以利client端建立後續的連線,所以當local_listener值因短名稱而無法被解析成IP時,就會讓client端顯示
ORA-12545 could not resolve the connect identifier specified
的錯誤。
ref: