martes, 5 de mayo de 2026

Configurar y Utilizar Oracle Flashback Technology


Oracle Flashback es una de las herramientas más útiles para un DBA, ya que nos permite recuperar datos o estados de la base de datos sin necesidad de recurrir a backups (RMAN). A diferencia de RMAN, Flashback trabaja con los datos actuales para "deshacer" errores en segundos.

IMPORTANTE: Todos los ejemplos prácticos de esta guía han sido validados y probados en Oracle Database 23ai.

Para utilizar Flashback Database, la base de datos debe estar en modo ARCHIVELOG. Primero verificamos el estado:

SELECT log_mode, flashback_on FROM v$database;


En este caso no se encuentra activo ni el modo archivelog de la base por lo tanto tampoco el modo flashback. Procedemos con la configuración de la Fast Recovery Area (FRA), activamos ambos modos.

--Definir espacio y ruta de la FRA ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 10G; ALTER SYSTEM SET DB_RECOVERY_FILE_DEST = '/opt/oracle/fast_recovery_area';

--Definir retención (ej. 24 horas en minutos) ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET = 1440;

--Activar modos (Requiere modo MOUNT) 
SHUTDOWN IMMEDIATE; 
STARTUP MOUNT; 
ALTER DATABASE ARCHIVELOG; 
ALTER DATABASE FLASHBACK ON
ALTER DATABASE OPEN;



No todos los Flashback funcionan igual. Se dividen principalmente por el origen de los datos que utilizan:

Basados en Segmentos de UNDO

Estos dependen del UNDO_TABLESPACE. Si los datos en el undo han sido sobrescritos, la operación fallará.

  • Flashback Query: Permite consultar datos en un tiempo pasado (AS OF TIMESTAMP/SCN).



SELECT last_name, salary FROM hr.employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '5' MINUTE) WHERE department_id = 60;


  • Flashback Version Query: Ideal para auditoría, permite ver los cambios de una fila.

--Muestra todas las versiones de una fila en un intervalo
SELECT versions_starttime, versions_operation, salary
FROM hr.employees
VERSIONS BETWEEN TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' HOUR) AND MAXVALUE
WHERE employee_id = 101;
  • Flashback Table: Revierte una tabla completa. (Ojo: requiere Row Movement).

-- Indispensable para evitar error ORA-08189 
ALTER TABLE hr.employees ENABLE ROW MOVEMENT; 

-- Revertir tabla a un punto exacto FLASHBACK TABLE hr.employees TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE);

Basados en Flashback Logs (FRA)

Dependen de la Fast Recovery Area y capturan cambios a nivel de bloque físico.

  • Flashback Database: Revierte toda la base de datos. Es la opción más drástica y rápida ante errores masivos de despliegue.

-- Si estás en un entorno PDB (CDB/PDB), primero cierra la PDB: 
ALTER PLUGGABLE DATABASE FREEPDB1CLOSE

-- Ejecuta el retroceso 
FLASHBACK PLUGGABLE DATABASE FREEPDB1TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '30' MINUTE); 

-- Abre con resetlogs para fijar la nueva línea de tiempo 
ALTER PLUGGABLE DATABASE FREEPDB1OPEN RESETLOGS;





Basados en Metadata (Recycle Bin)

  • Flashback Drop: Recupera tablas borradas con DROP. Oracle simplemente renombra el objeto en el diccionario de datos.

-- Si borraste la tabla por accidente: 
DROP TABLE hr.locations CASCADE CONSTRAINTS; 

-- Recupérala de la "papelera" 
FLASHBACK TABLE hr.locations TO BEFORE DROP;


TIP: A veces, recordar una fecha exacta o un SCN es complicado. Puedes crear un "alias" para el estado actual de tu base de datos antes de realizar cambios importantes.
-- Crear un punto de retorno normal 
CREATE RESTORE POINT antes_del_cambio;

Puedes consultar los puntos guardados

SELECT name, scn, time, guarantee_flashback_database FROM v$restore_point; 

Para regresar al punto especifico creado

-- Para una tabla específica 
FLASHBACK TABLE hr.locations TO RESTORE POINT antes_del_cambio;  

Recuerda que la tecnología Flashback no es solo una funcionalidad de recuperación, sino una estrategia de continuidad de negocio. Mientras que un backup tradicional en RMAN es tu seguro de vida ante un desastre físico o de hardware, Flashback es tu mejor aliado contra el error humano cotidiano.


lunes, 27 de abril de 2026

Uso de Hints de Paralelismo en grandes volúmenes de datos


Bajo el ecosistema de Oracle Database, es habitual lidiar con procesos que manejan millones de registros (Batch, ETL o reportes pesados). Cuando el tiempo de respuesta es fundamental, el procesamiento en paralelo se convierte en nuestra mejor herramienta.

Sin embargo, el Optimizador de Oracle (CBO) no siempre elige el paralelismo de forma automática. En este post, veremos cómo forzarlo correctamente y qué consideraciones debemos tener.

Cuando usamos un hint de paralelismo, Oracle divide una tarea grande en piezas más pequeñas. Un Query Coordinator (QC) coordina a varios procesos esclavos (Parallel Execution Servers) que trabajan simultáneamente.

La forma más común de implementarlo es a través del hint /*+ PARALLEL(alias, degree) */. El degree o grado define cuántos procesos esclavos vamos a solicitar.

SELECT /*+ PARALLEL(ventas, 4) */ 
       producto_id, SUM(monto)
FROM fact_ventas ventas
GROUP BY producto_id;

En este caso, estamos solicitando 4 procesos esclavos para escanear la tabla y realizar la agregación.

Este es un punto donde muchos fallan. Para que un INSERT funcione realmente rápido, debemos combinar el paralelismo con el Direct Path Load mediante el hint APPEND. Esto hace que Oracle escriba directamente al final de la tabla, saltándose el Buffer Cache y generando mucho menos Redo Log.

ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+ APPEND PARALLEL(destino, 8) */ INTO table_final destino
SELECT /*+ PARALLEL(origen, 8) */ * FROM table_staging origen;
COMMIT;

Para confirmar que el hint está funcionando, debemos generar el plan de ejecución (EXPLAIN PLAN). Debemos identificar las siguientes operaciones:

  • PX COORDINATOR: El proceso principal que une los resultados.
  • PX SEND / PX RECEIVE: Indica que los datos se están moviendo entre procesos esclavos.
  • PX BLOCK ITERATOR: Oracle ha dividido la tabla en bloques para los esclavos.
  • LOAD AS SELECT (HIGH WATER MARK): Indica que el APPEND y el paralelismo de escritura están activos.

Si el plan de ejecución muestra estas líneas (comenzando con "PX"), el paralelismo se está aplicando correctamente.


Este plan de ejecución representa una carga de datos de alto rendimiento (Full Parallel Stack) que utiliza el paralelismo tanto para leer como para escribir. En lugar de procesar los datos fila por fila, el (PX Coordinator) divide la tarea entre 4 procesos esclavos que filtran los duplicados simultáneamente y realizan una inserción directa al disco (Direct Path Load), saltándose la memoria intermedia y escribiendo los datos al final de la tabla de forma masiva. Además, el plan incluye el mantenimiento de índices en paralelo, lo que evita que la base de datos se ralentice al actualizar los índices después de la carga, garantizando la máxima velocidad posible y un uso mínimo de los logs de transacciones.

IMPORTANTE:

No se debe abusar del paralelismo. Aquí mis recomendaciones:

  1. Costo de CPU: Cada proceso paralelo consume CPU. Si el servidor tiene 8 núcleos y lanzas un PARALLEL 32, causarás una degradación general del sistema.
  2. Uso de Memoria: El paralelismo utiliza la PGA de forma intensiva para los ordenamientos y joins. Asegúrate de tener suficiente PGA_AGGREGATE_TARGET.
  3. Tablas pequeñas: No utilices este hint en tablas de pocos registros. El tiempo que le toma a Oracle gestionar los procesos esclavos será mayor que la ganancia de velocidad.

El uso de hints de paralelo es fundamental para grandes volúmenes, pero un grado de paralelismo mal calculado puede afectar a todos los usuarios. ¡Úsalo con cautela y siempre verifica tu plan de ejecución!

miércoles, 15 de abril de 2026

Optimización de Consultas Distribuidas (DBLinks) mediante el uso de Hints


En la administración de bases de datos Oracle, es común trabajar con entornos distribuidos. Sin embargo, las consultas a través de un Database Link (DBLink) suelen ser un dolor de cabeza para el rendimiento. El optimizador a menudo decide traer los datos de la tabla remota para procesarlos localmente, lo que satura la red y eleva los tiempos de respuesta.

Por defecto, Oracle asume que el sitio local (donde lanzas la consulta) debe ser el "maestro". Si tienes una tabla local de 100 filas y una remota de 10 millones, el optimizador podría intentar traerse los 10 millones de filas por la red para hacer el JOIN en tu instancia local.

Para controlar este comportamiento, contamos con una herramienta poderosa: el hint DRIVING_SITE.

El hint /*+ DRIVING_SITE(alias) */ obliga a Oracle a ejecutar la consulta en el nodo donde reside la tabla especificada. Esto permite que los filtros y join se realicen en el sitio remoto, enviando a nuestra base de datos únicamente el resultado final.

Revisemos el siguiente plan de ejecución, donde el optimizador decide procesar todo en el servidor local:

Al observar el plan, podemos identificar por qué esta consulta es una candidata crítica para el uso de DRIVING_SITE:

  • La operación raíz (SELECT STATEMENT) se ejecuta en la instancia local. Esto confirma que el servidor local está actuando como el nodo maestro, asumiendo toda la carga de procesamiento y coordinación.

  • Noten la operación REMOTE. Aquí, Oracle está "succionando" datos desde el DBLink hacia el servidor local. El plan estima solo 1 fila, pero en entornos reales, si esa tabla remota tiene millones de registros, la red se convertirá en un cuello de botella insoportable mientras el servidor local espera los paquetes.

  • El servidor local ya está trabajando intensamente. Está realizando un WINDOW SORT (funciones analíticas), un HASH UNIQUE (eliminación de duplicados) y múltiples HASH JOIN sobre unos 78,620 registros.

  • El HASH JOIN OUTER ocurre localmente. Es decir, después de procesar los 78k registros locales y traer la data remota por la red, el servidor local intenta mezclarlos.

Este es el plan de ejecución después de aplicar el hint. Observen cómo la arquitectura del plan cambia drásticamente:

  • A diferencia del plan anterior, la operación raíz ahora es REMOTE. Esto confirma que el servidor local ha dejado de ser el "maestro" para delegar toda la lógica y coordinación al nodo donde reside la tabla más pesada.

  • Las operaciones de SORT GROUP BY y HASH JOIN se ejecutan ahora en el sitio remoto. La data se filtra, se une y se agrupa antes de viajar, asegurando que por la red solo se envíe el resultado final ya procesado.

  • Al ejecutar la consulta donde viven los datos, Oracle puede utilizar el PARTITION RANGE ITERATOR y los índices locales (INDEX RANGE SCAN). Esto evita escaneos completos innecesarios y aprovecha la arquitectura física diseñada para esa tabla.

  • IMPORTANTE: El hint DRIVING_SITE será ignorado si utilizas funciones PL/SQL locales en la consulta (ej. una función que creaste en tu esquema local aplicada a una columna remota). Oracle necesita que todo lo necesario para procesar el bloque esté disponible en el sitio remoto donde ocurre la ejecución.

    Como administradores de bases de datos, nuestro trabajo no es solo hacer que las consultas funcionen, sino que lo hagan de forma eficiente. El uso de DRIVING_SITE transforma una consulta que podría durar minutos (o colapsar la red) en una que responde en milisegundos, simplemente moviendo la inteligencia del procesamiento al lugar correcto.

    jueves, 9 de abril de 2026

    Resolviendo el error ORA-1652: unable to extend temp segment by 128 in tablespace TEMP


    El error ORA-1652 es uno de los incidentes más temidos por los DBAs. La reacción más común suele ser añadir más archivos de datos (Tempfiles), pero la experiencia demuestra que el aumento en el consumo de espacio temporal es debido a un proceso o consulta ineficiente.

    Cuando el error ocurre, el espacio en TEMP se libera automáticamente al fallar la sesión, borrando los registros en las vistas de tiempo real. Para investigar, debemos consultar el historial de sesiones activas (ASH) para encontrar el pico máximo de consumo de cada consulta.

    SELECT 
        sql_id,
        user_id,
        program,
        round(MAX(temp_space_allocated)/1024/1024/1024,2) AS max_temp_gb,
        MIN(sample_time) AS inicio,
        MAX(sample_time) AS fin
    FROM v$active_session_history
    WHERE temp_space_allocated > 0
      AND sql_id IS NOT NULL
    --Aqui colocamos la fecha y hora relacionada al error ORA-1652  
      AND sample_time BETWEEN TO_TIMESTAMP('08/04/2026 08:00', 'DD/MM/YYYY HH24:MI') 
                          AND TO_TIMESTAMP('08/04/2026 08:30', 'DD/MM/YYYY HH24:MI')
    GROUP BY sql_id, user_id, program
    ORDER BY max_temp_gb DESC;


    En nuestro caso, encontramos que el SQL_ID 85v0ju71vfphg alcanzó un pico de 370 GB. Al revisar el reporte AWR (Automatic Workload Repository), la sección "Top SQL with Top Events" reveló lo siguiente:


    • Evento: direct path write temp
    • Wait Class: User I/O
    • Top Row Source: HASH JOIN / HASH GROUP BY
    ¿Por qué una consulta necesitaría tanto espacio? Al obtener el plan con DBMS_XPLAN.DISPLAY_AWR, detectamos dos problemas críticos:
    1. MERGE JOIN CARTESIAN: El motor intentó realizar un producto cartesiano (unir cada fila con todas las filas de otra tabla) debido a una condición de unión mal definida con una tabla. Esto multiplicó exponencialmente el set de datos intermedio.

    2. SORT UNIQUE: El uso de UNION (en lugar de UNION ALL) obligó a un ordenamiento masivo para eliminar duplicados de un set de datos que ya estaba inflado por el cartesiano.


    Para solucionar esto, el primer paso es auditar la lógica de las uniones (JOINs): asegurar que todas las tablas tengan su predicado de unión correspondiente en el WHERE o en la cláusula ON.

    Si la lógica es correcta pero el optimizador sigue eligiendo un cartesiano por un error de estimación en las estadísticas, podemos intervenir usando el hint /*+ NO_CARTESIAN */. Asimismo, evaluamos cambiar UNION por UNION ALL si sabemos que los resultados de ambas consultas son disjuntos o si los duplicados son aceptables.


    El ORA-1652 no se resuelve simplemente asignando más disco. Antes de ampliar, identifica el pico (ASH), confirma el evento (AWR) y audita la lógica (Plan de Ejecución). Optimizar el código es, en la gran mayoría de los casos, la forma más eficiente y profesional de resolver este error.

    martes, 31 de marzo de 2026

    Dimensionamiento de Memoria en Oracle


    El rendimiento de una base de datos Oracle no depende de cuánta RAM tengas, sino de cómo la distribuyes. En un entorno de producción, la memoria es un recurso finito y costoso; asignarla en exceso es tan peligroso como quedarse corto, ya que puede inducir problemas de paginación a nivel de OS o enmascarar consultas ineficientes que deberían ser optimizadas en código.

    En esta guía aprenderemos a interpretar los Advisors para ajustar la SGA y la PGA utilizando los componentes internos del motor.

    Antes de tocar parámetros, debemos entender que es SGA y PGA:

    • SGA (System Global Area): Memoria compartida. Su objetivo es minimizar la I/O física (lectura de disco).

    • PGA (Program Global Area): Memoria privada por proceso. Su objetivo es realizar ordenamientos y uniones "In-Memory".




    • db file sequential read (11.4% del tiempo): Es el tiempo que la base de datos pasa esperando a que el disco le entregue un bloque de datos que no encontró en la memoria. La SGA es demasiado pequeña para el volumen de datos que consultamos. El motor está "trabajando de más" yendo al disco por información que debería estar ya en la RAM.
    • acknowledge over PGA limit: Este es un evento "semáforo". Aparece cuando Oracle detiene un proceso porque ya se alcanzó el límite máximo de memoria RAM permitido. El sistema está asfixiado. Literalmente está "poniendo en cola" a los usuarios porque no hay más memoria disponible para procesar sus consultas. Es la confirmación de que nuestra PGA necesita crecer urgentemente.

    Diagnostico SGA (V$SGA_TARGET_ADVICE):
    Ejecuta la siguiente consulta:

    SELECT sga_size, sga_size_factor, estd_db_time, estd_physical_reads
    FROM v$sga_target_advice
    ORDER BY sga_size_factor;

    Si aumentamos la SGA de 30 GB a 45 GB (Factor 1.5):

    • Lecturas Físicas: Bajan de 170B a 149B (Una reducción del ~12%).
    • Tiempo de DB: Baja de 118M a 114M (Una mejora de apenas el 3.4%).
    Necesitamos invertir 15 GB adicionales de RAM para obtener una mejora de velocidad que el usuario final probablemente ni siquiera notará.

    Diagnostico PGA(V$PGA_TARGET_ADVICE):
    Ejecuta la siguiente consulta:

    SELECT pga_target_for_estimate/1024/1024 AS target_mb, 
           pga_target_factor, 
           estd_extra_bytes_rw,
           estd_pga_cache_hit_percentage
    FROM v$pga_target_advice;

    Si aumentamos la PGA de 10 GB a 18 GB (Factor 1.8):

    • Tráfico en Disco (Extra Bytes RW): Baja de 186 TB a 182 TB. Ahorramos 4 Terabytes de escritura innecesaria en el TEMP.

    • Eficiencia (Cache Hit %): Sube del 91% al 92%.

    Es una inversión inteligente. Con solo 8 GB adicionales de RAM, eliminamos el cuello de botella que causa el evento acknowledge over PGA limit y estabilizamos las operaciones pesadas.

    Una vez identificado el tamaño óptimo, aplica los cambios. Recuerda que si usas ASMM (Automatic Shared Memory Management), solo ajustas los targets.

    Puedes usar esta consulta para verificar:

    SELECT 
        name, 
        value/1024/1024 AS mbytes, 
        CASE 
            WHEN name = 'sga_target' AND value > 0 THEN 'ASMM: Gestión Automática de SGA'
            WHEN name = 'pga_aggregate_target' AND value > 0 THEN 'PGA: Gestión Automática de Procesos'
            WHEN name = 'memory_target' AND value > 0 THEN 'AMM: Gestión Total (SGA + PGA)'
            ELSE 'Gestión Manual / Límite Estricto'
        END AS modo_gestion
    FROM v$parameter 
    WHERE name IN ('sga_target', 'pga_aggregate_target', 'memory_target', 'pga_aggregate_limit');


    En este caso solo redimensionaremos la PGA, dado que tenemos mayor beneficio por un bajo costo (8GB de RAM).

    -- 1. Subir el Target
    ALTER SYSTEM SET pga_aggregate_target = 18G SCOPE=BOTH;
    -- 2.  Lo ideal es que el limit sea al menos 2x el target
    ALTER SYSTEM SET pga_aggregate_limit = 36G SCOPE=BOTH; 

    La PGA es mucho más flexible. Puedes aplicar los cambios y tendrán efecto inmediato, pero cuidado con el límite (limit), debe ser siempre mayor al target.

    IMPORTANTE:

    No redimensiones sin validar estos tres puntos:

    1. Evitar el Paging: La suma de SGA + PGA + SO nunca debe superar el 80% de la RAM física. Si el SO empieza a usar Swap, el rendimiento de Oracle colapsará.

    2. HugePages (Solo Linux): Si tu SGA es mayor a 8GB, asegúrate de configurar HugePages a nivel de kernel para evitar que el proceso vktm consuma demasiada CPU gestionando tablas de páginas.

    3. Monitoreo Post-Cambio: Tras el ajuste, monitorea V$SQL_WORKAREA_ACTIVE para confirmar que las operaciones pasaron de MULTI-PASS a OPTIMAL.

    La mejor optimización de memoria no es comprar más módulos de RAM, sino reducir la necesidad de ella mediante la indexación correcta y el tuning de sentencias SQL.

    viernes, 20 de marzo de 2026

    Resolviendo las limitaciones del Auto Optimizer Stats Collection en Oracle


    En el mundo de la administración de bases de datos, las estadísticas son la ruta de acceso que el optimizador (CBO) elegirá para ejecutar una sentencia SQL. Sin ellas, hasta la consulta más simple puede convertirse en una pesadilla de rendimiento. Oracle nos ofrece por defecto el Auto Optimizer Stats Collection, un job diseñado gestionar la recolección de estadísticas de forma integral y desatendida. Sin embargo, en entornos de Data Warehouse con volúmenes masivos de datos esto suele ser insuficiente.

    Recientemente, en una de las bases de datos que administro, me enfrenté a un escenario crítico: el mantenimiento nativo de Oracle no lograba concluir dentro de la ventana programada de 4 horas. Esto derivaba en la presencia de estadísticas obsoletas (STALE) y el bloqueo de estadísticas en objetos específicos, provocando una degradación progresiva en el rendimiento global de la base de datos.

    • El proceso se interrumpía dejando gran parte de los objetos sin procesar.

    • Las estadísticas quedaban en un estado inconsistente, impidiendo actualizaciones manuales y disparando errores como el ORA-20005.

    • Sin datos frescos, el optimizador elegía rutas de acceso ineficientes, aumentando drásticamente la latencia global del sistema.

    Para romper este ciclo, decidimos tomar el control total mediante una automatización personalizada. Nuestra lógica aplica reglas de ingeniería de datos claras:

    • El procedimiento identifica si el esquema contiene tablas particionadas o normales para aplicar el método de recolección correcto.
    • Priorizamos la última partición vigente, asegurando que el optimizador (CBO) siempre tenga datos frescos de la carga reciente sin desperdiciar recursos en datos históricos estáticos.
    • Implementamos una tabla de control para registrar cada inicio, fin y duración, permitiendo una auditoría que el job nativo no ofrece de forma tan detallada.

    Importante: Antes de implementar esta solución es necesario desactivar la recolección automática de estadísticas de Oracle. 

    Pero antes verificamos el estado actual de la tarea de recolección de estadísticas.

    select client_name,status from dba_autotask_client where client_name='auto optimizer stats collection';

    Procedemos a desactivar la tarea de recolección automática de Oracle.

    BEGIN
      DBMS_AUTO_TASK_ADMIN.DISABLE(
        client_name => 'auto optimizer stats collection',
        operation   => NULL,
        window_name => NULL
      );
    END;
    /

    Verificamos nuevamente el estado actual de la tarea de recolección de estadísticas.

    He compartido la solución completa (DDL de bitácora, procedimiento PL/SQL y configuración del Job) en mi repositorio de GitHub para que la comunidad pueda adaptarlo:

    🔗Oracle-Stats-Automation

    Puedes consultar el estado de tus estadísticas y el rendimiento del job mediante la tabla de bitácora:

    select * from sys.gbd_bitacora_estat where grupo=5 order by 1,2 asc;

    Esta solución fue desarrollada y validada con éxito en un entorno Oracle Database 12c, demostrando una estabilidad total tanto en la gestión de objetos particionados como en la integración con el Oracle Scheduler. Aunque el enfoque es estándar, se recomienda realizar pruebas previas en entornos de desarrollo antes de pasar a producción.

    martes, 10 de marzo de 2026

    Reubicación de la Auditoría Estándar (AUD$) en Oracle


    En entornos de producción, es común que las áreas de Seguridad de la Información exijan auditar las acciones de los usuarios. El objetivo es claro: garantizar el control y la trazabilidad ante incidentes que puedan impactar negativamente al negocio. Sin embargo, habilitar esta auditoría es solo la mitad del trabajo; la otra mitad es gestionarla correctamente para no comprometer la disponibilidad de la base de datos.

    Uno de los errores más peligrosos en configuraciones por defecto es permitir que la tabla de auditoría estándar (AUD$) crezca dentro de los tablespaces del sistema (SYSTEM o SYSAUX). Si esta crece sin control, corres el riesgo de fragmentar el diccionario de datos o colapsar la instancia por falta de espacio.


    Si la tabla AUD$ crece sin control, corres el riesgo de fragmentar el diccionario de datos o, peor aún, colapsar la instancia por falta de espacio. En este post, te mostraré la forma correcta y soportada de mover la auditoría a un tablespace dedicado utilizando el paquete DBMS_AUDIT_MGMT.


    Importante: Este procedimiento es válido únicamente para la Auditoría Tradicional. Si tu base de datos tiene habilitado Unified Auditing (lo cual es el estándar en 19c), los registros se almacenan en el esquema AUDSYS y la gestión del espacio se realiza exclusivamente mediante el paquete DBMS_AUDIT_MGMT.

    Lo primero es crear un tablespace exclusivo. Es una buena práctica habilitar el AUTOEXTEND con un límite razonable para evitar sorpresas.

    CREATE TABLESPACE TBS_AUDIT DATAFILE '+DATA' SIZE 2G AUTOEXTEND ON NEXT 512M MAXSIZE 30G;

    Antes de realizar cambios, debemos validar la ubicación actual de la tabla AUD$:

    SELECT table_name, tablespace_name 
    FROM dba_tables 
    WHERE table_name IN ('AUD$');


    Para realizar el movimiento de forma segura y soportada, utilizaremos el procedimiento SET_AUDIT_TRAIL_LOCATION. Este se encarga de mover tanto la tabla como sus índices (LOBs incluidos) sin afectar el diccionario de datos.
    BEGIN
    DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
    audit_trail_location_value => 'TBS_AUDIT'); 
    END;
    /
    Una vez ejecutado, verifica que el cambio se haya aplicado correctamente consultando nuevamente el diccionario de datos.

    SELECT table_name, tablespace_name FROM dba_tables WHERE table_name IN ('AUD$');


    Mover la auditoría no es solo una tarea de mantenimiento, es una medida de seguridad operativa. Al separar los logs de auditoría del tablespace SYSTEM, proteges la salud de tu diccionario de datos y facilitas la gestión de purgas futuras.

    Nota: Este procedimiento fue probado en la versión 12c de Oracle.

    Saludos.