os.tcp_keepalive 和ORACLE DCD
1.ORACLE DCD(死连接检测,即Dead Connection Detection)
即在$ORACLE_HOME/network/admin/sqlnet.ora文件中增加如下一行:
sqlnet.expire_time=N (N代表分钟)
Oracle数据库会在会话IDLE时间超过这个指定的时间时,检测这个会话的对端(即客户端)是否还有效。
避免客户端抛出ORA-3113而异常退出,导致会话在server端一直存在,占用连接会话数。
2.在OS层设置tcp_keepalive参数
这样,在OS层,如果一个TCP连接在指定的时间内没有活动,会发送一个探测包到连接的对端,检测连接的对端是否仍然存在。
如果这个时间小于防火墙中设置的“超时”时间,防火墙就会检查到连接中仍然有数据,就不会断开这个连接。
不同的操作系统上,修改TCP keepalive参数的方法略有不同,
1)在Windows NT平台上, 我们利用regedit来修改系统注册表,修改
HKEY_LOCAL_MACHINE\CurrentControlSet\Services\Tcpip\Parameters下的以下三个参数:
KeepAliveInterval,设置其值为1000
KeepAliveTime,设置其值为300000(单位为毫秒,300000代表5分钟)
TcpMaxDataRetransmissions,设置其值为5
2)AIX平台上, 用no命令修改如下参数:
AIX TCP_KEEPIDLE
描述:“保持活动”包确保连接保持活动/已建立状态。
如何查看或设置:使用 no 命令来确定当前值或设置该值。此更改将在您下次重新启动机器后失效。要永久地更改此值,
请将 no 命令添加到 /etc/rc.net 目录中。例如:
no -o tcp_keepidle=600
缺省值:14400 个半秒(2 小时)。
建议值:600 个半秒(5 分钟)。
TCP_KEEPINTVL
描述:指定为了验证连接而发送的各个包之间的时间间隔。
如何查看或设置:使用以下命令来将此值设置为 5 秒:
no -o tcp_keepintvl=10
缺省值:150(1/2 秒)
建议值:10(1/2 秒)
TCP_KEEPINIT
描述:指定 TCP 连接的初始超时值。
如何查看或设置:使用以下命令来将此值设置为 20 秒:
no -o tcp_keepinit=40
缺省值:150(1/2 秒)
建议值:40(1/2 秒)
我们也可以修改/etc/rc.net文件,
/usr/sbin/no -o tcp_keepidle=240
/usr/sbin/no -o tcp_keepinit=50
/usr/sbin/no -o tcp_keepintvl=50
注意:直接使用命令行修改,在机器重启后,会失效;修改rc.net文件,可以做到永久生效。
3)在HP平台上,
对于HP-UNIX V10.20及其在此之前的版本,用/usr/contrib/bin nettune命令来修改有关参数;
对于HP-UNIX V10.30及其以上版本,用/usr/bin/ndd命令来修改有关参数。
4)在SUN Solaris平台上,
用ndd -set /dev/tcptcp_keepalive_interval NNN命令来修改有关参数,tcp_keepalive_interval的单位为毫秒,缺省值为7200000毫秒,即2个小时。
5) linux平台上,
直接修改/etc/sysctl.conf 加入如下参数
net.ipv4.tcp_keepalive_time = 120 (单位1秒,于AIX 代表1/2秒不同)
sysctl -p 生效
3. 查询活动/不活动的连接情况:
SELECT s.username , s.status ,s.machine ,spid ,
'kill -9 '||spid os_level_abort,
'alter system kill session ' ||''''||s.sid||','||s.serial# || ''';' Oracle_abort_level,
TO_CHAR (logon_time, 'dd/mm/yyyy hh24:mi:ss') login_time,
last_call_et ,
TO_CHAR (TRUNC (last_call_et / 3600, 0))||' '||' HRS '||
TO_CHAR (
TRUNC ((last_call_et - TRUNC (last_call_et / 3600, 0) * 3600) / 60, 0)
) ||' MINS' idle_time_in_hour,
module
FROM v$session s, v$process p
WHERE TYPE = 'USER'
AND p.addr = s.paddr
AND status != 'KILLED'
AND last_call_et > 60 * 60 * 1
ORDER BY last_call_et desc;
–