Oracle:JDBC TNS URL连接无法通过故障转移,因为侦听器仍在响应

时间:2017-07-17 16:09:59

标签: oracle listener failover tns dataguard

我面临一个愚蠢的问题,但经过一段时间在线搜索和试验,我开始失去希望。
由于Dataguard,我有两个配置为副本的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获得了连接。

但数据保护的重点是执行自动故障转移。
但如果我被迫杀死听众:

  1. 这不是我所期待的:)
  2. 切换可能不起作用,因为它使用侦听器来执行此操作
  3. 如果有人对正确的配置有所了解,我很感兴趣!

    提前致谢。

2 个答案:

答案 0 :(得分:1)

经过长时间努力寻找合适的解决方案后,我非常确定这种机制强烈依赖于侦听器:只有在侦听器停止时,故障转移机制才能正常工作
知道了,我最终决定实现自己的解决方案,而不涉及应用程序代码。

由于我无法使用原始侦听器,因为Dataguard使用它们来执行其操作,所以我复制了所有侦听器。 例如,对于端口1521上的LISTENER_DB1,我在端口1531上创建了LISTENER_DB1_FO(FO代表您可能已经猜到的FailOver)。

从应用程序的角度来看,我的配置变为:

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))
        )
    )

感谢一位帮助我的同事,我编写了一个脚本,用于检查数据库角色是否为主要角色(即使数据库处于挂载状态也能正常工作)。从这个答案来看,我的脚本将启动或停止相关的监听器。

print q1 == q2

然后我责备了那个剧本。唯一的“缺点”是两个cron执行之间的最小间隔是一分钟。如果你运气不好,你的FailOver检测可能需要59秒才能被检测到。

但是我们已经测试了好几天了,它就像一个魅力。

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

答案 1 :(得分:0)

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