暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 会话超时设置2:设置实例级参数

原创 听见风的声音 2023-02-17
1664


     dba经常会被开发或应用运维人员问起,数据库的会话超时时间的是多少,应用的数据库会话在多长时间会被终结,或者说kill掉。MySQL dba在被问起这个问题时回答起来非常简单,一般就是两个超时参数。Oracle dba回答起来可能更简单,可能就一句话,会话没有超时设置。这个简单的回答其实掩盖了Oracle数据库会话超时设置的复杂性。Oracle会话的超时设置可以在net services中设置,也可以设置实例级参数,还可以在用户的profile中设置,本文时这个系列的第二篇,谈谈会话超时的实例级参数。

1 会话超时实例级参数

     Oracle数据库中,可以设置max_idle_time和max_idle_blocker_time两个实例级别的会话超时参数,从v$parameter视图中看一下这两个视图的说明。

SQL> l
  1* select NAME,DESCRIPTION from v$parameter where name like '%idle%'
NAME                     DESCRIPTION
------------------------ --------------------------------------------------------------------------------
max_idle_time            maximum session idle time in minutes
max_idle_blocker_time    maximum idle time for a blocking session in minutes


      这两个参数的单位都是分钟,max_idle_time设置的会话空闲最大时间,会话空闲超过这个时间会被终结,对应的Oracle服务进程会被kill掉。max_idle_blocker_time设置的时阻塞会话的最大空闲时间,阻塞会话空闲时间超过设定值会被kill掉。这两个参数有没有默认值,可不可以在会话级设置,设置后是不是要重启一下服务器,这些信息也可以从v$parameter视图中查询到。

SQL> select NAME,VALUE,ISDEFAULT,ISSYS_MODIFIABLE,ISSES_MODIFIABLE from v$parameter where name like '%idle%';
NAME                     VALUE                ISDEFAULT ISSYS_MOD ISSES
------------------------ -------------------- --------- --------- -----
max_idle_time            0                    TRUE      IMMEDIATE FALSE
max_idle_blocker_time    0                    TRUE      IMMEDIATE FALSE


      可以看到这两个参数的默认值都是0,也就是没有超时设置,这两个参数都是实例级可调的,调整后立即生效。在会话级,这两个参数都不能调整。可以验证一下

SQL> alter session set max_idle_time=0;
alter session set max_idle_time=0
                  *
ERROR at line 1:
ORA-02096: specified initialization parameter is not modifiable with this
option


     可以看到,这个参数在alter session时不能调整。

     max_idle_blocker_time时阻塞会话的超时限制,什么时阻塞会话,Oracle官方文档对此有个说明:

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.

     简单翻译下就是:一个会话当它持有其它会话需要的资源时被认为是阻塞会话。例如:

         会话持有其它会话需要的锁。

         会话执行一个并行操作,它的消费者组,PDB或者数据库达到了最大并行服务器限制或者排队的并行操作。

          会话的PDB或者是数据库实例即将达到会话和进程限制。

      官网列举的三个例子中,持有锁的阻塞会话比较常见,其它两种情况也需要注意。

2 实验验证max_idle_time参数

     下面通过一个小实验验证一下这个参数,数据库的版本是

SQL> select BANNER_FULL from v$version;
BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

       max_idle_time的默认参数为0,即禁用会话空闲超时,将它改为1分钟,

SQL> alter system set max_idle_time=1;

System altered.

SQL> show parameter max_idle_time

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_idle_time                        integer     1


打开一个会话,先运行一条sql,在等待1分钟后,在运行sql

SQL> select sysdate from dual;

SYSDATE
-------------------
2023-02-16 00:50:29

SQL> select * from t_test;
select * from t_test
*
ERROR at line 1:
ORA-03135: connection lost contact
Process ID: 12154
Session ID: 70 Serial number: 30076


执行sql报错,连接丢失,会话被kill的信息可以在数据库的alert.log中看到

2023-02-16T00:58:06.077747-05:00
KILL SESSION for sid=(70, 30076):
  Reason = max_idle_time parameter
  Mode = KILL HARD SAFE -/-/NO_REPLAY
  Requestor = PMON (orapid = 2, ospid = 1723, inst = 1)
  Owner = Process: USER (orapid = 49, ospid = 12154)
  Result = ORA-0

      这里被kill掉的会话的sid和serial#和之前报错的会话相同。alert日志里还可以看到会话被kill掉的原因Reason = max_idle_time parameter。

      这个实验反复试过几次,更改过参数后,对之前的会话也是生效的,对sys用户不生效,和登录方式没有关系。

     实验完成后,恢复这个会话的默认设置,重置这个参数

SQL> alter system reset max_idle_time;
System altered.
SQL> show parameter max_idle_time
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_idle_time                        integer     1

       参数的值并没有改回默认值,这是应为reset操作在不设置范围时只更改spfile里的值,要重置内存里的参数,需要指定范围

SQL> alter system reset max_idle_time scope=memory;
System altered.
SQL> show parameter max_idle_time
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_idle_time                        integer     0

3 验证max_idle_blocker_time参数

   在阻塞会话的集中情况中,持有其它会话请求的锁的情况比较容易模拟实现,这里使用行锁验证这个参数,首先,设置这个参数为1分钟

SQL> alter system set max_idle_blocker_time=1;
System altered.
SQL> show parameter max_idle_blocker_time
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_idle_blocker_time                integer     1


创建两个会话,关闭自动提交,运行更新语句更新一个有主键表同一主键值,实验所用的表名为t_test,只有一个名为id的主键列。

会话1先运行更新语句,由于在sqlplus默认情况下自动提交时打开的,这里需要它关闭,适用set命令

SQL> set autoc off
SQL> show autoc
autocommit OFF
SQL> update t_test set id=12 where id=2;

1 row updated.

SQL> select * from t_test;
select * from t_test
       *
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 17950
Session ID: 36 Serial number: 25168


然后再会话2上运行更新语句

SQL> set autoc 0
SQL> show autoc
autocommit OFF
SQL> update t_test set id=102 where id=2;
一分钟过后,这个更新成功

1 row updated.

      会话2在运行这个语句的时候被会话1阻塞,产生了行锁等待,会话1空闲时间超过1分钟之后,被数据库kill掉,会话2的更新操作成功。数据库告警日志里也有这次操作的信息

2023-02-16T02:48:18.203413-05:00
Process termination requested for pid 17950 [source = rdbms], [info = 2] [request issued by pid: 1723, uid: 54321]
2023-02-16T02:48:18.252757-05:00
KILL SESSION for sid=(36, 25168):
  Reason = max_idle_blocker_time parameter
  Mode = KILL HARD SAFE -/-/NO_REPLAY
  Requestor = PMON (orapid = 2, ospid = 1723, inst = 1)
  Owner = Process: USER (orapid = 51, ospid = 17950)
  Result = ORA-0

      可以看到会话被kill掉的原因Reason = max_idle_blocker_time parameter,会话的sid和serial#,和会话1相同。

  4 小结

      在实例级别设置会话超时参数对数据库系统的sys用户不生效,对自定义的用户有效,会话因空闲超时被kill数据库的告警日志里会有记录。特别是max_idle_blocker_time这个参数,对于防止长时间的行锁有一定的作用,比如有些应用获得行锁后去做别的事情,导致其它会话长时间等待,这种场合下应该适用这个参数。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论