Skip to main content

Command Palette

Search for a command to run...

Statspack - Toma de contacto

Updated
8 min readView as Markdown
Statspack - Toma de contacto
C
Hola mundo! Soy Carmen. En mi camino como DBA, con particular interés en Oracle, nace este blog para documentar los pequeños aprendizajes y compartirlos con todos los que por una razón u otra han acabado aqui. No busco inventar o descubrir nada nuevo, pero si algo he aprendido en estos años es que a veces la clave no está en qué comunicas, sino el cómo, asique te animo a leer algún post mientras disfrutas de un buen café. Actualmente cuento con 3 años de experiencia, con formación en administración de bases de datos y en desarrollo de SQL en Oracle principalmente. Mis próximos pasos? Una gran incógnita por ahora, entre posts y cafés los descubriremos juntos.

Hola mundo! Bienvenidos a una tarde más de estudio de performance de Oracle SQL, hoy os traigo una pequeña actividad que hice hace unas semanas, para el Master de Optimización de SQL del reconocido DBA Javier Morales, que estoy cursando actualmente (os dejo el enlace para que no os perdais la edición del año que viene: Master Optimización SQL en Oracle).

Al estudiar las herramientas de monitorización y análisis de rendimiento disponibles en Oracle, una de las que merece especial atención es Statspack. Esta herramienta permite recopilar estadísticas de rendimiento y generar informes detallados sobre el comportamiento de la base de datos durante un periodo de tiempo determinado y al no requerir licencias adicionales, puede utilizarse en Standard Edition, lo que la convierte en una alternativa especialmente útil para el análisis de rendimiento en entornos donde herramientas como AWR no están disponibles.

La tarea consistía redactar un pequeño diagnóstico analizando los varios fragmentos de un informe Stackpack, asi sin más, sin contexto, a ciegas, solo tú vs métricas. Por tanto, no es un informe completo ni una auditoria pero nos va a servir para una primera toma de contacto con Stackpack para ver qué significan algunas de sus métricas y que conclusiones podemos deducir de ellas.

Estos informes nos proporcionan la información sobre un periodo en el tiempo, pero el trabajo de análisis y diagnóstico corresponde al DBA. Asique vamos con ello, pero antes, recuerda:

"Paso a paso y los problemas de uno en uno" .


Análisis de Stackpack

1. Información básica

  • 6 horas de ejecución

  • Elapsed: 360 mins

  • DB time: 27.96 min → la BD trabajó 27.96 min de las 6 h reales →0.1 av de actives sessions ( 0.077)

  • Primera conclusión: no ha tenido mucha caga, la base de datos no está estresada.


2. Top 5 timed events

Primero una breve definición de lo que estamos analizando:

  • CPU time: tiempo que oracle pasó ejecutando activamente código en la cpu, representa el tiempo de trabajo real:

    • Ejecución de sentencias SQL, JOINS....

    • Parseo

    • Ejecuciones de PL/SQL

    • Cálculo de planes

  • log file sync: evento de espera, tras hacer un commit:

    • Escribe los redo logs

    • Espera confirmacion fisica del disco

    • Devuelve control al user

    • La sesión está esperando a que el LGWR termine de escribir los redo

  • direct path read: oracle está leyendo bloques desde disco a la PGA directamente, sin pasar por buffer cache.

  • db file sequencial read: lectura secuencial de bloques individuales( normalmente implica acceso por índice). Un valor alto puede implicar:

    • Nested loops excesivos, índices malo, I/O lento

    • SQL ejecutándose millones de veces

    • Importante mirar → Average wait

    • Tiempos:

      • 0-2 ms : excelente

      • 3-8 ms: normal

      • 10-20 ms: sospechoso

      • >20: storage lento

  • Disk file operations I/O: oracle espera operaciones físicas sobre archivos, no necesariamente lecturas de tablas. Muy común en RMAN, autoextend, tempfile creciendo, ASM/filesystem lento. Puede involucrar:

    • Apertura/cierre de datafiles

    • Resize de archivos

    • File metadata

    • Tempfiles

Resumen:

  • CPU alta → problemas lógicos (SQL)

  • Sequencial read alto → problema de acceso a datos

  • Direct path read alto → queries grandes /full scans

  • Log files sync alto → problemas de commit/ redo

  • Disk file operation i/o → problema infra/storage

Ahora interpretamos los parámetros que acompañan a los eventos

  • Waits: cantidad de veces que oracle tuve que esperar ese evento

  • Time(S): total tiempo acumulado esperando ese evento ( tiempo total perdido)

  • Avgs wait(ms) : tiempo promedio que oracle tardó en cada spera ( es decir, si el recurso responde rápido o lento)

  • % total call time: porcentaje del tiempo total de DB Time consumido por ese evento

Volviendo a nuestro informe:

CPU time

  • Oracle estuvo 878 segundo ejecutando trabajo

  • Conclusión: 58.6% del db time fue cpu → más de la mitad del tiempo fue trabajo efectivo de oracle, no esperas

Log file sync

  • 241.888 waits → 242mil eventos de redo log escribiéndose en disco para una bd con solo 27.96 mins de DB time

    • entonces, no estaba sobrecargada pero algo podría estar dando lugar a un elevado numero de commits, checkpoints, escrituras internas

    • conformando el 25.4% del DB Time

  • Tiempo consumido = 382 s (6.36 s)

  • Avg: probablemente truncado → 1.58 mins x 241.888 = 382 s

    • 2ms para log file sync es bueno
  • Conclusión: la infra parece estar sana, el problema puede estar en la aplicación.

Direct path read

  • 127 mil operaciones.

  • Avg wait excelente.

  • Tiempo consumido 146s (2.4 min)

  • menos del 10% del tiempo total de oracle

  • Conclusión: aunque ocurrió con un frecuencia alta, apenas supone el 10% total.

Segunda conclusión general:

  • DB sana a nivel de infraestructura.

  • Posibles problemas:

    • de lógica SQL

    • commints frecuentes

    • consultas muy grandes.


3. SQLs de alto impacto

SELECT * FROM ZNOTIFICACIONES

  • Elapsed time : tiempo total consumido por todas las ejecuciones

    • 176.91-32.36 = 144.45s que estuvo esperando
  • Executions: se ejecutó 108 veces

  • Elap per exec : cada ejecución tarda 1.64 s

  • Total: consume el 10.5% del tiempo total

  • CPU time: solo 32.46 s fueron de cpu

  • Physical read: lecturas a disco porque no está en buffer cache  (valor muy alto)

  • FECHA_CREACION <= SYSDATE

Todo lo creado hasta hoy (probablemente toda la tabla , lo que implicará un Full Scan

→ Sumamos carga al ordenarlo luego por id

  • Cada vez que se lanza está leyendo casi 58,633.5 bloques

    • Cada bloque ≃  8KB → 58.633 bloques  x 8KB = aprox 469 MB por ejecución
  • Physical Reads totales ≃ 6.332.423 x 8 kb ≃ 48 GB leídos en disco

  • Conclusión: 48 GB leídos en disco, excesivo para una select sobre una tabla


DETELE FROM SINCRTMP

  • Executions:  número muy elevado de ejecuciones

    • 31900 veces ejecutada cada hora →532 veces cada minuto → se puede estar ejecutando en bucle
  • Buffer Gets: lecturas lógicas altísimas

  • Gets per executioin → muy alto para borrado usando una clave

  • Elapsed time: unos casi 25 min, mucho tiempo

    • Se ejecuta 191.857 veces y cada ejecución lee aproximadamente 1.919 bloques lógicos

    • Tiempo medio de ejecución: 1490.41s / 191.857 = aprox 0.0078s ( 8 ms)

      • 8 ms x 191.857 veces = aprox 1534s (aprox el elapsed time, casi 25 min )
  • Tiempo medio de ejecución: 1490.41s / 191.857 = aprox 0.0078s ( 8 ms)

    • 8 ms x 191.857 veces = aprox 1534s (aprox el elapsd time,casi 25 min)

Buffer gets son bloques leídos en memoria, desde buffer cache. No implican disco, pero sí implican trabajo lógico de oracle:

  • Buscar bloques

  • Recorrer índices

  • Comprobar filas

Conclusión: muy probable Oracle está haciendo un Full Scan para cada delete  → problema con el índice, quizás mal definido/inexistente ??

Soluciones:

  • Comprimir la tabla.

  • Crear un índice por clave.

  • Analizar si es posibles reducir esas 191.857 ejecuciones con un sleep para bajar la frecuencia con la que se ejecuta, una vez por minuto por ejemplo, en vez de cada 8 ms.


Análisis de segmentos

Que porcentaje de todas las lecturas lógicas de la bd pertenece a ese objeto.

Los logical reads (buffer gets):

  • Bloques leídos desde buffer cache

  • Accesos lógicos en memoria oracle

  • Conclusiones:

    • Las ejecuciones sobre la tabla ZNOTIFICACIONES genera el 93.9 % de todas las lecturas físicas de la instancia

    • Logical reads = 3.219.424  ≃  Physical Reads= 3.218.456

→ prácticamente cada lectura lógica ha implicado una lectura física a disco

→no está usando bloques en caché


SELECT…. INNER JOIN….

  • CPU TIME ≈ Elapsed → la query no espera, consume CPU principalmente

  • Ese 36.6% es sobre el trabajo efectivo, esos 27 minutos totales de la bd

  • Gets per Exec demasiado alta para una select con filtros

Lo que podemos deducir:

  • En cada ejecución leemos esos 2.147 bloques, es decir, nos lo estamos trayendo todo prácticamente en cada ejecución

  • la ZSD puede ser una vista

  • JOIN en el que probablemente no coincidan FK con PK

  • JOIN transformada para que encaje bien

  • Se estań completando los valores con 0

  • Conclusión: no parece un problema de disco ni esperas, puede ser un problema con las columnas que se utilizan para hacer el join y los filtros.