问题:
当我尝试在 Oracle 19c 数据库上通过 OpenVPN 运行收集统计信息时,如果运行时间超过一定时间,SQL Developer 不会返回典型的“PL/SQL 过程已成功完成”消息。
显然,连接在一段时间后就挂起了,我要么需要断开与 OpenVPN 的连接,要么在 Windows 任务管理器中终止 SQL Developer 来关闭它。
我的 Oracle 19c 数据库和 OpenVPN 服务器位于不同的云提供商上。
在这个数据库上运行收集统计信息通常需要大约半小时。
在 SQL Developer 上运行 gather stats 命令
我检查了:
OpenVPN 服务器上的 Iptables 和 OpenVPN 日志以及 Oracle 19c 服务器上的侦听器和警报日志上没有任何异常。
两台机器上的 net.ipv4.tcp_keepalive_time 和 net.netfilter.nf_conntrack_tcp_timeout_established 都设置为其默认值 7200(2 小时)和 432000(5 天)。
如果我以系统身份连接到数据库并运行:
从 v$sqlarea sql、v$session x 中选择 x.sid、x.serial#、x.username、x.status、x.osuser、x.machine、x.program、x.event、x.state、sql.sql_text,其中 x.sql_hash_value = sql.hash_value 和 x.sql_address = sql.address 和 x.username = 'myuser';
大约半小时后,我注意到收集统计数据的会话处于非活动状态。因此,我认为收集统计数据确实运行并成功完成,但只是没有返回上述输出消息。
我尝试过的:
在同一实例中的较小数据库上,通过 OpenVPN 运行收集统计信息将返回上述成功消息。此操作大约需要 10 分钟。
通过将我的 IP 地址添加到云提供商的防火墙并运行收集统计信息来直接(不使用 OpenVPN)连接到数据库也会返回上述成功消息。
在 Oracle 19c 服务器上生成 SSH 公钥/私钥对并在 SQL Developer 上使用 SSH 主机,但连接非常不稳定/总是重置。
设置 Dante 代理服务器。显然,SQL Developer 只能使用某种特殊的代理服务器。
使用 StrongSwan 设置 IPSEC VPN。我的 Windows 10 由于某种原因无法与其建立连接。
答案1
首先,我可以通过运行以下命令确认收集统计信息确实成功完成:
select * from v$session_longops where opname like '%Schema%' order by start_time desc;
之后我在两台服务器上运行了以下 tcpdump 命令:
tcpdump -i eth0 -A "(src <myipaddress> or src <myoracle19caddress> or dst <myipaddress> or dst <myoracle19caddress>) and not port ssh and not port openvpn and not icmp" (OpenVPN Server)
tcpdump -i eth0 -A "(src <myipaddress> or src <myopenvpnserveraddress> or dst <myipaddress> or dst <myopenvpnserveraddress>) and not port ssh and not icmp" (Oracle 19c Server)
并且发现Oracle 19c服务器确实发送了成功消息,但是OpenVPN服务器始终没有收到。
在对各个网站进行一番搜索之后,我发现我误解了 net.ipv4.tcp_keepalive_time 的实际作用。
这意味着[默认情况下] keepalive 例程等待两个小时(7200 秒) 在发送第一个保活探测之前,然后每75秒重新发送一次。
之后,我找到了托管我 OpenVPN 服务器的云提供商的网络配置。
空闲连接
[...] 为具有连接概念的 IP 协议实施 10 分钟的连接跟踪。这意味着,只要在过去 10 分钟内为该连接发送或接收了至少一个数据包,就允许与已建立连接相关联的入站数据包。如果 10 分钟或更长时间内未发送或接收该连接的数据包,则将删除空闲连接的跟踪条目。删除连接的跟踪条目后,[...] 不允许额外的入站数据包,直到至少发送了一个新的出站数据包。此连接跟踪适用于所有源和目标 - 内部和外部 IP 地址。
利用这些新信息,我通过在 Oracle 19c 服务器上运行以下命令将保持活动时间设置为小于 10 分钟的值来解决此限制:
sysctl -w net.ipv4.tcp_keepalive_time=300 net.ipv4.tcp_keepalive_intvl=60 net.ipv4.tcp_keepalive_probes=5
并通过将这些更改保存到 /etc/sysctl.conf 使它们永久生效。
最后,SQL Developer 收到成功消息并关闭连接。