RAC連線中TNSNAMES需注意的問題

tangyunoracle發表於2010-11-18

Oracle RAC中的LOAD_BALANCE引數和FAILOVER引數的預設值為。

LOAD_BALANCE引數:在DESCRIPTION_LIST層為ON,而在DESCRIPTIONADDRESS_LIST預設值都是OFF

FAILOVER引數:在DESCRIPTION_LISTDESCRIPTIONADDRESS_LIST層的預設值都是ON;

注意這些引數的預設值可能會幫助你避免一些奇怪的問題。

[@more@]

1、指定了INSTANCE_NAME引數仍然會連線到兩個例項上

DFKZYK1 =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))

(LOAD_BALANCE = ON)

)

(CONNECT_DATA =

(SERVICE_NAME = DFKZYK)

(INSTANCE_NMAE = DFKZYK1)

)

)

下面測試連線:

SQL> CONN SYS/TANGYUN@DFKZYK1

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk2

SQL> CONN SYS/TANGYUN@DFKZYK1

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk2

SQL> CONN SYS/TANGYUN@DFKZYK1

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk1

這個問題也是一次偶然的發現,明明配的是例項1卻連線到例項2上去。之前一直都是這樣配都沒有出現過這樣的問題,想了很多種可能性,還是沒有想明白為什麼,最後細細檢查才發現是INSTANCE_NAME寫成了INSTANCE_NMAE,引數寫錯了,但是Oracle卻沒有檢查錯誤,而是直接忽略掉這個引數,導致問題很難被發現。

2LOAD_BALANCE引數的沒有起作用

DFKZYK =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))

)

(LOAD_BALANCE = ON)

(CONNECT_DATA =

(SERVICE_NAME = DFKZYK)

)

)

資料庫的LOCAL_LISTENER引數設定已經被取消:

SQL> CONN SYS/TANGYUN@DFKZYK

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk2

SQL> SHOW PARAMETER LOCAL_LISTENER;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string

SQL> CONN SYS/TANGYUN@DFKZYK

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk1

SQL> SHOW PARAMETER LOCAL_LISTENER;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string

在不設定LOCAL_LISTENER引數偶爾會出現連線失敗,LOAD_BALANCE引數設定沒有生效,無論設定為ONOFF,都不會影響資料庫的連線。測試了多次後才注意到,LOAD_BALANCE引數新增位置錯誤,這裡使用了ADDRESS_LIST並新增了括號,而LOAD_BALANCE引數沒有放到括號中,使得這個設定對於ADDRESS_LIST中的配置無效,而預設LOAD_BALANCEON,因此LOAD_BALANCE設定仍然可以生效。

正確的設定應該是:

DFKZYK =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))

(LOAD_BALANCE = ON)

)

(CONNECT_DATA =

(SERVICE_NAME = DFKZYK)

)

)

需要注意的是,不僅LOAD_BALANCE引數,FAILOVER引數也有生效區間的問題,這兩個引數在DESCRIPTION_LISTDESCRIPTIONADDRESS_LIST三個層面都可以生效,因此在設定引數的時候一點要注意是否引數設定在指定層面上。

當服務名同時配置了LOAD_BALANCEFAILOVER時:

DFKZYK =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))

(LOAD_BALANCE = ON)

(FAILOVER=OFF)

)

(CONNECT_DATA =

(SERVICE_NAME = DFKZYK)

)

)

且配置LOCAL_LISTENER引數時。

SQL> CONN SYS/TANGYUN@DFKZYK

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk2

SQL> SHOW PARAMETER LOCAL_LISTENER;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string NODE2

SQL> CONN SYS/TANGYUN@DFKZYK

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk1

SQL> SHOW PARAMETER LOCAL_LISTENER;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string NODE1

資料庫伺服器上兩個節點的TNSNAMESNODE1(節點1)NODE2(節點2)中的配置均為:

NODE1/NODE2 =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = node1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip)(PORT = 1521))
)

當例項1當機時並不出現問題,但是當例項1沒有問題,但是監聽宕掉時,這個服務名的配置可能會偶爾連線不上:

SQL> CONN SYS/TANGYUN@DFKZYK

ERROR:
ORA-12541: TNS:
無監聽程式

警告: 您不再連線到 ORACLE

SQL> CONN SYS/TANGYUN@DFKZYK

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk2

SQL> CONN SYS/TANGYUN@DFKZYK

已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
dfkzyk2

SQL> CONN SYS/TANGYUN@DFKZYK

ERROR:
ORA-12541: TNS:
無監聽程式

警告: 您不再連線到 ORACLE

導致這個問題的原因是由於配置LOCAL_LISTENER後,雖然例項1對應節點的監聽關閉,但是例項2所在節點的監聽仍然包含例項2上的資訊,因此連線時負載均衡仍然會考慮例項1,當節點2上的監聽將連線發到節點1的監聽時碰到了錯誤,而靜態FAILOVER又沒有啟動,因此出現了錯誤。

這種情況下,如果修改服務名設定FAILOVERON,那麼可以避免錯誤的產生:

DFKZYK =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))

(LOAD_BALANCE = ON)

(FAILOVER=ON)

)

(CONNECT_DATA =

(SERVICE_NAME = DFKZYK)

)

)

這樣,仍然有部分連線會嘗試例項1,但是在碰到錯誤後,會自動連線到例項2上。

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

相關文章