Uso del gestor de recursos en un CBD y PDB

Con la llegada de la 12c se han introducido mejoraras en el manejo de los gestores de recursos, de manera que el Resource Manager puede ser usado a dos niveles:
• CDB: Gestiona los recursos entre los distintos PDB
• PDB: Gestiona los recursos de manera tradicional

Gestión de los recursos en el CDB: Administrando recursos entre los PDBS

Algo que puede parecer evidente pero que debemos de decir, es que esta gestión se lleva a cabo en el CBD$ROOT, No se puede poner recursos al CDB$ROOT, igualmente no aparece en el computo de los shares
El Resource Manager lleva a cabo esta tarea mediante dos conceptos, shares y límites

  • Shares
    Los shares es la manera que tiene de repartir los recursos, a más shares, mas recursos dispone el PDB
    El porcentaje que asigna cada share se obtiene dividiendo el 100% de los recursos entre el numero de shares y multiplicándolo.

  • Limites
    EL otro parámetro que puedes indicar es el límite de utilización sobre el global, este límite puedes aplicarlo solamente a:

    • CPU
    • Cantidad de ejecuciones paralelas en el servidor

[table caption=»Planes de recursos» width=500]
Contenedor,shares,utilization limit, PARALLEL SERVER LIMIT
Default, 1 ,100%, 100%
PDB1 ,4 ,50% , 100%
PDB2 ,1 ,100% ,50%
[/table]

¿Qué significa un valor de 50% en PARALLEL SERVER LIMIT?

El PARALLEL SERVER LIMIT indica un porcentaje, este porcentaje es sobre el valor de inicialización de la base de datos de PARALLEL_SERVERS_TARGET, así pues, si tenemos un valor de 200 en PARALLEL_SERVER_TARGETS tendremos que el PARALLEL_SERVER_LIMITS será de 0.50*200=100 procesos paralelos.

No todos los PDBs tienen por que tener una política de asignación, aquellos que no la tengan irán a parar a el “Default allocation”.
Las directivas sobre los PDBs se han de crear en el momento de CREATE_CDB_PLAN_DIRECTIVE, y un PDB solamente puede ser afectado por una directiva.

¿Cuáles son los parámetros por defecto de la directiva “Default allocation”?

Si no especificas ninguna política específica para un PDB irá a la de por defecto con :
Shares=1
Utilization_limit=100
Parallel_srever_limit=100

Pasos para crear/modificar un plan

Para modificarlos el paquete DMNS_RESOURCE_MANAGER tiene su propia directiva llamada UPDATE_CDB_DEFAULT_DIRECTIVE

Pasos para la creacion

Al igual que en las BBDD clásicas hay que:
1. Crear el pending area
2. Crear el plan
3. Crear directivas (DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE)
4. Validar el pending area
5. Submit el pending area

Habilitar el plan

Al igual que en las versiones antiguas

ALTER SYSTEM SET RESOURCE_MANAGER_PLAN=’myplan;

Se puede deshabilitar el plan quitando la variable de inicialización

ALTER SYSTEM SET RESOURCE_MANAGER_PLAN=’’;

PDB: Administracion de recursos dentro de los PDB

La administracion de recursos dentro del PDB se lleva a cabo igual que se llevaba dentro de las bases de datos tradicionales, teniendo en cuenta:

  • Ha de ser un single level resource plan, ya no puede ser multilevel
  • Tienes solamente 8 grupos de consumidores ( en el no-cdb son 32)
  • No puedes tener subplans dentro del plan ( en el no-dbs se podia)

Hay que tener en cuenta que hay dos parámetros que cambian de nombre:
MAX_UTILIZATION_LIMIT pasa a ser UTILIZATION_LIMIT
PARALLEL_TARGET_PERCENTAGE pasa a ser PARALLEL_SERVER_LIMIT

Es importante que, para poder crear una politica de gestor de recursos dentro de un PDB,la política del CDB para los recursos que quieres administrar debe de debe de satisfacer :
CPU

  • La directiva debe de tener definido el valor de SHARES para ese PDB
  • La directiva debe de tener definido el valor de UTILIZATION_LIMIT a menos del 100%

PARALLEL EXECUTION

  • Las dos de arriba de CPU
  • La directiva debe de tener definido el valor de PARALLEL_SERVER_LIMIT a menos del 100%

Notas finales del resource manager

Se ha introducido un Nuevo grupo de consumidores llamado LOG_ONLY que sirve para usarlo en como switch group en los casos en los que merely want to log the runaway query but don’t want to change its consumer group or perform any other action
Puedes ver lo definido en las vistas
V$RSRC_PLAN
DBA_CDB_RSRC_PLANS

Otra de las cosas que ofrece el RESOURCE MANAGER es que ha añadido nuevas columnas en la vista V$SQL_MONITOR

  • RM_LAST_ACTION The most recent action taken by the Resource Manager, such as cancelling a SQL execution or killing a session
  • RM_LAST_ACTION_REASON The reason for the most recent action taken by theResource Manager on this SQL operation, such as SWITCH_CPU_TIME orSWITCH_ELAPSED_TIME
  • RM_LAST_ACTION_TIME The time of the most recent action taken by the Resource Manager on this SQL operation
  • RM_CONSUMER_GROUP The current consumer group for this SQL operation

Runaway queries : Consultas que tardan mas de lo esperado

Hoy vamos a ver otra entrada para dummies.

¿Que es una Runaway query?

Una «Runaway query» es una consulta que tarda mas de lo esperado, pero …
¿Como podemos definir «lo esperado»?

La definición que toma oracle de ese «mas de lo esperado » es que su ejecución se demora mas allá de lo esperado por el planificador , pero , en terminos corrientes llamamos así a las consultas que «no terminan nunca».

Como véis, inaguramos el mes con una entrada muy sencilla, pero es un concepto importante a tener en cuenta

Encontrar el proceso que se come la CPU en windows

Una de las principales diferencias de oracle para Unix y Windows radica en que, debido a el tipo de sistema operativo, en Windows tenemos un proceso monolítico oracle.exe, y no la multitud de procesos que nos encontramos en los sistemas Unix. Así pues, cuando queremos saber cual es el proceso que se nos come la CPU, siempre vamos a tener una misma respuesta oracle.exe y, además de eso, probablemente no podamos enlazarlo con los procesos de sistema operativo.

¿Como solucionamos este problema?

Para empezar, mi recomendación es tener en el servidor uno de estos dos programas

  • Pprocess explorer
  • QSlice

Los dos programas son gratuitos y se pueden descargar desde soporte de microsoft, y nos permitirán ver con mayor facilidad el origen de nuestro problema.

Si abrimos el process explorer , veremos algo similar a esto:
process explorer

Aquí podemos ver como uno de los procesos oracle se esta comiendo el 100% de la CPU , si hacemos boton derecho «propiedades», el process explorer nos indicará en una ventana independiente la informacion de este proceso, si vamos a la pestaña «threads» y ordenamos por CPU, tendremos:
proceso oralce.exe

Aqui vemos como los treads que mas CPU están consumiendo son

  • 3076 con el 23%
  • 4976 con el 19,95%

Ahora, teniendo estos dos número de thread, si que podremos ir a nuestra ventana de sql y enlazar este numero de thread con el proceso/sesion de Oracle que está causando la carga


select proc.spid ThreadNO,  
sess.username Usuario,  
sess.osuser OSUser,
sess.machine Maquina,  
sess.status Estado,  
sess.sid SessionID,  
sess.program Program  
from v$process proc, v$session sess, v$bgprocess bg  
where sess.paddr = proc.addr  
and bg.paddr(+) = proc.addr  
and proc.spid in (3076)

Esta informacion tambien puede obtenerse con qslice.exe, solamente que la información del thread está en exadecimal, y habremos de pasarla a decimal, por otra parte, la ventaja del qslice.exe es que es más ligero que el process explorer, con lo que, como decía al principio, mi recomendación es tener los dos en el servidor

Creando grupos de consumidores. A la caza del bloqueo II

Hasta el momento, en la entrada   A la caza del bloqueo I   teníamos  un  plan de recursos llamado NO_LOCKS que mataba aquellos procesos que estaban mas de 5 segundos bloqueando otra consulta. Este plan de consumidores no era muy util , ya que podía provocar estragos matando indiscriminadamente cualquier bloqueo de mas de 5 segundos, con lo que hoy daremos un paso mas para hacer de ese plan de recursos algo mas útil.

En esta entrada vamos a crear un grupo de consumidores, este grupo de consumidores nos permitirá afinar el perfil de los usuarios sobre los que queremos aplicar nuestro pal de recursos.

El grupo de consumidores lo vamos a llamar USER_NO_LOCK_ALLOW y lo crearemos de la siguiente manera:

BEGIN
 dbms_resource_manager.clear_pending_area();
 dbms_resource_manager.create_pending_area();
 dbms_resource_manager.create_consumer_group(
consumer_group =>'USER_NO_LOCK_ALLOW','Grupo de consumidores alos que no permitiremos bloqueos '
);
 dbms_resource_manager.submit_pending_area();
END;

 

Una vez tenemos nuestro grupo de consumidores creado, es el momento de decidir que usuarios queremos tener dentro de el y cuales no. Oracle 11g nos da muchas opciones para seleccionar este grupo de usuarios, algunas de ellas son:

Por esquema

Si quisieramos añadir a los usuarios del esquema «esquema1» a este grupo de consumidores usariamos el parámetro dbms_resource_manager.oracle_user  del paquete dbms_resource_manager

BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.set_consumer_group_mapping(
dbms_resource_manager.oracle_user,'esquema1','USER_NO_LOCK_ALLOW'
);
dbms_resource_manager.submit_pending_area();
 END;

Por maquina cliente

Supongamos que queramos aplicar incluir en nuestro grupo de consumidores solamente las sesiones que se ejecutan desde el servidor cliente «WORKGROUP\client1», para ello  usaríamos dbms_resource_manager.client_machine

BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.set_consumer_group_mapping(
dbms_resource_manager.client_machine,'WORKGROUP\MAQUINA1','USER_NO_LOCK_ALLOW'
);
dbms_resource_manager.submit_pending_area();
END;

Por programa

Para separar por programa usaremos la llamada dbms_resource_manager.client_program

BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.set_consumer_group_mapping(
dbms_resource_manager.client_program,'PROGRAMA1','USER_NO_LOCK_ALLOW'
);
dbms_resource_manager.submit_pending_area();
END;

Como podeis ver, las posibilidades son muy grandes, en esta entrada nos hemos centrado en capturar sesiones por parámetros de login, pero la funcion dbms_resource_manager.set_consumer_group_mapping permite también seleccionar usuarios por atributos de runtime-.

La lista de las opciones la podeis encontrar en la documentación del paquete
dbms_resource_manager.set_consumer_group_mapping, pero a groso modo se puede resumir en:
Login Attributes

  • oracle_user
  • service_name
  • client_os_user
  • client_program
  • client_machine

 Runtime Attributes

  • module_name
  • module_name_action
  • service_module
  • service_module_action

Ahora solamente nos quedará el incluir este grupo de consumidores en nuestro plan de recursos, indicándole que son los consumidores de este grupo a los que no se les debe permitir el bloquear al resto de los usuarios . Pero esto será en otra entrada.