【问题标题】:Setting Oracle 11g Session Timeout设置 Oracle 11g 会话超时
【发布时间】:2010-07-29 15:01:53
【问题描述】:

重启服务器后,Tomcat服务器的oracle连接每晚都会超时。在重新启动之前,连接没有超时。现在,早上,应用程序在访问数据库时抛出 JDBC 连接错误。重新启动 Tomcat 可解决此问题。我假设这是由于重新建立了连接。我认为,这是由于 Oracle DB 使会话超时。如何在 Oracle 11g 中禁用会话超时?
谢谢!
史蒂夫

Config.groovy 省略了开发和测试。

dataSource {
  pooled = true
}

hibernate {
   cache.use_second_level_cache = true
   cache.use_query_cache = true
   cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}

// environment specific settings
environments {
production {
  dataSource {
    driverClassName = "oracle.jdbc.driver.OracleDriver"
    username = "XXXXX"
    password = "XXXXXX"
    dialect = "org.hibernate.dialect.Oracle10gDialect"
    dbCreate = "update" // one of 'create', 'create-drop','update'
    url = "jdbc:oracle:thin:@XXXXXX:1521:xxxx"
  }
}  }

【问题讨论】:

  • 这是一个运行在 tomcat 上的 grails 应用程序吗?
  • 是 - Grails 1.2.2、RHEL 5.5、Tomcat 6.0.26

标签: oracle oracle11g


【解决方案1】:

这通常由与 Tomcat 连接的用户关联的配置文件控制。

SQL> SELECT PROFILE, LIMIT FROM DBA_PROFILES WHERE RESOURCE_NAME = 'IDLE_TIME';

PROFILE                        LIMIT
------------------------------ ----------------------------------------
DEFAULT                        UNLIMITED

SQL> SELECT PROFILE FROM DBA_USERS WHERE USERNAME = USER;

PROFILE
------------------------------
DEFAULT

所以我连接的用户有无限的空闲时间 - 没有超时。

【讨论】:

  • 亚当,谢谢你的建议!用户看起来一切都井井有条,但不幸的是,连接在一夜之间断开了。啊!还有其他想法吗?显然我不是 DBA,但让我感到困惑的是,直到我重新启动服务器才发生这种情况。我想知道我是否确实运行了一个允许连接无限期保持不变的命令,并且当服务器重新启动时,设置丢失了。
【解决方案2】:

Adam 已经建议了数据库配置文件。

您可以检查 SQLNET.ORA 文件。有一个EXPIRE_TIME 参数,但这是用于检测丢失的连接,而不是终止现有的连接。

鉴于它在一夜之间发生,听起来更像是空闲超时,这可能是由于应用服务器和数据库服务器之间的防火墙造成的。设置 EXPIRE_TIME 可能会阻止这种情况发生(因为每 10 分钟会检查一次以检查客户端是否处于活动状态)。

或者数据库可能正在关闭并重新启动,这正在杀死连接。

或者,您应该能够使用validationQuery 配置 tomcat,以便它会自动重新启动连接而无需重新启动 tomcat

【讨论】:

  • Gary,sqlnet.ora 文件在我的系统上并没有真正包含太多内容。它只定义了两个变量——NAMES.DIRECTORY_PATH 和 ADR_BASE。你觉得这对吗? - 史蒂夫
  • 听起来很正常。如果没有 expire_time,Oracle 通常不会注意到客户端连接是否终止,除非它处于中间状态。如果 v$session 条目没有闲置,听起来它们像是被故意关闭为客户端应用程序。
【解决方案3】:

这很可能是由您的应用程序的连接池引起的;不是 Oracle DBMS 问题。大多数连接池都有一个验证语句,可以在为您提供连接之前执行。在 oracle 中,您需要“从双重中选择 1”。

重新启动服务器后开始出现的原因是连接池可能是在没有重新启动的情况下添加的,而您现在是第一次体验连接池的使用。处理数据库连接的资源文件的修改日期是什么?

验证查询示例:

 <Resource name="jdbc/EmployeeDB" auth="Container" 
            validationQuery="Select 1 from dual" type="javax.sql.DataSource" username="dbusername" password="dbpassword"
            driverClassName="org.hsql.jdbcDriver" url="jdbc:HypersonicSQL:database"
            maxActive="8" maxIdle="4"/>

编辑: 对于 Grails,grails 池也有类似的配置选项。 Grails 1.2 示例(请参阅Grails 1.2 的发行说明)

dataSource {
    pooled = true
    dbCreate = "update"
    url = "jdbc:mysql://localhost/yourDB"
    driverClassName = "com.mysql.jdbc.Driver"
    username = "yourUser"
    password = "yourPassword"
    properties {
        maxActive = 50
        maxIdle = 25
        minIdle = 5
        initialSize = 5
        minEvictableIdleTimeMillis = 60000
        timeBetweenEvictionRunsMillis = 60000
        maxWait = 10000     
    }   
}

【讨论】:

  • Brian,感谢您的建议,但我的应用程序使用 grails 进行数据库配置。我不认为tomcat配置文件起作用。对? - 史蒂夫
  • 在您的 grails 数据库配置中将 pooled 设置为 true 还是 false?如果您没有设置参数,则默认值为 true。如果 pooled 设置为 true,我敢打赌问题是池,而不是 Oracle 会话。
【解决方案4】:

我来这个问题是为了寻找一种基于总会话生命周期而不是空闲时间来启用 oracle 会话池到期的方法。 另一个目标是避免应用程序意外强制关闭。

似乎可以通过将池 validation query 设置为

select 1 from V$SESSION 
where AUDSID = userenv('SESSIONID') and sysdate-LOGON_TIME < 30/24/60

这将以不影响应用程序的可预测方式关闭老化超过 30 分钟的会话。

【讨论】:

【解决方案5】:

数据库是否知道连接已断开,或者会话是否仍列在 v$session 中?我认为,这表明它正在被网络丢弃。你知道在遇到问题之前它可以保持空闲多长时间,以及它是否与 TCP 空闲值(net.ipv4.tcp_keepalive_time、tcp_keepalive_probes 和 tcp_keepalive_interval 来自 sysctl,如果我没记错的话)有任何相似之处吗?不记得默认情况下 sysctl 更改是否持续存在,但这可能是修改后的内容,然后在重新启动时重置。

您还可以在不反弹整个服务器的情况下重置 JDBC 连接;在 WebLogic 中当然可以,我意识到这并没有多大帮助,但我不熟悉 Tomcat 等价物。

【讨论】:

  • Alex,我只看到了带有 LOGON_TIME 的会话 > 上次 tomcat 重启。如果网络使会话超时,那么无论 tomcat 重新启动如何,这些会话仍应在表中。对? sysctl 信息:net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_time = 7200
  • 是的,Tomcat 重启不会影响任何旧的孤立会话。我猜 Oracle 可能会在一段时间后注意到它们已经死亡并终止它们,完全独立于您的客户端关闭其结束(仅在尝试发送数据时);我们有一个 JDBC 客户端应用程序,它在远程 DB 被弹回数小时后表现得像,但我确信有很多变化。您需要在超时后立即检查 v$session 中的内容,但由于这是未知的,而且有时在一夜之间,这有点困难。我猜想监控 v$session 并查看它们何时关闭?祝你好运...
【解决方案6】:

检查应用程序连接池设置,而不是更改 oracle 数据库上的任何会话超时设置。他们超时是正常的。

看看这里: http://grails.org/doc/1.0.x/guide/3.%20Configuration.html#3.3%20The%20DataSource

您确定“pooled”参数设置正确吗?

您好, 拉尔斯


编辑:
乍一看,您的配置似乎还可以。 我今天遇到了这个问题。可能和你的痛苦有关:
"Infinite loop of exceptions if the application is started when the database is down for maintenance"

【讨论】:

  • 拉斯,谢谢你的建议。我将我的 Config.groovy 添加到问题中。在我看来,一切都井井有条。有什么不对劲吗? - 史蒂夫
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多