代码改变世界

ORACLE新参数MAX_IDLE_TIME和MAX_IDLE_BLOCKING_TIME简介

2022-11-03 22:52  潇湘隐者  阅读(687)  评论(0编辑  收藏  举报

Oracle 12.2 引入了新参数MAX_IDLE_TIME。它可以指定会话空闲的最大分钟数。如果会话空闲的时间超过了这个阈值的话,这个会话将会被自动终止。其实在Oracle 10g& 11g时代,我还写过脚本定期清理INACTIVE会话,当时写的文章名为ORACLE定期清理INACTIVE会话”。从Oracle 12.2开始,就完全没有必要这样做了,设置一个简单的参数即可解决这个问题,见微知著,一叶知秋。以后数据库运维的趋势确实是越来越简单化,自动化。

MAX_IDLE_TIME这个参数的时间单位是分钟,注意不是秒。可以在PDB级别或CDB级别修改。但是不能在会话级别修改(ALTER SESSION),另外,对于RAC实例,不同节点的值可以设置成不一样。如果参数MAX_IDLE_TIME的值为0,表示不限制会话的空闲时间。当会话的空闲时间超过阈值时,会话被终止后,你会在客户端收到ORA-03113错误。注意,有时候我们也会通过RESOURCE_LIMIT限制会话最大的空闲时间,通过在PROFILE里面设置IDLE_TIME的值来实现,如果是通过这种方式来终止会话的话,收到的错误为“ORA-02396: exceeded maximum idle time, please connect again”。注意两者的区别。

另外,我们来看另外一个参数MAX_IDLE_BLOCKER_TIME ,这个参数最开始宣称是ORACLE 21c引入的新特性,但是实际上ORACLE 19c已经有这个参数了。它定义了阻塞会话的最大会话空闲时间,以分钟为单位。 默认值 0 也表示没有限制。官方文档关于这个参数的介绍如下:

A session is considered to be a blocking session when it is holding resources required by other sessions. For example:

- The session is holding a lock required by another session.
- The session is a parallel operation and its consumer group, PDB, or database has either reached its maximum parallel server limit or has queued parallel operations.
- The session’s PDB or database instance is about to reach its SESSIONS or PROCESSES limit.

This parameter differs from the MAX_IDLE_TIME parameter in that MAX_IDLE_TIME applies to all sessions (blocking and non-blocking), whereas MAX_IDLE_BLOCKING_TIME applies only to blocking sessions. Therefore, in order for MAX_IDLE_BLOCKING_TIME to be effective, its limit must be less than the MAX_IDLE_TIME limit.

当会话持有其它会话所需的资源时,该会话被视为阻塞会话. 例如

  1. 该会话持有另一个会话所需的锁。
  2. 该会话是并行操作,并且其使用者组,PDB或数据库已达到其最大并行服务器限制或已排队的并行操作。
  3. 会话的PDB或数据库实例即将达到其SESSIONS或PROCESSES限制。

这个参数与MAX_IDLE_TIME参数的不同之处在于,MAX_IDLE_TIME适用于所有会话(阻塞和非阻塞),而MAX_IDLE_BLOCKING_TIME仅适用于阻塞会话。  因此,为了使MAX_IDLE_BLOCKING_TIME有效,其限制必须小于MAX_IDLE_TIME限制。

注意事项:

此参数对并行查询进程和 SYS 用户会话都没有影响。所以你不要用sys用户去测试,否则你会发现它不生效。

This parameter does not have an effect on parallel query processes, nor on SYS user sessions.

此参数从Oracle 19c开始就已经提供了。不是从Oracle 21c开始。

This parameter is available starting with Oracle Database 19c.

有了这个参数,你又不用写脚本kill阻塞会话了。你看,新增的一个功能/特性就能节省你很多工作。但是这个功能也还有一些不足的地方:DBA不清楚Kill了哪些会话,阻塞会话当时执行过什么SQL也无从得知,如果是自己写的脚本,往往可以记录这些信息,方便时候我们回溯、分析问题。如果Oracle在终止会话的同时,将这些信息写入trace文件或数据字典,那就相当完美了。