agosto 2026

miércoles, 26 de agosto de 2026

Cómo solucionar el ORA-01555: Diagnóstico y cálculo real del Undo Retention


¡Hola a todos! En esta ocasión vamos a revisar un error clásico con el que nos topamos los administradores de bases de datos Oracle en el día a día: el célebre ORA-01555: snapshot too old.

Cuando este mensaje aparece en los logs, la reacción impulsiva suele ser subir el parámetro UNDO_RETENTION o inflar el tablespace sin un análisis previo. Veamos cómo diagnosticarlo correctamente utilizando las vistas del sistema, cómo calcular el valor ideal y qué alternativas reales existen para solucionarlo.

Cuando ocurre el error, Oracle indica qué sentencia SQL falló y cuánto tiempo llevaba ejecutándose. Para entender el comportamiento general de las consultas de lectura consistente y la retención real, podemos consultar la vista V$UNDOSTAT con el siguiente script:

SELECT BEGIN_TIME, END_TIME, UNDOTSN AS Tablespace_ID,
UNDOBLKS AS Bloques_Generados, TXNCOUNT AS Transacciones,
MAXQUERYLEN AS Query_Mas_Largo_Seg, TUNED_UNDORETENTION AS Retencion_Autotuneada_Seg
FROM V$UNDOSTAT 
WHERE MAXQUERYLEN IS NOT NULL ORDER BY MAXQUERYLEN DESC;


Como se observa, el tiempo del query más largo (QUERY_MAS_LARGO_SEG) ronda consistentemente cerca de las 4 horas (14,184 segundos) debido a procesos analíticos o reportes pesados recurrentes. Oracle intenta autoajustar la retención (RETENCION_AUTOTUNEADA_SEG), pero si el espacio físico no es suficiente, el undo expira antes de tiempo y surge el fallo.

Para evitar adivinar números al azar, podemos apoyarnos en la tasa real de generación de bloques de nuestro entorno. Utiliza la siguiente consulta para calcular los Gigabytes exactos requeridos en el Tablespace de Undo para soportar una ventana de tiempo determinada.

SELECT 
    t.gb_undo_actual,
    n.gb_undo_necesarios,
    CASE 
        WHEN t.gb_undo_actual >= n.gb_undo_necesarios THEN 'SUFICIENTE'
        ELSE 'FALTA ESPACIO'
    END AS estado_undo
FROM 
    (SELECT ROUND(SUM(bytes) / (1024 * 1024 * 1024), 2) AS gb_undo_actual 
     FROM dba_data_files 
     WHERE tablespace_name = (SELECT value FROM v$parameter WHERE name = 'undo_tablespace')) t,
     --Reemplaza el valor de 14184 por tu valor más alto obtenido de la consulta anterior en la columna "Query_Mas_Largo_Seg"
    (SELECT ROUND( ( 14184 * 
                     (SELECT MAX(UNDOBLKS / ((END_TIME - BEGIN_TIME) * 86400)) FROM V$UNDOSTAT) * 
                     (SELECT TO_NUMBER(VALUE) FROM V$PARAMETER WHERE NAME = 'db_block_size') 
                   ) / (1024 * 1024 * 1024), 2 ) AS gb_undo_necesarios 
     FROM dual) n;


Como podemos ver en este análisis, aunque el proceso es demandante, nuestro tablespace cuenta con 543.99 GB actuales frente a los 450.89 GB requeridos, arrojando un estatus de SUFICIENTE en cuanto a espacio físico.

Si un reporte tarda casi 4 horas en ejecutarse, subir el parámetro UNDO_RETENTION globalmente a ese nivel extremo puede inflar innecesariamente el tablespace para toda la transaccionalidad normal del sistema.

Para evitar que el autoajuste de Oracle se base en picos anómalos, podemos calcular un valor de retención inteligente basado exclusivamente en la operación estándar de la base de datos:

SELECT 
    ROUND(AVG(TUNED_UNDORETENTION)) AS UNDO_RETENTION_SUGERIDO_SEG
FROM V$UNDOSTAT
WHERE MAXQUERYLEN < 3600; -- Excluimos queries mayores a 1 hora (reportes pesados)


 Esto te dará un valor equilibrado para proteger el día a día sin sobredimensionar la retención por culpa de una sola consulta analítica.

Tienes dos caminos posibles para decidir cómo proceder:

Opción A: Ampliar el Undo

Si el reporte es un proceso heredado o una consulta analítica que por naturaleza debe tardar horas, debes aceptar el costo de almacenamiento:

  1. Modifica el parámetro UNDO_RETENTION en segundos (cubriendo holgadamente el tiempo del proceso, por ejemplo, 15,100 segundos):

    ALTER SYSTEM SET undo_retention = 15100 SCOPE=BOTH; 

  2. Si requieres asegurar estrictamente que Oracle no sobrescriba el undo antes de cumplir ese tiempo (garantizando el espacio físico previamente dimensionado):

    ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;

    Nota: Ten en cuenta que con RETENTION GUARANTEE, si el tablespace se llena por completo, las nuevas transacciones que requieran espacio fallarán. ¡Asegúrate de haber dimensionado bien el espacio físico antes de activarlo!

  3. Para revertir en caso de emergencia por espacio:

    ALTER TABLESPACE undotbs1 RETENTION NOGUARANTEE; 

Opción B: Tunear la consulta

Un proceso analítico o reporte que tarde casi 4 horas suele ser un candidato ideal para optimización. En lugar de gastar gigabytes de disco guardando transacciones viejas, conviene:

  • Revisar planes de ejecución y crear o ajustar índices faltantes.

  • Migrar consultas pesadas a procesamiento en paralelo (PARALLEL).

  • Particionar las tablas involucradas para que el motor lea solo lo necesario.

  • Reducir el tiempo de ejecución elimina automáticamente la necesidad de un tablespace de undo gigantesco.

En resumen, modificar UNDO_RETENTION o configurar un RETENTION GUARANTEE funciona excelente como un parche rápido para salir del paso, pero la verdadera habilidad de un DBA se demuestra yendo directo a la raíz: optimizar los procesos.

Al final, lograr que tus consultas sean eficientes no solo te ahorra dolores de cabeza con el odioso ORA-01555, sino que también optimiza el rendimiento general del motor y evita que desperdicies espacio valioso en los discos.

Saludos.