Mostrando entradas con la etiqueta limit. Mostrar todas las entradas
Mostrando entradas con la etiqueta limit. Mostrar todas las entradas

viernes, 9 de agosto de 2013

Como se Puede Limitar la Duración de una Sesión Oracle

Tenía que limitar la duración de una sesión Oracle mientras preparaba un entorno nuevo. Así decidí documentar lo que hice. Probé el ejemplo bajo estas líneas en una base de datos Oracle 11.2.0.2.7. Para empezar conecté como SYS y limité CONNECT_TIME a un minuto el el perfil DEFAULT: 

SQL> conn / as sysdba
Conectado.
SQL> alter profile default
  2  limit connect_time 1
  3  /
 
Perfil modificado.

SQL>

Luego cambié RESOURCE_LIMIT a TRUE para hacer cumplir los límites: 

SQL> alter system set resource_limit = true
  2  /
 
Sistema modificado.

SQL>

Creé un usuario con el perfil DEFAULT. Entonces me conecté a la base de datos como este usuario, miré CONNECT_TIME en USER_RESOURCE_LIMITS y comprobé la hora cada diez segundos:

SQL> create user andrew
  2  identified by reid
  3  profile default
  4  /
 
Usuario creado.
 
SQL> grant create session to andrew
  2  /
 
Concesion terminada correctamente.
 
SQL> conn andrew/reid
Conectado.
SQL> select limit from user_resource_limits
  2  where resource_name = 'CONNECT_TIME'
  3  /
 
LIMIT
----------------------------------------
1
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:29:42
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:29:52
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:02
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:12
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:22
 
SQL> host sleep 10
 
SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
 
TIME_NOW
--------
18:30:32
 
SQL> host sleep 10

Después de un minuto, la consulta siguiente fracasó y la sesión terminó con un ORA-02399:

SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
select to_char(sysdate,'hh24:mi:ss')
*
ERROR en linea 1:
ORA-00604: se ha producido un error a nivel 1 de SQL
recursivo
ORA-02399: ha excedido el tiempo maximo de conexion,
desconectando
ORA-02399: ha excedido el tiempo maximo de conexion,
desconectando

SQL>

... y una nueva tentativa a emplear la consulta probó que la sesión no estaba conectada a la base de datos: 

SQL> select to_char(sysdate,'hh24:mi:ss')
  2  time_now from dual
  3  /
select to_char(sysdate,'hh24:mi:ss')
*
ERROR en linea 1:
ORA-01012: no esta conectado
Identificador de Proceso: 6736
Identificador de Sesion: 36 Numero de Serie: 9
 

domingo, 31 de marzo de 2013

ORA-02393

Este ejemplo está probado en Oracle 11.2.0.2.7 y muestra come se puede limitar el tiempo de CPU de una consulta SQL. Antes de empezar, hay que verificar que RESOURCE_LIMIT sea TRUE. Si no se hace esto, Oracle no impone los límites: 

SQL> alter session set nls_language = 'SPANISH'
  2  /
 
Sesion modificada.
 

SQL> alter system set resource_limit = true
  2  /
 
Sistema modificado.
 
SQL>

Luego es necesario crear un perfil que limitará el tiempo de CPU a un segundo (el valor es suministrado en centésimas de segundo): 

SQL> create profile para_andrew
  2  limit cpu_per_call 100
  3  /
 
Perfil creado.
 
SQL>

Entonces debemos tener un usuario con este perfil:

SQL> create user andrew identified by reid
  2  profile para_andrew
  3  /
 
Usuario creado.
 
SQL> grant create session,
  2        alter session,
  3        select any dictionary to andrew
  4  /
 
Concesion terminada correctamente.
 
SQL> conn andrew/reid
Connected.
SQL> alter session set nls_language = 'SPANISH'
  2  /
 
Sesion modificada.
 
SQL>

Medimos el tiempo de CPU al principio de la manera siguiente:

SQL> select a.value/100
  2  from v$mystat a, v$sysstat b
  3  where a.statistic# = b.statistic#
  4  and b.name = 'CPU used by this session'
  5  /
 
A.VALUE/100
-----------
        .01
 
SQL>

Luego ejecutamos una consulta que empleará más de un segundo de tiempo de CPU: 

SQL> select count(*)
  2  from dba_tables a, dba_tables b
  3  /
from dba_tables a, dba_tables b
     *
ERROR en linea 2:
ORA-02393: ha excedido el limite de llamadas para uso
de CPU
 
SQL>

La consulta falla con un error ORA-02393. Entonces vemos que el tiempo de CPU de la sesión sea aproximadamente un segundo más:

SQL> select a.value/100
  2  from v$mystat a, v$sysstat b
  3  where a.statistic# = b.statistic#
  4  and b.name = 'CPU used by this session'
  5  /
 
A.VALUE/100
-----------
        1.2
 
SQL>

En inglés / in English