首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >网络层阻塞引发的 “嫁祸式报错”——Oracle 与备库 TNS 连接被抢占 / 超时,却伪装成 “设备权限 / 存储故障”

网络层阻塞引发的 “嫁祸式报错”——Oracle 与备库 TNS 连接被抢占 / 超时,却伪装成 “设备权限 / 存储故障”

作者头像
用户3107127
发布2026-07-09 15:53:31
发布2026-07-09 15:53:31
150
举报

巡检 Oracle 11G ADG 环境时,突然弹出的报错让人心凉半截 —— 主备库同步直接中断,DG Broker 红屏告警,一堆错误码看得人眼花缭乱:

代码语言:javascript
复制
DGMGRL> show configuration;

Configuration - ycjj2dg

  Protection Mode: MaxPerformance
  Databases:
    ycjj2dg - Primary database
      Error: ORA-16778: redo transport error for one or more databases  # redo传输失败
    ycjj    - Physical standby database
      Warning: ORA-16857: standby disconnected from redo source for longer than specified threshold  # 备库失联超阈值
Fast-Start Failover: DISABLED
Configuration Status:
ERROR

更诡异的是,查询主库传输通道状态时,跳出一个 “设备相关” 的报错,直接把排查方向往存储上带:

代码语言:javascript
复制
SQL>select error,statusfrom gv$archive_dest where dest_id=1;

ERROR                                                   STSTUS
-----------------------------------------------------------------------------------
ORA-07286: sksagdi: cannot obtain device information.       ERROR  # 设备信息获取失败?

翻主库 trace 日志,全是 FAL 归档失败的哀嚎,仿佛存储真的出了大问题:

代码语言:javascript
复制
FAL[server, ARC0]: FAL archive failed, see trace file.
ARCH: FAL archive failed. Archiver continuing
ORACLE Instance ycjj - Archival Error. Archiver continuing.

备库更惨,直接卡在日志缺口上,补都补不上:

代码语言:javascript
复制
Fetching gap sequence in thread 1, gap sequence 38218-38218
FAL[client]: Failed to request gap sequence
 GAP - thread 1 sequence 38218-38218
FAL[client]: All defined FAL servers have been attempted.

主库 ARC 进程日志更是直接甩锅 “设备”,让人不得不怀疑存储权限、挂载出了问题:

代码语言:javascript
复制
Error 7286 creating standby archive log file at host 'ycjj'
ARC0: Attempting destination LOG_ARCHIVE_DEST_2 network reconnect (7286)
ARC0: Destination LOG_ARCHIVE_DEST_2 network reconnect abandoned

2. 排查迷局:死磕存储 3 小时,竟被报错 “戏耍”

这个 ADG 环境已经稳定运行半个月,配置按理说没问题,但 ORA-07286 明晃晃的 “device information” 字样,还是把我骗进了死胡同:

  • 先查备库归档目录 /u01/app/oracle/archivelog 权限:oracle:oinstall 读写权限拉满,没问题;
  • 再检查存储挂载:df -h 显示空间充足,挂载点稳定,没半点异常;
  • 甚至重启了主备库、监听,报错依旧,ORA-07286 像块狗皮膏药甩不掉;
  • 怀疑备库文件系统损坏,跑了 fsck 检查,结果一切正常……

就在我对着 “设备故障” 四个字怀疑人生时,主库 alert 日志突然刷屏式弹出一堆致命错误,瞬间打破僵局 —— 这哪里是存储问题,分明是网络被攻击了!

代码语言:javascript
复制
***********************************************************************
Fatal NI connect error 12170.
  VERSION INFORMATION:
TNS for Linux: Version 11.2.0.4.0 - Production
  Tns error struct:
    ns main err code: 12535
TNS-12535: TNS:operation timed out  # TNS连接超时!
    nt main err code: 505
TNS-00505: Operation timed out
    nt secondary err code: 110
  Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=59.125.128.214)(PORT=55816))  # 外部陌生IP!
***********************************************************************

一眼扫过去,全是 59.125.128.xx 这类外部 IP 疯狂发起连接,短短 1 分钟就有几十条超时记录 ——原来 ORA-07286 是个影帝级 “嫁祸犯”! 网络被恶意扫描搞瘫痪,却伪装成 “设备故障”,把我耍得团团转。

3. 真相大白:“嫁祸链条” 全拆解,网络黑手才是真凶

结合日志细节,整个 “嫁祸骗局” 的逻辑瞬间清晰,这根本不是存储问题,而是一场由外部恶意连接引发的连锁反应:

🔗 嫁祸链条:外部攻击 → 网络阻塞 → 报错嫁祸 → ADG 瘫痪

  1. 外部恶意扫描抢占资源:大量陌生 IP(如 59.125.128.214)疯狂扫描主库 1521 端口,占用 Oracle 监听进程、网络端口,导致监听 “忙到没空” 处理主备库的正常连接;
  2. 主备 TNS 连接被阻断:主库 LGWR/ARC 进程向备库传输 redo 日志时,TNS 连接因资源被占、网络拥堵超时,触发 TNS-12535/Fatal NI connect error 12170
  3. Oracle 报错 “张冠李戴”:底层网络连接失败,Oracle 却给出模糊的 “设备信息获取失败”(ORA-07286),把锅甩给存储 / 设备;
  4. ADG 同步彻底崩了:redo 传输超时 → 备库缺日志 → FAL 补缺口失败 → DG Broker 报 ORA-16778/ORA-16857,同步中断。

简单说:网络被 “碰瓷”,存储背了锅,ADG 躺了枪

4. 紧急破案:3 步锁死黑手,ADG 10 分钟复活

既然真相是外部攻击 + 网络阻塞,那就对症下药,先斩黑手,再修连接:

第一步:给恶意 IP 下 “死刑令”,防火墙 + 白名单双重封锁

外部 IP 是罪魁祸首,先断了它们的路,主备库同时执行:

1. 防火墙精准拦截(root 用户)

仅允许主备库内网 IP 访问 1521 端口,其他 IP 直接拉黑:

代码语言:javascript
复制
# 主库(IP:192.168.1.10)/备库(IP:192.168.1.20)均执行
iptables -F  # 清空旧规则
# 允许主备库互访1521
iptables -A INPUT -p tcp -s192.168.1.10 --dport1521-j ACCEPT
iptables -A INPUT -p tcp -s192.168.1.20 --dport1521-j ACCEPT
# 拒绝所有其他IP访问1521,一刀切!
iptables -A INPUT -p tcp --dport1521-j DROP
# 保存规则,重启不失效
service iptables save
# 验证:看到两条ACCEPT和一条DROP即生效
iptables -L-n | grep1521

2. Oracle 白名单兜底(sqlnet.ora)

防火墙之外再加一道保险,只让信任的 IP 连数据库:

编辑主备库 $ORACLE_HOME/network/admin/sqlnet.ora,添加:

代码语言:javascript
复制
tcp.validnode_checking = YES  # 启用IP校验
tcp.invited_nodes = (192.168.1.10, 192.168.1.20, localhost)  # 白名单:主备库+本地
tcp.excluded_nodes = (all)  # 黑名单:所有其他IP

重启监听生效:

代码语言:javascript
复制
lsnrctl stop
lsnrctl start

3. 验证封锁效果

查看监听日志,确认外部 IP 已被拦截:

代码语言:javascript
复制
tail -f $ORACLE_BASE/diag/tnslsnr/$(hostname)/listener/trace/listener.log

✅ 预期:再也没有 59.125.128.xx 的连接记录,只有主备库 IP 的正常访问。

第二步:修复主备 TNS 连接,给传输 “上保险”

阻断外部干扰后,优化 Oracle 网络参数,避免正常连接再超时:

1. 优化 sqlnet.ora(主备库)

添加 / 修改以下参数,延长超时时间、提升传输稳定性:

代码语言:javascript
复制
# 入站连接超时(监听接收连接,默认60秒→120秒)
sqlnet.inbound_connect_timeout = 120
# 出站连接超时(主库连备库/补gap,默认无→120秒)
sqlnet.outbound_connect_timeout = 120
# 传输数据超时(避免redo传输因延迟断开,300秒)
sqlnet.recv_timeout = 300
sqlnet.send_timeout = 300
# 禁用TCP延迟确认(小数据包传输提速,即时生效)
tcp.nodelay = YES
# 启用TCP保活(10秒探测一次死连接,释放资源)
sqlnet.expire_time = 10

2. 优化 listener.ora(主备库)

提升监听并发能力,避免连接排队超时:

代码语言:javascript
复制
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.10)(PORT = 1521))  # 替换为主/备库IP
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

# 监听握手超时(120秒,与sqlnet.ora呼应)
listener_net_timeout_LISTENER = 120
# 监听队列大小(默认50→200,提升并发处理)
queuesize_LISTENER = 200
# 禁用IPv6(避免干扰,仅用IPv4)
IP_VERSION = 4

# 静态注册(确保DG Broker识别实例)
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = ycjj)  # 实例名
      (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
    )
  )

3. 重启生效

代码语言:javascript
复制
# 重启监听
lsnrctl stop && lsnrctl start
# 重启数据库(让sqlnet.ora参数生效)
sqlplus / as sysdba
SHUTDOWN IMMEDIATE;
STARTUP;

第三步:验证 + 补缺口,ADG 满血复活

1. 测试 TNS 连通性(主备互测)

持续 30 次 tnsping,无超时即正常:

代码语言:javascript
复制
# 主库测备库
for i in {1..30}; do tnsping ycjj; echo "第 $i 次测试"; sleep 1; done
# 备库测主库
for i in {1..30}; do tnsping ycjj2dg; echo "第 $i 次测试"; sleep 1; done

✅ 预期:全是 OK (xx msec),无 TNS-12535 超时。

2. 补日志缺口 + 验证传输

代码语言:javascript
复制
-- 主库切换日志,触发归档传输
sqlplus / as sysdba
ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM SWITCH LOGFILE;

-- 查看归档传输状态(STATUS=TRANSMITTED,ERROR为空)
SELECT SEQUENCE#, DEST_ID, STATUS, ERROR FROM V$ARCHIVED_LOG WHERE DEST_ID=2 ORDER BY SEQUENCE# DESC;

3. DG Broker 验证

代码语言:javascript
复制
dgmgrl sys/密码@ycjj2dg as sysdba
DGMGRL> SHOW CONFIGURATION;

✅ 预期输出:

代码语言:javascript
复制
Configuration - ycjj2dg
  Protection Mode: MaxPerformance
  Databases:
    ycjj2dg - Primary database
    ycjj    - Physical standby database
Fast-Start Failover: DISABLED
Configuration Status:
SUCCESS

5. 进阶加固:操作系统 + 长期防护,杜绝 “二次碰瓷”

1. 操作系统 TCP 优化(主备库 root 用户)

编辑 /etc/sysctl.conf,提升网络稳定性:

代码语言:javascript
复制
vi /etc/sysctl.conf
添加:
net.ipv4.tcp_keepalive_time = 600  # TCP保活时间(10分钟)
net.ipv4.tcp_keepalive_intvl = 60  # 探测间隔(60秒)
net.ipv4.tcp_keepalive_probes = 3  # 探测3次失败则断开
net.ipv4.tcp_syn_retries = 3      # 减少SYN重试,避免超时等待

# 生效配置
sysctl -p

2. 长期防护(生产环境必做)

  1. 固化防火墙规则:定期检查 iptables 规则,防止被误修改;
  2. 启用 Oracle 审计:监控异常连接,提前预警恶意扫描:
代码语言:javascript
复制
ALTER SYSTEM SET audit_trail=DB,EXTENDED SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
  1. 监听日志轮转:避免日志过大影响性能,配置 logrotate 自动切割;
  2. 网络质量监控:用 mtr 主库IP 备库IP 持续监控丢包 / 延迟,异常及时告警。

6. 血的教训:这些坑千万别踩!

  1. 别被报错字面意思骗了:看到 ORA-07286 的 “device” 就死磕存储,忽略网络排查 ——Oracle 底层报错有时会 “张冠李戴”;
  2. 1521 端口必须上锁:公网暴露的 Oracle 监听,不做 IP 限制就是给恶意扫描递 “菜刀”;
  3. DG 故障先查网络:redo 传输、FAL 补缺口全依赖 TNS 连接,网络不通,配置再对也白搭;
  4. 双重防护才靠谱:防火墙 + sqlnet.ora 白名单,缺一不可,避免单一防护失效。

这场 “嫁祸式报错” 闹剧,最终以 “拉黑恶意 IP + 优化网络” 收场。ADG 同步恢复正常,但也给所有 DBA 提了个醒:遇到诡异报错时,别钻牛角尖,换个角度查日志,真相可能就在 “刷屏的超时记录” 里!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ByteHouse 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2. 排查迷局:死磕存储 3 小时,竟被报错 “戏耍”
  • 3. 真相大白:“嫁祸链条” 全拆解,网络黑手才是真凶
    • 🔗 嫁祸链条:外部攻击 → 网络阻塞 → 报错嫁祸 → ADG 瘫痪
  • 4. 紧急破案:3 步锁死黑手,ADG 10 分钟复活
    • 第一步:给恶意 IP 下 “死刑令”,防火墙 + 白名单双重封锁
      • 1. 防火墙精准拦截(root 用户)
      • 2. Oracle 白名单兜底(sqlnet.ora)
      • 3. 验证封锁效果
    • 第二步:修复主备 TNS 连接,给传输 “上保险”
      • 1. 优化 sqlnet.ora(主备库)
      • 2. 优化 listener.ora(主备库)
      • 3. 重启生效
    • 第三步:验证 + 补缺口,ADG 满血复活
      • 1. 测试 TNS 连通性(主备互测)
      • 2. 补日志缺口 + 验证传输
      • 3. DG Broker 验证
  • 5. 进阶加固:操作系统 + 长期防护,杜绝 “二次碰瓷”
    • 1. 操作系统 TCP 优化(主备库 root 用户)
    • 2. 长期防护(生产环境必做)
  • 6. 血的教训:这些坑千万别踩!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档