代码之家  ›  专栏  ›  技术社区  ›  mbutton77

Oracle:JDBC TNS URL连接不会故障转移,因为侦听器仍在响应

  •  1
  • mbutton77  · 技术社区  · 8 年前

    我面临着一个愚蠢的问题,但在网上搜索和实验一段时间后,我开始失去希望。

    我使用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获得一个连接,DB2成为主要连接,但由于DB1侦听器仍在运行,它的行为就好像一切正常,我最终尝试在DB1上获得一个连接,这导致了以下错误:

    ORA-01033: ORACLE initialization or shutdown in progress
    

    如果我杀死了侦听器,那么故障转移就可以工作,我从DB2获得了一个连接。


    但如果我被迫杀死听众:

    1. 这不是我所期望的:)

    如果有人知道正确的配置,我很感兴趣!

    提前谢谢。

    2 回复  |  直到 8 年前
        1
  •  1
  •   mbutton77    8 年前

    经过长时间的努力寻找合适的解决方案,我确信这种机制在很大程度上依赖于监听器: 故障转移机制只有在侦听器停止时才能正常工作 .

    由于我无法使用原始侦听器,因为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))
            )
        )
    

    #! /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写了那个脚本。唯一的“缺点”是两个cron执行之间的最小间隔是一分钟。如果您运气不好,则故障转移检测可能需要59秒。

    但我们已经测试了好几天了,效果很好。

    如果有人有正确的解决方案或更好的想法,不要犹豫!

        2
  •  0
  •   indra bhushan    7 年前

    可以在主服务器和备用服务器上使用相同的名称创建服务。可以使用服务名称修改连接。仅在当前主服务器上保持服务。