2017-07-17 14 views
0

私は愚かな問題に直面していますが、オンライン検索と実験をしてから、
私はDataguardのおかげで、レプリカになるように設定された2つのOracle DBを持っています。私のような、私のDBに接続するためのJDBC TNSのURLを使用してい
Oracle:JDBC TNS URL接続は、リスナーがまだ応答しているためにフェールオーバーしません。

:私はスイッチオーバーを実行すると

 
jdbc:oracle:thin:@ 
    (DESCRIPTION_LIST= 
    (FAILOVER=on) 
    (LOAD_BALANCE=off) 
    (DESCRIPTION= 
     (ADDRESS= 
     (PROTOCOL=TCP) 
     (HOST=DB1) primary 
     (PORT=1521)) 
     (CONNECT_DATA= 
      (SERVER=DEDICATED) 
      (SID=MySID)) 
     ) 
    (DESCRIPTION= 
     (ADDRESS= 
     (PROTOCOL=TCP) 
     (HOST=DB2) secondary 
     (PORT=1521)) 
     (CONNECT_DATA= 
      (SERVER=DEDICATED) 
      (SID=MySID)) 
     ) 
    ) 

は、役割が交換されます:DB1は、二次になり、DB2がプライマリになります。 DB1はマウント状態です。
これまでのところ、とても良いです。

私の接続URLでは、DB2からの接続はプライマリになりますが、DB1リスナーがまだ起動しているので、すべてが正常であるかのように動作し、取得しようとします次のエラーにつながるDB1の接続、:

 
ORA-01033: ORACLE initialization or shutdown in progress 

私はその後、リスナー、フェールオーバーの作品を殺すと私はDB2からの接続を得た場合。

しかし、dataguardの全ポイントは自動フェールオーバーを実行することです。
しかし、私は、リスナーを殺すために強制していた場合:

  1. それはない、私はそうであれば

を行うために、リスナーを使っているよう

  • スイッチバックは、動作しない場合があります:)期待していたものだだれでも正しい構成についての手がかりを持っている、私は興味がある!

    ありがとうございます。

  • +0

    プログラム的に実装することができますが、これは非常に簡単です。例外をキャッチし、他のsidを試してみてください。それは1つのアイデアです。 –

    +0

    提案していただきありがとうございます。私はアプリケーションサーバーにいるので接続プールメカニズムを使用しているので、コード化する必要はありません。コーディングはコードのオーバーロードを意味し、おそらくサポートを失います。私は何かを完全に夢中にしようとはしていないし、私は現在のツールでそれを達成する簡単な方法がないことに驚いている。 – mbutton77

    答えて

    0

    適切な解決策を見つけようと長い時間がたっても、このメカニズムがリスナーに強く依存していることは確かです。リスナーが停止している場合のみ、フェールオーバーメカニズムが正常に機能します。
    これを知ると、私は最終的にアプリケーションコードに触れることなく、独自のソリューションを実装することに決めました。

    オリジナルのリスナーで再生できないため、Dataguardが操作を実行するために使用したため、すべてのリスナーを複製しました。

     
    jdbc:oracle:thin:@ 
        (DESCRIPTION_LIST= 
        (FAILOVER=on) 
        (LOAD_BALANCE=off) 
        (DESCRIPTION= 
         (ADDRESS= 
         (PROTOCOL=TCP) 
         (HOST=DB1) primary 
         (PORT=1531)) 
         (CONNECT_DATA= 
          (SERVER=DEDICATED) 
          (SID=MySID)) 
         ) 
        (DESCRIPTION= 
         (ADDRESS= 
         (PROTOCOL=TCP) 
         (HOST=DB2) secondary 
         (PORT=1531)) 
         (CONNECT_DATA= 
          (SERVER=DEDICATED) 
          (SID=MySID)) 
         ) 
        ) 
    

    :たとえば は、ポート1521上のLISTENER_DB1のために、私は、アプリケーションの観点から、私の設定は、その後になっポートで1531

    をLISTENER_DB1_FO(ご想像の通りFOがフェイルオーバーの略)を作成しました私を少し助けてくれた同僚のおかげで、私はデータベースの役割がプライマリかどうかをチェックするスクリプトを書いています(DBがマウントされていても動作します)。その答えから、私のスクリプトは、関連するリスナーを開始または停止します。

    #! /bin/bash export ORACLE_HOME=<YOUR_HOME> export ORACLE_BIN=$ORACLE_HOME/bin/ DATABASE_ROLE() { export ORACLE_SID=$1 request='SELECT DATABASE_ROLE FROM V$DATABASE' result=`$ORACLE_BIN/sqlplus -silent/as sysdba << EOF set pages 0 feedback off
    ${request}; exit EOF` echo ${result} } for DBNAME in DB1 DB2 DB3 do $ORACLE_BIN/lsnrctl status LISTENER_${DBNAME}_FO > /dev/null return_status=$? if [ "$(DATABASE_ROLE ${DBNAME})" != 'PRIMARY' ];then echo "DB ${DBNAME} is secondary" if [ $return_status -eq 0 ];then $ORACLE_BIN/lsnrctl stop LISTENER_${DBNAME}_FO fi else echo "DB ${DBNAME} is primary" if [ $return_status -eq 1 ];then $ORACLE_BIN/lsnrctl start LISTENER_${DBNAME}_FO fi fi done

    それから私は、そのスクリプトをcronned。唯一の「欠点」は、2回のcron実行の最小間隔が1分であることです。あなたの不具合なら、あなたのFailOver検出には59秒かかることがあります。

    しかし、私たちは数日間それを試してきましたが、それは魅力的です。

    誰かが正しい解決策または良いアイデアを持っている場合は、躊躇しないでください!おかげさまで

    関連する問題