[转帖]Oracle与防火墙
https://www.laoxiong.net/oracle_and_firewall.html
最近有两次Oracle数据库故障与防火墙有关。这里的防火墙是硬件网络防火墙,而不是软件防火墙。
先说说简单的。一个运行在Windows系统上的Oracle 9i,客户端不能连接数据库,但是用tnsping测试没有问题。解决问题的办法很简单,但是我们仍然需要了解一下引起这个问题的原因。
这个问题首先得从客户通通过监听连接数据库的整个过程说起,此处指专用服务器连接模式:
- 服务器上的监听进程在1521端口上进行侦听
- 客户端发起一个数据库连接请求
- 监听进程fork一个Oracle服务器进程(Server Process),也可称之为影子进程 (Shadow Process)。服务器进程选择一个大于1024的端口号进行侦听,监听进程把这个端口号发回到客户端,要求客户端重新连接这个指定的端口。
- 客户端重新连接监听指定的新端口,也就是重新进行连接。
- 客户端与Server Process直接对话,不再通过监听,进行会话认证(登录),执行SQL等等。
从上述过程可以看到,客户端最终连接的端口实际上并不是1521。由于防火墙一般只开放了几个端口,对Oracle数据库只开放了1521端口,这样在客户端进行第二次连接时,不能通过防火墙,导致连接数据库失败。
值得庆幸的是,只有Windows平台上的9i及以下版本的Oracle才会有这个问题。Oracle在Linux以及Unix平台下,多个进程间可以对端口进行复用,Oracle Server Process仍然使用的是跟监听进程一个端口(1521)。通过在linux使用strace跟踪客户端连接数据库的过程可以发现,客户端只连接了一次,并没有进行第二次连接,与上面描述的流程相比已经发生了变化。在Windows平台上,10g及以上版本的库,也同样利用端口复用,避免了这样的问题。
那么Windows上运行的Oracle 9i怎么解决这个问题呢?答案很简单,在Windows注册表的\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEn(这里n指Oracle Home的序号,只有一个Oracle Home时是0)键下面增加一项USE_SHARED_SOCKET,其值为TRUE。然后重启监听及Oracle服务(注意要重启Oracle的服务,而不仅仅是重启数据库),就可以解决此问题。实际上10g就是默认USE_SHARED_SOCKET为TRUE。
对于这种问题,或者是让防火墙打开针对数据库主机的所有端口访问,也能解决。但是这种方案往往会被负责安全的人否决。
下面这个由防火墙导致的问题,就相对复杂一点了。
某个应用经常报ORA-3113错误,检查发现ORA-3113来源于数据库的一个db link。为了方便下面的描述,将应用直接连接的数据库称为DB_A,DB_A通过db link连接的对端的数据库称为DB_B。在DB_B主机上没有发现任何有关的trace和日志,应用执行的SQL也是非常简单的SELECT语句,返回的数据量也不大。但出错的语句并不是固定的某一个SQL。在应用连接的数据库DB_A上做ORA-3113 error stack的trace,也没有发现有价值的东西。
导致ORA-3113错误的原因很多。大家可以参考ITPUB上的一篇贴子《ORA-03113错误分析》。
在这个ORA-3113错误的问题中,数据库DB_B没有任何日志,出现这种情况的一个很可能的原因是,DB_B上的Server Process已经中止,但又不是在执行SQL过程中出错异常中止了,比如被KILL掉,网络连接中断等。被KILL掉这个原因,首先被排除,因为这个错误出现得很多,每天都有。询问维护人员,称也没有进行过KILL操作。那么最大的可能性应该是网络了。顺着这条线索,我们在DB_A上用netstat -na命令检查到DB_B的网络连接,与DB_B中v$session中的会话进行比较,发现DB_A连接到DB_B的数据库会话,比netstat 命令看到的网络连接数少得多。
这是一个重大的突破。首先要怀疑的是防火墙。因为防火墙导致Oracle连接异常的情况非常多。访问数据库的DBA,这两个数据库分别在不同的业务网络中,中间使用了Cisco的防火墙。请防火墙维护工程师检查防火墙的设置,发现防火墙设置了TCP连接超时(这个术语是防火墙工程师告诉给我的,实际上我个人认为这个术语字面含义跟其实际的作用相差较大)设置为1小时。也就是,对于通过防火墙的所有TCP连接,如果在1小时内没有任何活动,就会被防火墙拆除,这样就会导致连接中断。在拆除连接时,也不会向连接的两端发送任何数据来通知连接已经拆除。
而出问题的业务系统,使用的高峰期是在正常的工作时间内,最高时会导致DB_A会产生数十个连接到DB_B。但是在业务低谷期或经过一个晚上,防火墙将拆除大部分甚至是所有的连接。而下一次使用时,应用通过连接池选择DB_A中的一个会话,这个会话的db link之前已经连接到DB_B,但是网络连接已经被防火墙拆除,但是这个会话并不知道,仍然会认为这个连接有效,结果试图向DB_B提交SQL时,就出现了ORA-3113错误。
实际上,很多使用网络连接的应用,可以使用称之为KeepAlive的特性,来保持TCP连接的活动性。在打开一个连接时,通过setsockopt函数,设置socket为SO_KEEPALIVE,这样,在OS层,如果一个TCP连接在指定的时间内没有活动,会发送一个探测包到连接的对端,检测连接的对端是否仍然存在。如果这个时间小于防火墙中设置的“超时”时间,防火墙就会检查到连接中仍然有数据,就不会断开这个连接。
操作系统中keep alive的相关设置,不同的系统有不同的设置方法。比如在Linux中,在sysctl中设置net.ipv4.tcp_keepalive_time = 120,表示探测时间为120秒,即2分钟。在AIX中,通过no命令将tcp_keepidle参数设置为240,表示探测时间为120秒。注意AIX中这个参数的单位是1/2秒,而在Linux中是1秒。
不幸的是,通过在Linux和AIX上对Oracle进行跟踪发现,Oracle客户端连接数据库时(包括Oracle Server作为客户端连接DB LINK上的数据库),并没有在TCP Socket上打开SO_KEEPALIVE,因此不能通过设置操作系统的tcp keep alive的设置来解决此问题。
(Update 2009-08-06:在对监听的跟踪时发现,连接时客户端没有设置SO_KEEPALIVE,但是Server Process却对TCP Socket设置了SO_KEEPALIVE属性。)
还好Oracle提供了类似的机制。也就是DCD(Dead Conneciton Detection)。在$ORACLE_HOME/network/admin/sqlnet.ora文件中增加如下一行:
sqlnet.expire_time=NNN
这里NNN为分钟数,Oracle数据库会在会话IDLE时间超过这个指定的时间时,检测这个会话的对端(即客户端)是否还有效。避免客户端由于异常退出,导致会话一直存在。
因此,我们可以通过在DB_B数据库中的sqlnet.ora文件中设置expire_time来解决上面提到的ORA-3113问题。
关于Tcp KeepAlive,DCD以及防火墙,可参考metalink的文档257650.1。
[转帖]Oracle与防火墙的更多相关文章
- 在Linux系统下远程连接oracle的防火墙设置
在Linux系统要远程连接Oracle的防火墙设置方法: 打开5801至5810 端口用于vnc iptables -I INPUT -p tcp --dport 5801:5810 -j ACCEP ...
- [转帖]Oracle 11G RAC For Windows 2008 R2部署手册
Oracle 11G RAC For Windows 2008 R2部署手册(亲测,成功实施多次) https://www.cnblogs.com/yhfssp/p/7821593.html 总体规划 ...
- [转帖]Oracle 补丁体系(PSR/PSU/CPU) 及 opatch 工具 介绍
Oracle 补丁体系(PSR/PSU/CPU) 及 opatch 工具 介绍 原文:http://blog.csdn.net/tianlesoftware/article/details/58095 ...
- [转帖]Oracle 各个版本的升级路线图
从oracle 7开始(甚至更早版本)到oracle 9iR2. 来源: https://blog.csdn.net/cymm_liu/article/details/11647533 http:// ...
- [转帖]Oracle 12cR2使用经验
大规模升级来临,谈谈Oracle 12cR2使用经验 随着2019年2月13日,Oracle 19c (Oracle 12.2.0.3) for Exadata 版本发布,Oracle 12cR2体系 ...
- [转帖]Oracle 裁员史:技术人死于重组,卒于云计算
Oracle 裁员史:技术人死于重组,卒于云计算 https://www.infoq.cn/article/tm-mcdHCPCI4eEwr6dbY 大厂裁员 我妈妈也总担心我没工作了 怎么还房贷 田 ...
- [转帖]oracle改版sql server问题点汇总
https://www.cnblogs.com/zhangdk/p/oracle_sqlserver.html 只记得 最开始的时候看过 没有具体的了解里面的特点 原作者总结的很好 留下来 以后说不定 ...
- 转帖 Oracle 主键的处理方法 http://www.cnblogs.com/Richardzhu/p/3470929.html
Oracle之主键的创建.添加.删除操作 一.创建表的同时创建主键约束 1.1.无命名 SQL> create table jack (id int primary key not null ...
- [转帖] Oracle数据库 通过触发器 限制登录ip
转帖 From https://yq.aliyun.com/ziliao/123360 create or replace trigger logon_ip_control after logon o ...
- [转帖]Oracle字符集的查看与修改 --- 还未尝试 找个周六 试试.
Oracle 字符集的查看和修改 感谢原作者 改天试试 https://www.cnblogs.com/rootq/articles/2049324.html 一.什么是Oracle字符集 Oracl ...
随机推荐
- 非工程师指南: 训练 LLaMA 2 聊天机器人
引言 本教程将向你展示在不编写一行代码的情况下,如何构建自己的开源 ChatGPT,这样人人都能构建自己的聊天模型.我们将以 LLaMA 2 基础模型为例,在开源指令数据集上针对聊天场景对其进行微调, ...
- 码农的转型之路-PLC异地组网与远程控制
PLC异地组网与远程控制,需求是基于园子认识的朋友提供,大体是实现PLC多个局域网异地组网,并实现远程控制.大屏展示.手机端控制.预警推送等功能.其他就是可以方便二次开发界面,以满足不同客户的需求. ...
- 文心一言 VS 讯飞星火 VS chatgpt (23)-- 算法导论4.2 5题
五.V.Pan 发现一种方法,可以用 132 464 次乘法操作完成 68 x 68 的矩阵相乘,发现另一种方法,可以用 143 640 次乘法操作完成 70 x 70 的矩阵相乘,还发现一种方法,可 ...
- 让当前元素的width或者height达到父元素的尺寸
double.infifinity 和double.maxFinite可以让当前元素的width或者height达到父元素的尺寸: 区别: 我想成为我的父母所允许的最大的(double.infinit ...
- Java PDF书签——添加、编辑、删除、读取书签
概述 本文介绍通过Java程序来操作PDF书签,根据对书签的不同操作要求,分以下情况来介绍: 1. 添加书签(包括添加一级书签.多级子书签) 2. 编辑书签(包括重置书签标题.书签样式等) 3. 删除 ...
- 【云享·人物】华为云AI高级专家白小龙:AI如何释放应用生产力,向AI工程化前行?
摘要:AI技术发展,正由应用落地阶段向效率化生产阶段演进,AI工程化能力将会不断深入业务,释放企业生产力. 本文分享自华为云社区<[云享·人物]华为云AI高级专家白小龙:AI如何释放应用生产力, ...
- 探索开源工作流引擎Azkaban在MRS中的实践
摘要:本文主要介绍如何在华为云上从0-1搭建azkaban并指导用户如何提交作业至MRS. 本文分享自华为云社区<开源工作流引擎Azkaban在MRS中的实践>,作者:啊喔YeYe. 环境 ...
- 智能电视APP鲜时光,如何应用AB测试打造极致的用户观看体验?
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 数字技术的发展让智能电视普及率大幅提升,2023年智能电视的市场渗透率已超90%,与智能电视相匹配的各类应用 ...
- Filebeat的安装和使用(Linux)
安装 filebeat-7.9.3(与Elasticsearch版本一致) 考虑到Elasticsearch 比较费硬盘空间,所以目前项目中只上传error的日志.详细日志还是去具体服务器查看(没有专 ...
- JDk 与 ADB 环境变量配置
### Java环境变量配置 首先,JDK是整个Java的核心,包括了Java运行环境,一推Java工具和Java基础的类库. 网址:https://www.oracle.com/technetwor ...