Oracle数据库第三种会话超时管理的办法是在用户的profile文件中设置超时管理,这种方法有一个其它两种办法没有的好处是可以针对每个用户设置单独的超时参数,具有更好的灵活性。
1 用户profile文件
创建用户时可以为用户指定一个profile文件,在profile文件里可以设置用户的密码策略和资源限制等,其中就包括会话的空闲超时和会话的连接时间限制。通常我们在创建用户时不会指定profile文件,这是用户适用的就是数据库默认的profile文件,名字就叫做DEFAULT。
profile的资源限制是否生效由一个实例参数决定,这个实例参数的名字是resource_limit,这个参数的默认值如下:
SQL> select NAME,VALUE,DEFAULT_VALUE,ISSYS_MODIFIABLE, DESCRIPTION from v$parameter where name='resource_limit'; NAME VALUE DEFAULT_VALUE ISSYS_MOD DESCRIPTION ---------------- ----- -------------- --------- ---------------------------------------- resource_limit TRUE TRUE IMMEDIATE master switch for resource limit
可以看到这个参数的默认值是true,更改后可以立即生效。这个参数的设置对用户的资源限制和会话管理有影响,对用户的密码策略则没有影响,无论这个参数的值是什么,用户的密码策略总是生效的。
需要考虑的另一点时,在启用用户的profile资源限制时,会对数据库的性能造成轻微的影响,这是因为在每一次连接数据库时,Oracle都要载入profile文件,执行资源策略。
2 在profile文件中执行会话空闲和连接时间限制
在用户的profile文件中,可以设置会话的空闲超时时间。如果会话调用之间的空闲时间超过设置时间,会话当前的事务会被回滚,会话被终结,会话占用的资源也会被释放。会话的下一个调用会收到指示它不再连接到实例的错误。这里面要注意的是,在会话空闲超时之后,Oracle的pmon后台进程会执行会话清除工作,在pmon进程完成会话清除之前,进程任然会被显示为活跃进程,并且仍然被计算到会话和用户资源限制之内。
在用户的profile文件中,也可以设置会话的连接时间限制,如果会话的连接时间超过了限制时间,会话的当前事务被回滚,会话被丢弃,资源占用资源被释放。
上面的这两个参数的单位都是分钟,有一点需要注意的是,这两个时间都不是精确的,Oracle不会持续监测会话的空闲时间或者是连接时间,不这么做的原因是为了节省资源,以免对性能造成过大的影响。Oracle的做法是每个几分钟进行检查,因此,会话可能会稍微超过一点设置的时间才会被判为超时,这个超过的时间有可能是几分钟。看一下数据库中这两个参数的默认设置:
SQL> select PROFILE,RESOURCE_NAME,LIMIT from dba_profiles where PROFILE='DEFAULT'and RESOURCE_NAME in ('IDLE_TIME', 'CONNECT_TIME')
PROFILE RESOURCE_NAME LIMIT
-------------------------------- -------------------------------- --------------------------------
DEFAULT IDLE_TIME UNLIMITED
DEFAULT CONNECT_TIME UNLIMITED
在数据库默认的DEFAULT profile文件中,这两个参数的默认值都是unlimited,即没有限制。
3 实验验证
先验证一下空闲超时设置,直接更改DEFAULT profile文件中的这个参数值,在profile文件里更改的值只对更改之后的新建的会话有效,对已经登录的会话是无效的。
SQL> alter profile DEFAULT limit IDLE_TIME 3; Profile altered.
更改之后新建一个会话,不执行任何操作,大约3分钟后会话,会话被终结,数据库告警日志里出现了下面的信息。
2023-02-17T15:00:12.939943+08:00 KILL SESSION for sid=(110, 33842): Reason = profile limit idle_time Mode = KILL SOFT -/-/NO_REPLAY Requestor = PMON (orapid = 2, ospid = 1672, inst = 1) Owner = Process: USER (orapid = 47, ospid = 3895) Result = ORA-0
告警日志里显示被终结会话的sid和serial#,会话被kill的原因,请求kill这个会话的进程是pmon。
验证完之后恢复DEFAULT profile 中这个文件的默认设置
alter profile DEFAULT limit IDLE_TIME unlimited;
验证连接超时设置使用单独的profile,为用户创建一个单独的profile,设置会话连接超时时间,先创建一个profile文件
SQL> create profile test_connect limit CONNECT_TIME 3; Profile created.
创建用户profile时至少要指定一个参数,其它的参数会采用默认值,如下面看到的
SQL> select PROFILE,RESOURCE_NAME,LIMIT from dba_profiles where PROFILE='TEST_CONNECT'; PROFILE RESOURCE_NAME LIMIT -------------------- -------------------------------- -------------------- TEST_CONNECT COMPOSITE_LIMIT DEFAULT TEST_CONNECT SESSIONS_PER_USER DEFAULT TEST_CONNECT CPU_PER_SESSION DEFAULT TEST_CONNECT CPU_PER_CALL DEFAULT TEST_CONNECT LOGICAL_READS_PER_SESSION DEFAULT TEST_CONNECT LOGICAL_READS_PER_CALL DEFAULT TEST_CONNECT IDLE_TIME DEFAULT TEST_CONNECT CONNECT_TIME 3 TEST_CONNECT PRIVATE_SGA DEFAULT TEST_CONNECT FAILED_LOGIN_ATTEMPTS DEFAULT TEST_CONNECT PASSWORD_LIFE_TIME DEFAULT TEST_CONNECT PASSWORD_REUSE_TIME DEFAULT TEST_CONNECT PASSWORD_REUSE_MAX DEFAULT TEST_CONNECT PASSWORD_VERIFY_FUNCTION DEFAULT TEST_CONNECT PASSWORD_LOCK_TIME DEFAULT TEST_CONNECT PASSWORD_GRACE_TIME DEFAULT TEST_CONNECT INACTIVE_ACCOUNT_TIME DEFAULT
设置测试用户的profile为这个文件
SQL> alter user test profile test_connect; User altered.
开启一个会话
SQL> / SYSDATE ------------------- 2023-02-17 15:13:02 SQL> / SYSDATE ------------------- 2023-02-17 15:13:04 SQL> / select sysdate from dual * ERROR at line 1: ORA-02399: exceeded maximum connect time, you are being logged off
会话超时后,显示的是超过最大连接时间,会话被注销,检查Oracle数据库的日志告警文件,里面没有发现与这个会话有关的错误信息。
4 关于Oracle数据库的会话超时设置
Oracle数据库的会话超时设置在这三篇文章里基本描述清楚了,空闲会话超时时间设置在sqlnet.ora,数据库实例参数以及用户profile中都可以设置,sqlnet.ora和监听设置里还可以设置对会话创建时间的超时管理。要注意的是SQLNET.EXPIRE_TIME设置的会话异常监测的时间间隔,用于故障连接监测,对正常的连接不起作用,如果网络环境不稳定,经常发生连接异常的情况下可以设置此参数,避免异常终结的连接占用过多的数据库资源。实例级参数max_idle_blocker_time设置的是阻塞会话的空闲超时时间,对阻塞其它会话起作用,这个主要用于高并发环境下有些应用在锁定资源后去做大量的与数据库无关的操作或者发生故障。用户profile的最大连接时间则于连接的状态无关,只要到达设置时间,连接就会被注销。用户profile里设置的时间参数可以只对某个或某几个用户有效。在生产数据库上应该根据实际情况设置各个参数值,如果有可能,尽可能在应用的连接池内进行连接的时间管理,避免数据库设置和应用设置的冲突,简化连接问题排查。




