理解透明應用程式故障轉移 (TAF) 和快速連線故障轉移 (FCF) (文件 ID 1602113.1)
適用於:
JDBC - 版本 10.1.0.2 到 11.2.0.3.0 [發行版 10.1 到 11.2]
本文件所含資訊適用於所有平臺
***Checked for relevance on 24-Apr-2013***
用途
本文件旨在解釋兩個 RAC 概念,即透明應用程式故障轉移 (TAF) 和快速連線故障轉移 (FCF)。
適用範圍
需要了解 JDBC。
詳細資訊
透明應用程式故障轉移 (TAF)
-
TAF 的含義是什麼?
透明應用程式故障轉移 (TAF),簡稱應用程式故障轉移,是 OCI 驅動程式的一項功能。當連線到的資料庫例項出錯時,可利用該功能自動重新連線該資料庫。此時,活動事務將回滾。事務回滾將恢復上次提交的事務。無論之前的連線是如何被喪失的,這個新的資料庫連線將由另一個節點建立,但與原始連線是完全一樣的。
TAF 總處於活動狀態而無需設定。
TAF 不能用於 thin 驅動程式。
-
TAF 的確切用途是什麼?
當第一個例項出錯時,可以透過 TAF 自動轉移到其他例項。
有關 OCI 和 TAF 的更多詳細資訊,請參閱 Oracle? Call Interface Programmer's Guide.
-
如何將 TAF 用於 JDBC 驅動程式?
需在 tnsnames.ora 中設定以下服務:
inst_primary=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(Host=hostname1)(Port=1521)) (ADDRESS = (PROTOCOL = TCP)(HOST=hostname2)(PORT = 1521))
(CONNECT_DATA=(SERVICE_NAME=ORCL)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC))))
請參閱 Oracle? Database Net Services Administrator's Guide 中故障轉移型別事件
以下是 OracleOCI 故障轉移介面中可能的故障轉移型別:
-
FO_SESSION
相當於 tnsnames.ora 檔案 CONNECT_DATA 標誌中的 FAILOVER_MODE=SESSION。其含義是,當 OCI 應用程式中的開啟遊標需要重新執行時,伺服器端僅需重新驗證使用者會話。
-
FO_SELECT
相當於 tnsnames.ora 檔案 CONNECT_DATA 標誌中的 FAILOVER_MODE=SELECT。其含義是,伺服器端需重新驗證使用者會話,而且 OCI 中的開啟遊標可繼續獲取。這意味著客戶機端邏輯維持每個開啟遊標的獲取狀態。
-
FO_NONE
相當於 tnsnames.ora 檔案 CONNECT_DATA 標誌中的 FAILOVER_MODE=NONE。這是預設設定,不使用故障轉移功能。還可明確指定阻止故障轉移的發生。另外,FO_TYPE_UNKNOWN 意味著從 OCI 驅動程式返回了一個錯誤的故障轉移型別。
以下是 OracleOCI 故障轉移介面中可能的故障轉移事件:
-
FO_BEGIN
說明故障轉移已檢測到一個丟失的連線,故障轉移開始啟動。
-
FO_END
說明成功完成故障轉移。
-
FO_ABORT
說明故障轉移不成功,沒有重試選項。
-
FO_REAUTH
說明已重新驗證使用者控制程式碼。
-
FO_ERROR
說明故障轉移暫不成功,但為應用程式提供處理錯誤並重試故障轉移的機會。處理錯誤的常規方法是發出 sleep() 方法,並透過返回值 FO_RETRY 進行重試。
-
FO_RETRY
說明應用程式應重試故障轉移。
-
FO_EVENT_UNKNOWN
一個錯誤的故障轉移事件。
TAF 回撥
當一個資料庫連線故障,故障轉移至另一個資料庫連線時使用 TAF 回撥。TAF 回撥是故障轉移時註冊的回撥。故障轉移時呼叫回撥,將生成的事件通知 JDBC 應用程式。應用程式也有一些故障轉移控制。 -
FO_SESSION
- TAF 回撥記錄在 Oracle? Database JDBC Developer's Guide 的以下章節: 注意:回撥設定是可選的。
Java TAF 回撥介面
OracleOCI 故障轉移介面包括 callbackFn() 方法,該方法支援以下型別和事件:
public interface OracleOCIFailover{
// Possible Failover Types
public static final int FO_SESSION = 1;
public static final int FO_SELECT = 2;
public static final int FO_NONE = 3;
public static final int;
// Possible Failover events registered with callback
public static final int FO_BEGIN = 1;
public static final int FO_END = 2;
public static final int FO_ABORT = 3;
public static final int FO_REAUTH = 4;
public static final int FO_ERROR = 5;
public static final int FO_RETRY = 6;
public static final int FO_EVENT_UNKNOWN = 7;
public int callbackFn (Connection conn,
Object ctxt, // ANy thing the user wants to save
int type, // One of the possible Failover Types
int event ); // One of the possible Failover Events
// Possible Failover Types
public static final int FO_SESSION = 1;
public static final int FO_SELECT = 2;
public static final int FO_NONE = 3;
public static final int;
// Possible Failover events registered with callback
public static final int FO_BEGIN = 1;
public static final int FO_END = 2;
public static final int FO_ABORT = 3;
public static final int FO_REAUTH = 4;
public static final int FO_ERROR = 5;
public static final int FO_RETRY = 6;
public static final int FO_EVENT_UNKNOWN = 7;
public int callbackFn (Connection conn,
Object ctxt, // ANy thing the user wants to save
int type, // One of the possible Failover Types
int event ); // One of the possible Failover Events
請參閱以下 TAF 示例,它來自於 OTN 上提供的 JDBC 標準示例。
/*
* This sample demonstrates the registration and operation of
* JDBC OCI application failover callbacks
*
* Note: Before you run this sample, set up the following
* service in tnsnames.ora:
* inst_primary=(DESCRIPTION=
* (ADDRESS=(PROTOCOL=tcp)(Host=hostname)(Port=1521))
* (CONNECT_DATA=(SERVICE_NAME=ORCL)
* (FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC))
* )
* )
* Please see Net8 Administrator's Guide for more detail about
* failover_mode
*
* To demonstrate the the functionality, first compile and start up the sample,
* then log into sqlplus and connect /as sysdba. While the sample is still
* running, shutdown the database with "shutdown abort;". At this moment,
* the failover callback functions should be invoked. Now, the database can
* be restarted, and the interrupted query will be continued.
*
*/
// You need to import java.sql and oracle.jdbc packages to use
// JDBC OCI failover callback
import java.sql.*;
import java.net.*;
import java.io.*;
import java.util.*;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleOCIFailover;
import oracle.jdbc.pool.OracleDataSource;
public class OCIFailOver {
static final String user = "hr";
static final String password = "hr";
static final String URL = "jdbc:oracle:oci8:@inst_primary";
public static void main (String[] args) throws Exception {
Connection conn = null;
CallBack fcbk= new CallBack();
String msg = null;
Statement stmt = null;
ResultSet rset = null;
// Create a OracleDataSource instance and set properties
OracleDataSource ods = new OracleDataSource();
ods.setUser(user);
ods.setPassword(password);
ods.setURL(URL);
// Connect to the database
conn = ods.getConnection();
// register TAF callback function
((OracleConnection) conn).registerTAFCallback(fcbk, msg);
// Create a Statement
stmt = conn.createStatement ();
for (int i=0; i<30; i++) {
// Select the NAMEs column from the EMPLOYEES table
rset = stmt.executeQuery ("select FIRST_NAME, LAST_NAME from EMPLOYEES");
// Iterate through the result and print the employee names
while (rset.next ())
System.out.println (rset.getString (1) + " " +
rset.getString (2));
// Sleep one second to make it possible to shutdown the DB.
Thread.sleep(1000);
} // End for
// Close the RseultSet
rset.close();
// Close the Statement
stmt.close();
// Close the connection
conn.close();
} // End Main()
} // End class jdemofo
/*
* Define class CallBack
*/
class CallBack implements OracleOCIFailover {
// TAF callback function
public int callbackFn (Connection conn, Object ctxt, int type, int event) {
/*********************************************************************
* There are 7 possible failover event
* FO_BEGIN = 1 indicates that failover has detected a
* lost connection and faiover is starting.
* FO_END = 2 indicates successful completion of failover.
* FO_ABORt = 3 indicates that failover was unsuccessful,
* and there is no option of retrying.
* FO_REAUTH = 4 indicates that a user handle has been re-
* authenticated.
* FO_ERROR = 5 indicates that failover was temporarily un-
* successful, but it gives the apps the opportunity
* to handle the error and retry failover.
* The usual method of error handling is to issue
* sleep() and retry by returning the value FO_RETRY
* FO_RETRY = 6
* FO_EVENT_UNKNOWN = 7 It is a bad failover event
*********************************************************************/
String failover_type = null;
switch (type) {
case FO_SESSION:
failover_type = "SESSION";
break;
case FO_SELECT:
failover_type = "SELECT";
break;
default:
failover_type = "NONE";
}
switch (event) {
case FO_BEGIN:
System.out.println(ctxt + ": "+ failover_type + " failing over...");
break;
case FO_END:
System.out.println(ctxt + ": failover ended");
break;
case FO_ABORT:
System.out.println(ctxt + ": failover aborted.");
break;
case FO_REAUTH:
System.out.println(ctxt + ": failover.");
break;
case FO_ERROR:
System.out.println(ctxt + ": failover error gotten. Sleeping...");
// Sleep for a while
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
System.out.println("Thread.sleep has problem: " + e.toString());
}
return FO_RETRY;
default:
System.out.println(ctxt + ": bad failover event.");
break;
}
return 0;
}
}
* This sample demonstrates the registration and operation of
* JDBC OCI application failover callbacks
*
* Note: Before you run this sample, set up the following
* service in tnsnames.ora:
* inst_primary=(DESCRIPTION=
* (ADDRESS=(PROTOCOL=tcp)(Host=hostname)(Port=1521))
* (CONNECT_DATA=(SERVICE_NAME=ORCL)
* (FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC))
* )
* )
* Please see Net8 Administrator's Guide for more detail about
* failover_mode
*
* To demonstrate the the functionality, first compile and start up the sample,
* then log into sqlplus and connect /as sysdba. While the sample is still
* running, shutdown the database with "shutdown abort;". At this moment,
* the failover callback functions should be invoked. Now, the database can
* be restarted, and the interrupted query will be continued.
*
*/
// You need to import java.sql and oracle.jdbc packages to use
// JDBC OCI failover callback
import java.sql.*;
import java.net.*;
import java.io.*;
import java.util.*;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleOCIFailover;
import oracle.jdbc.pool.OracleDataSource;
public class OCIFailOver {
static final String user = "hr";
static final String password = "hr";
static final String URL = "jdbc:oracle:oci8:@inst_primary";
public static void main (String[] args) throws Exception {
Connection conn = null;
CallBack fcbk= new CallBack();
String msg = null;
Statement stmt = null;
ResultSet rset = null;
// Create a OracleDataSource instance and set properties
OracleDataSource ods = new OracleDataSource();
ods.setUser(user);
ods.setPassword(password);
ods.setURL(URL);
// Connect to the database
conn = ods.getConnection();
// register TAF callback function
((OracleConnection) conn).registerTAFCallback(fcbk, msg);
// Create a Statement
stmt = conn.createStatement ();
for (int i=0; i<30; i++) {
// Select the NAMEs column from the EMPLOYEES table
rset = stmt.executeQuery ("select FIRST_NAME, LAST_NAME from EMPLOYEES");
// Iterate through the result and print the employee names
while (rset.next ())
System.out.println (rset.getString (1) + " " +
rset.getString (2));
// Sleep one second to make it possible to shutdown the DB.
Thread.sleep(1000);
} // End for
// Close the RseultSet
rset.close();
// Close the Statement
stmt.close();
// Close the connection
conn.close();
} // End Main()
} // End class jdemofo
/*
* Define class CallBack
*/
class CallBack implements OracleOCIFailover {
// TAF callback function
public int callbackFn (Connection conn, Object ctxt, int type, int event) {
/*********************************************************************
* There are 7 possible failover event
* FO_BEGIN = 1 indicates that failover has detected a
* lost connection and faiover is starting.
* FO_END = 2 indicates successful completion of failover.
* FO_ABORt = 3 indicates that failover was unsuccessful,
* and there is no option of retrying.
* FO_REAUTH = 4 indicates that a user handle has been re-
* authenticated.
* FO_ERROR = 5 indicates that failover was temporarily un-
* successful, but it gives the apps the opportunity
* to handle the error and retry failover.
* The usual method of error handling is to issue
* sleep() and retry by returning the value FO_RETRY
* FO_RETRY = 6
* FO_EVENT_UNKNOWN = 7 It is a bad failover event
*********************************************************************/
String failover_type = null;
switch (type) {
case FO_SESSION:
failover_type = "SESSION";
break;
case FO_SELECT:
failover_type = "SELECT";
break;
default:
failover_type = "NONE";
}
switch (event) {
case FO_BEGIN:
System.out.println(ctxt + ": "+ failover_type + " failing over...");
break;
case FO_END:
System.out.println(ctxt + ": failover ended");
break;
case FO_ABORT:
System.out.println(ctxt + ": failover aborted.");
break;
case FO_REAUTH:
System.out.println(ctxt + ": failover.");
break;
case FO_ERROR:
System.out.println(ctxt + ": failover error gotten. Sleeping...");
// Sleep for a while
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
System.out.println("Thread.sleep has problem: " + e.toString());
}
return FO_RETRY;
default:
System.out.println(ctxt + ": bad failover event.");
break;
}
return 0;
}
}
快速連線故障轉移 (FCF)
-
FCF 的含義是什麼?
快速連線故障轉移為 JDBC 應用程式提供一種與驅動程式無關的方法以利用 10g Release 1 (10.1) 中引入的連線故障轉移工具。
當 RAC 服務故障傳播到 JDBC 應用程式時,資料庫已回滾本地事務。然後,快取管理器會清空所有無效連線。當一個擁有無效連線的應用程式嘗試透過該連線進行工作時,將收到 SQLException ORA-17008, Closed Connection異常。該應用程式有必要處理該異常並重新連線。
-
FCF 的確切用途是什麼?
FCF 提供故障的快速通知,並可使用相同 URL 立刻重新連線。當 RAC 節點失敗時,應用程式將收到一個異常。該應用程式有必要處理該異常並重新連線。
JDBC 驅動程式不會重新瞄準現有連線。當節點失敗時,應用程式必須關閉現有連線並獲取一個新連線。應用程式透過獲取異常來了解節點失敗。當節點失敗時不止丟擲一個 ORA 異常,應用程式必須能處理所有這些錯誤。
應用程式可能會呼叫 OracleConnectionCacheManager 上的 isFatalConnectionError() API 來決定所捕獲的 SQLException 是否致命。
如果該 API 的返回值為 true,則需重試 DataSource.xxxxxx 上的 getConnection
-
如何將 FCF 用於 JDBC 驅動程式?
若要將 FCF 用於 JDBC,必須完成以下操作:
-
配置並啟動 ONS。如果 ONS 未正確設定,則隱式連線快取建立將失敗,並會針對第一個 getConnection() 請求丟擲 ONSException。
請參閱 - FCF 目前透過一個啟用池的資料來源進行配置,並與 UCP 緊密整合。正如在 10g 和 11g R1 中使用的那樣,透過隱式連線快取啟用的 FCF 目前已被棄用。
- 在向 OracleDataSource 傳送第一條 getConnection() 請求前設定 FastConnectionFailoverEnabled 屬性。當啟用 FastConnection 故障轉移時,故障轉移適用於池中所有連線。
-
設定 OracleDataSource url 屬性時,請使用服務名而非 SID。
-
配置並啟動 ONS。如果 ONS 未正確設定,則隱式連線快取建立將失敗,並會針對第一個 getConnection() 請求丟擲 ONSException。
-
用於測試 FCF 的示例程式碼
以下程式碼示例顯示了 FCF 的工作方法,它可能並非最佳方法,但給出了所需操作的一般思路。
請確保更改程式、<hostname1>、<hostname2> 和 <service_name> 中的以下字串。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionPoolName("FCFSamplePool");
pds.setFastConnectionFailoverEnabled(true);
pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200\nwalletfile= /oracle11/onswalletfile");
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");pds.setURL("jdbc:oracle:thin@(DESCRIPTION= "+
"(LOAD_BALANCE=on)"+
"(ADDRESS=(PROTOCOL=TCP)(HOST=racnode1) (PORT=1521))"+
"(ADDRESS=(PROTOCOL=TCP)(HOST=racnode2) (PORT=1521))"+
"(CONNECT_DATA=(SERVICE_NAME=service_name)))");
...
try { conn = pds.getConnection; ...}catch (SQLException sqlexc)
{
if (conn == null || !((ValidConnection) conn).isValid())
// take the appropriate action
...
conn.close();
}
上述示例從 Oracle? Universal Connection Pool for JDBC Developer's Guide 11g Release 2 (11.2) 中的 8 Using Oracle RAC Features 這一節的 FCF 文件摘錄。
基於 ICC 的 FCF 仍記錄在 Oracle? Database JDBC Developer's Guide 11g Release 2 (11.2)27 Fast Connection Failover 中,然而,本章目前已標記為棄用。
建議使用基於 UCP 的 FCF 實施。
示例請參閱 Note 566573.1 Fast Connection Failover (FCF) Test Client Using 11g JDBC Driver and 11g RAC Cluster
基於 ICC 的 FCF 仍記錄在 Oracle? Database JDBC Developer's Guide 11g Release 2 (11.2)27 Fast Connection Failover 中,然而,本章目前已標記為棄用。
建議使用基於 UCP 的 FCF 實施。
示例請參閱 Note 566573.1 Fast Connection Failover (FCF) Test Client Using 11g JDBC Driver and 11g RAC Cluster
Join the
參考
NOTE:1064652.1 - How to Verify Universal Connection Pool (UCP) / Fast Connection Failover (FCF) Setup 來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/27571661/viewspace-1781801/,如需轉載,請註明出處,否則將追究法律責任。
請登入後發表評論
登入
全部評論
|
相關文章
- 4.2.14 啟用客戶端快速連線故障轉移客戶端
- 4.2.14.4 為ODP.NET啟用快速連線故障轉移
- 4.2.14.1 關於啟用客戶端快速連線故障轉移客戶端
- 4.2.14.2 為JDBC客戶機啟用快速連線故障轉移JDBC
- 4.2.14.3 為Oracle呼叫介面客戶端啟用快速連線故障轉移Oracle客戶端
- 5 切換和故障轉移操作
- Elixir 分散式 Application 故障轉移和接管分散式APP
- [AlwaysOn] AlwaysOn可用性組的故障轉移和故障轉移模式[中英文對照] 3模式
- [AlwaysOn] AlwaysOn可用性組的故障轉移和故障轉移模式[中英文對照] 6模式
- [AlwaysOn] AlwaysOn可用性組的故障轉移和故障轉移模式[中英文對照] 5模式
- [AlwaysOn] AlwaysOn可用性組的故障轉移和故障轉移模式[中英文對照] 4模式
- [AlwaysOn] AlwaysOn可用性組的故障轉移和故障轉移模式[中英文對照] 2模式
- [AlwaysOn] AlwaysOn可用性組的故障轉移和故障轉移模式[中英文對照] 1模式
- Mysql MHA部署-05故障轉移MySql
- Oracle Dataguard故障轉移(failover)操作OracleAI
- 【UCP】理解TAF和FCF(重點是UCP)
- SQLServer 2012 AG強制故障轉移SQLServer
- Sentinel哨兵模式解決故障轉移模式
- redis健康檢查與故障轉移Redis
- PostgreSQL中利用驅動程式實現故障轉移SQL
- 【Redis】Redis Cluster-叢集故障轉移Redis
- Windows故障轉移群集(WSFC)的備份和恢復Windows
- docker搭建redis叢集和Sentinel,實現故障轉移DockerRedis
- Redis 故障轉移、高可用方案,都在這了!Redis
- Oracle Rman多通道故障轉移問題分析Oracle
- 伺服器叢集的故障轉移方案伺服器
- SQL Server 2008的故障轉移叢集概述UBSQLServer
- MySQL MHA部署 Part 6 MHA故障轉移測試MySql
- weblogic多資料來源故障轉移問題Web
- 4.2.13 主備庫實現自動故障轉移
- 基於istio實現單叢集地域故障轉移
- 使用etcd選舉sdk實踐master/slave故障轉移AST
- Sqlserver 2014 alwayson故障轉移群集節點被踢出群集SQLServer
- dolphinscheduler 實現master當機故障轉移能力原始碼分析AST原始碼
- ES 筆記三十一:分片與叢集的故障轉移筆記
- Windows Server2012 故障轉移叢集之動態仲裁(Dynamic Quorum)WindowsServer
- 使用ProxySQL實現MySQL Group Replication的故障轉移、讀寫分離(一)MySql
- 節點 B 上的 Windows 防火牆未正確配置為故障轉移群集Windows防火牆
- MongoDB 4.2副本集自動故障轉移(一主一副一仲裁)MongoDB