DG同步中断后连接不恢复,根本原因在于FAL进程无自动重试机制,依赖SQL*Net超时与重试参数及客户端配置;需重点检查REOPEN、RETRY_COUNT、监听器超时、DNS解析、SCAN配置及防火墙会话保持。
DG同步中断后连接不恢复?先确认FAL是否启用自动重连
oracle data guard(dg)本身不提供应用层的“自动重连”,所谓“重连”实际由客户端驱动(如sql*net)或中间件控制。fal(fetch archive log)进程负责从主库拉取归档日志,但它默认不具备网络闪断后的主动重试逻辑——它只在fal_server不可达时报错退出,不会自己sleep再试。
常见错误现象:ORA-16700(standby database is not in a consistent state)、ORA-12170(TNS:Connect timeout occurred),但DG状态仍显示TRANSPORT-ON、APPLY-ON,日志里反复出现“FAL[server]: Failed to connect to primary”却无后续重试记录。
- FAL依赖SQL*Net底层超时机制,需靠
sqlnet.ora中SQLNET.RECV_TIMEOUT和SQLNET.SEND_TIMEOUT配合,但它们只控制单次连接/读写阻塞,不控制重试次数与间隔 - 真正影响FAL“重传行为”的是
FAL_CLIENT和FAL_SERVER参数值是否稳定可解析;DNS抖动或VIP漂移未及时更新会导致FAL持续失败 - 若使用SCAN或负载均衡地址,确保
TNSNAMES.ORA中对应条目启用了RETRY_COUNT和RETRY_DELAY(仅适用于Oracle 19c+ 客户端)
如何配置FAL重传间隔:没有直接命令,靠SQL*Net重试参数组合实现
Oracle DG没有类似timer connect-retry(BGP用)那样的FAL专用重试配置命令。FAL的“重试”本质是SQL*Net连接失败后,由后台进程触发的下一次FAL请求发起——这个间隔由两个隐式因素决定:FAL轮询周期 + SQL*Net建连失败后的退避策略。
实操建议聚焦以下三点:
- 调整
LOG_ARCHIVE_DEST_n中的REOPEN参数:例如REOPEN=60表示归档传输失败后,60秒后重试归档发送(间接影响FAL触发频率) - 在
sqlnet.ora中设置SQLNET.OUTBOUND_CONNECT_TIMEOUT=30(避免长时间卡在SYN等待),并搭配SQLNET.INBOUND_CONNECT_TIMEOUT=60 - 禁用
SQLNET.ALLOWED_LOGON_VERSION_SERVER等可能引发握手失败的兼容性限制,减少非网络原因的“假断连”
注意:REOPEN不是FAL专属,它作用于整个归档传输链路;FAL本身无独立超时/重试参数,强行调小REOPEN(如设为5)可能导致频繁无效连接冲击主库监听器。
JDBC/OCI应用连DG备库闪断?别只盯FAL,先看客户端重连策略
很多故障表面是DG同步中断,实则是应用连备库查询时因网络闪断直接报IO Error: Connection reset或ORA-03113,然后连接池丢弃连接、不再重试——这和FAL完全无关,属于应用层容错缺失。
典型场景:Spring Boot + HikariCP 连接备库做只读分流,网络抖动后所有请求失败,直到手动重启应用。
- HikariCP默认不开启连接测试,
connection-test-query已废弃,应改用connection-init-sql=SELECT 1 FROM DUAL+connection-timeout=3000 - 必须启用
idle-timeout和max-lifetime,防止连接池长期持有已断开的socket - Oracle JDBC thin driver 21c起支持
oracle.net.CONNECT_TIMEOUT和oracle.net.RECV_TIMEOUT,但需显式传入URL,例如:jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=xx)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xxx))(RETRY_COUNT=3)(RETRY_DELAY=10))
为什么改了参数还是没重连成功?检查三个容易被忽略的点
即使配了REOPEN、RETRY_COUNT、SQLNET.OUTBOUND_CONNECT_TIMEOUT,仍可能失效——问题常出在更底层。
- 防火墙或安全组拦截了重连SYN包:某些云厂商默认关闭“连接跟踪状态保持”,导致第二次SYN被丢弃,需开启
conntrack或对应会话保持策略 - 备库监听器
listener.ora中INBOUND_CONNECT_TIMEOUT设得太小(如默认60秒),而主库归档积压多、FAL首次连接耗时超限,直接被监听器拒绝 - 使用了Oracle RAC + SCAN,但
FAL_SERVER指向的是单节点VIP而非SCAN名,节点故障后FAL无法自动切换到存活实例
最隐蔽的一点:LOG_ARCHIVE_DEST_2里如果写了SYNC NOAFFIRM但主库强制要求SYNC AFFIRM,FAL会静默失败且不报错,日志只显示“FAL[server]: No more gap to resolve”,实际归档根本没拉过来。










