ORA-03113: ~ 2 小时 10 分钟后通信通道上的文件结束

ORA-03113: end-of-file on communication channel after ~ 2 hours and 10 mins

我有一个带有过程的 sql 脚本。我 运行 它使用 sqlplus -s @script.sql logfile.log myparam1 myparam2 但是大约 2 小时 10 分钟后,我的脚本以

结尾
ERROR:
ORA-03114: not connected to ORACLE 


DECLARE
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel 
Process ID: 12345 
Session ID: 33 Serial number: 54321 

我有以下 tcp 设置

-bash-4.1$ cat /proc/sys/net/ipv4/tcp_keepalive_time (which is two hours)
7200
-bash-4.1$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
-bash-4.1$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

当脚本 运行ning 时,我检查了我端建立的 TCP 连接,但在数据库端(数据库服务器机器)没有这样的连接。

我的理论是数据库服务器以某种方式断开了连接。当我的系统在 2 小时(7200 秒)后发送第一个 keepalive 探测时,它发现连接不再活跃并关闭连接和脚本 returns.

我无法理解为什么数据库系统会断开连接? 数据库端是否有任何设置可以增加冗长程度?或者这可能与某些防火墙设置有关?此外,在 2 小时 10 分钟内,我们可以猜测 2 小时部分来自 tcp_keepalive_time,即 10 分钟部分。任何数据库端重试?

编辑:DBA 和我查看了这个问题,我看到我这边的 TCP 连接是 ESTABLISHED,他没有看到我这边有任何连接。

如果我们在那段时间没有任何 activity,大约两个小时后我们的防火墙会断开我们的 Pro*C 连接,我们会遇到类似的情况。我们的解决方案是:

select 1 from dual;

每个数据库连接每 15 分钟一次,以保持活动状态。

如果我没记错的话,您上面提到的 tcp 保持活动时间仅在连接具有使用 SO_KEEPALIVE 的 setsockopt 调用时使用。由于与Oracle的实际连接是由Oracle管理的,我们无从知晓是否设置。

在查看此内容时,我在网络上的一些地方 (this and this) 看到 $ORACLE_HOME/network/admin/sqlnet.ora 文件中对 sqlnet.expire_time=minutes_to_check 的引用。他们说:

With this parameter in place, after 10 minutes of inactivity, the server send a small 10 bytes probe packet to the client. If this packet is not acknowledge, the connection will be closed...

下次我引起我们的 DBA 的注意时,我将不得不让他们更改此值并查看它如何影响事情。后来在第二个 link,他们说:

If the SQLNET.EXPIRE_TIME is less than the FW connection idle time-out, then the firewall will consider this packet as activity, and the idle time-out (firewall blackout) will never happen until both the client and the server processes are alive.

我希望这正是我们所需要的。

  1. 首先,您应该检查您的 alert.log,以发现期间的任何错误 这次。
  2. 然后,有两种方法可以使您的活动会话断开连接。
    (1)SQLNET.EXPIRE_TIME < 120
    (2)初始化参数resource_limit为真,你的profile's(dba_users + dba_profiles ) idle_time < 120

通信通道上的文件结束很少是数据库方面的问题。 如果您怀疑数据库端有问题,请通过 gv$session 监控会话 activity。如果会话在特定语句上是 "hung" 或 long-运行,您将能够立即发现。失去与数据库的连接并不少见,尤其是在网络不稳定的情况下。

我们尝试将 SQLNET.EXPIRE_TIME 设置为 10 分钟。但它没有用。我们启动了数据库服务器机器,但它仍然无法正常工作。也许一些最新的防火墙可能不会将 DCD 数据包视为文章 mentioned in the article 中提到的有效流量(也由上面的 @user1683793 给出)。 最后,我们将 keepalive 时间更改为 25 分钟(在客户端机器上),这样 tcp 连接上就会有一些流量。幸运的是,防火墙似乎将保活数据包视为流量。

-bash-4.1$ cat /proc/sys/net/ipv4/tcp_keepalive_time
1500