怎样实现Oracle 19c Data Guard环境下的自动IP漂移_利用Role-Based数据库服务

2026-05-21数据库290619

Data Guard自身不能实现自动IP漂移,必须依赖Role-Based服务+客户端TAF或VIP工具(如Keepalived);Role-Based服务需用DBMS_SERVICE.CREATE_SERVICE按角色动态创建并启动,TAF连接串必须显式配置FAILOVER_MODE=SESSION或SELECT,且监听器须禁用静态注册、仅支持SERVICE_NAME动态路由。

不能靠data guard自身实现自动ip漂移,必须配合role-based服务 + 客户端taf或vip层工具(如keepalived)才能落地。 oracle dg只管数据同步和角色切换,网络层的ip绑定、监听重定向、连接重试全靠外部机制兜底。漏掉服务注册逻辑或客户端未启用taf,切换后应用照样连不上。

Role-Based服务必须用DBMS_SERVICE.CREATE_SERVICE动态注册

静态service_names参数在角色切换后不会自动更新,主备库启动时都按各自配置注册服务,导致监听器里始终存在两个同名服务,客户端随机连到已降级的旧主库上。

  • 必须在主库执行:DBMS_SERVICE.CREATE_SERVICE创建带ROLE = 'PRIMARY'的服务,例如'orcl_primary'
  • 在备库执行相同语句但ROLE = 'PHYSICAL_STANDBY',例如'orcl_standby'
  • 服务创建后需显式DBMS_SERVICE.START_SERVICE,且要确保srvctl add service(RAC场景)或ALTER SYSTEM REGISTER触发监听器刷新
  • 验证:切换前后分别查V$ACTIVE_SERVICES,确认只有当前角色对应的服务处于STATUS = 'RUNNING'

TAF客户端连接串里必须指定FAILOVER_MODE=SESSION+TYPE=SELECT

只配SERVICE_NAME不等于启用TAF;没声明FAILOVER_MODE,Oracle客户端根本不会尝试重连,报错直接抛给应用层。

  • 连接串示例:(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=scan01)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl_primary)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=180)(DELAY=5))))
  • TYPE=SELECT是关键——只有它支持会话内查询重试;TYPE=SESSION仅重连新会话,老事务全丢
  • RETRIESDELAY必须大于DG切换耗时(实测19c switchover通常40~90秒),否则重试未完成就超时
  • Java应用需额外设置oracle.jdbc.replay.enable=true,否则TAF对JDBC无效

监听器必须支持服务名动态路由,禁用静态注册

如果listener.ora里写了SID_LIST_LISTENER硬编码实例,切换后监听器仍把请求转给已关闭的原主库进程,连接直接拒绝。

oracle知识库

oracle知识库下载

下载

  • 主备库tnsnames.ora中所有条目必须用SERVICE_NAME而非SID
  • listener.ora中删掉SID_LIST_LISTENER段,只保留LISTENER基本定义
  • 确认LOCAL_LISTENER参数指向本机监听地址,且REMOTE_LISTENER指向SCAN(RAC)或另一节点(单机DG)
  • 验证:lsnrctl status输出里应只看到SERVICE_NAME条目,无SID残留

最易被忽略的是服务状态与监听器状态的“时间差”:即使DBMS_SERVICE.START_SERVICE返回成功,监听器可能延迟数秒才感知变更;而switchover命令执行后,原主库瞬间shutdown,新主库若未等监听器完成服务注册就开放连接,应用必然失败。务必在ALTER DATABASE OPEN之后加sleep 10再通知应用层切流。

标签: