理解透明應用程式故障轉移 (TAF) 和快速連線故障轉移 (FCF) (文件 ID 1602113.1)

OGG-01161發表於2015-08-25

適用於:

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)



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


  • 用於測試 TAF 的示例程式碼
    請參閱以下 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;

       }
    }
  • 快速連線故障轉移 (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,必須完成以下操作:
      1. 配置並啟動 ONS。如果 ONS 未正確設定,則隱式連線快取建立將失敗,並會針對第一個 getConnection() 請求丟擲 ONSException。
        請參閱  
      2. FCF 目前透過一個啟用池的資料來源進行配置,並與 UCP 緊密整合。正如在 10g 和 11g R1 中使用的那樣,透過隱式連線快取啟用的 FCF 目前已被棄用。
      3. 在向 OracleDataSource 傳送第一條 getConnection() 請求前設定 FastConnectionFailoverEnabled 屬性。當啟用 FastConnection 故障轉移時,故障轉移適用於池中所有連線。
      4. 設定 OracleDataSource url 屬性時,請使用服務名而非 SID。


    • 用於測試 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

     


    Join the  參考 NOTE:1064652.1 - How to Verify Universal Connection Pool (UCP) / Fast Connection Failover (FCF) Setup
    NOTE:566573.1 - Fast Connection Failover (FCF) Test Client Using 11g JDBC Driver and 11g RAC Cluster

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

    理解透明應用程式故障轉移 (TAF) 和快速連線故障轉移 (FCF) (文件 ID 1602113.1)
    請登入後發表評論 登入
    全部評論

    相關文章