Monitorizar QC en GV$SESSION

Mi nombre es Carla y me defino como una apasionada de conocer, compartir ideas, divertirme y aprender todo lo relacionado con Oracle.
Alegre y creativa, con un alto grado de autoexigencia, que busca, incluso sin querer, una forma diferente de ver un mismo problema o solución. Defensora del trabajo en equipo en todas las facetas de la vida y de disfrutar todo lo que haces, siempre con humildad.
Actualmente cuento con más de 15 años de experiencia como administradora de Oracle, habiendo ocupado previamente posiciones como desarrolladora en la rama de Inteligencia de Negocios. Fue en ese momento que me di cuenta de que no quería centrarme en el desarrollo, sino participar en todas las capas que involucraban los datos, desde el despliegue de la base de datos hasta su explotación final.
Siempre estoy dispuesta a ayudar y compartir conocimientos. Creo firmemente que con la tecnología hay que divertirse y no verla como una competencia. La persona con la que tienes que ser el mejor es contigo mismo.
Tengo un escenario donde queremos monitorizar información de sesiones entrando en juego paralelismo.
¿Qué me dice el sentido común? ¿Queremos monitorizar en un monitor de sesiones activas procesos slave o los coordinadores? En nuestro escenario no tiene sentido duplicar sesiones en el monitor atendiendo a slaves. Queremos el proceso principal, el que coordina o si no es paralelo la sesión activa.
Para ello me he valido de la siguiente consulta:
SELECT
a.inst_id,
a.sid,
a.username,
a.machine,
a.program,
a.state,
a.module,
a.sql_exec_start,
a.blocking_session,
a.serial#,
b.spid,
a.action,
a.resource_consumer_group
FROM
gv$session a,
gv$process b
WHERE
( a.paddr = b.addr )
AND ( a.status LIKE 'ACTIVE' OR a.blocking_session IS NOT NULL )
AND a.sql_exec_start IS NOT NULL
AND a.username IS NOT NULL
and a.inst_id=b.inst_id
AND NOT EXISTS (
-- Discrimino los slaves
SELECT 1
FROM GV$PX_SESSION px
WHERE px.SID = a.SID AND px.SERIAL# = a.SERIAL# AND px.INST_ID = a.INST_ID and px.qcinst_id is not null
);
Ubicamos PID en el nodo que aplica y discriminamos slaves, queremos solo una entrada por padre.
Por qué he tenido ésta inquietud? Porque aunque las consultas entre por un DOP contenido por Resource Manager con máximo paralelismo de 1, la consultas por GV$, en mi caso en un RAC de 2 nodos, siempre van a mostrar dos sesiones activas debido al siguiente comportamiento:
When you query a GV$ view one PX server is allocated on each instance, these PX servers are not counted against parallel_max_servers so they do not effect the number of PX servers that can be used by statements accessing other objects.
Oracle controls and maintains all aspects of PZ processes. Setting parallel_max_servers to 0 will not prevent Oracle from starting PZ processes in a RAC environment if a GV$ query is issued. Setting parallel_force_local to TRUE does not restrict PZ operations to a specific instance. PZ processes are always used for gv$ queries regardless of any parallel_* parameter setting.
En resumen, el límite de DOP de 1 no aplica ni se puede contener para las GV$, en mi caso siempre abre 2 sesiones (una por nodo). Duplicando de esta manera sesiones activas en el monitor de sesiones.
Si queremos descartar las sesiones que consulten una GV$ adaptamos la consulta de la siguiente manera:
with paralelas as (
SELECT px.sid,px.inst_id, pp.serial#
FROM GV$PX_SESSION px,
GV$PX_PROCESS pp
WHERE px.SID = pp.SID
AND px.INST_ID= pp.INST_ID
and (px.qcinst_id is not null or pp.is_gv='TRUE')
)
SELECT
a.inst_id,
a.sid,
a.username,
a.machine,
a.program,
a.state,
a.module,
a.sql_exec_start,
a.blocking_session,
a.serial#,
b.spid,
a.action,
a.resource_consumer_group
FROM
gv$session a,
gv$process b
WHERE
( a.paddr = b.addr )
AND a.sql_exec_start IS NOT NULL
AND a.username IS NOT NULL
AND a.sid != (
SELECT
sys_context('USERENV', 'SID')
FROM
dual
)
and a.type = 'USER'
and a.inst_id=b.inst_id
AND NOT EXISTS (
SELECT 1
FROM paralelas par
WHERE par.sid = a.SID
AND par.INST_ID = a.INST_ID
)
ORDER BY
upper(a.machine),
upper(a.program);



