Purga automática de la Recycle bin

En muchas organizaciones suele estar activa la recyclebin para poder aprovechar del feature “FLASHBACK TABLE”, el cual podemos recuperar una tabla accidentalmente eliminada con tal solo un comando (para el próximo posteo voy a publicar un caso de uso con este grandioso feature). A continuación voy a dejar el instructivo para poder, no solo activar la recyclebin, sino a mantenerla. Los motores Oracle no cuentan con un proceso automático de purga de la recyclebin, lo cual en caso de necesitarlo deberíamos programarlo por nuestra propia cuenta. Eso es lo que les voy a dejar a continuación.

  1. Primero nos vamos a asegurar que tengamos la recyclebin activa.
 sqlplus / as sysdba
SQL> set linesize 300
SQL> show parameter recyclebin
NAME                                 TYPE                             VALUE
------------------------------------ -------------------------------- -----------------------------
recyclebin                           string                           ON

En caso que el valor esté en “off”, debemos activarla. Para ello:

SQL> alter system set recyclebin=on scope=spfile;
System altered.

Ahora si, les comparto un procedure que encontré en un blog de un colega (
Rack Blogger ). La base del procedure es de el, pero lo he modificado dado que al implementarlo el mismo compilaba con errores.
IMPORTANTE: Antes de implementarlo en producción, les aconsejo probar su funcionamiento en los ambientes previos (Desarrollo, QA, Pre-Produccion)

CREATE OR REPLACE PROCEDURE purge_dba_recylebin (
   p_purge_before_date     IN DATE DEFAULT NULL,
   p_purge_keep_versions   IN NUMBER DEFAULT NULL,
   p_test_only             IN VARCHAR2 := 'Y')
IS
   CURSOR c_purge_before_date
   IS
      SELECT owner,object_name, type
        FROM dba_recyclebin
       WHERE droptime  p_purge_keep_versions;

   v_sql   VARCHAR2 (1024);

   PROCEDURE runsql (p_object_owner IN VARCHAR2, p_object_name in varchar2, p_object_type IN VARCHAR2)
   IS
   BEGIN
      v_sql := 'purge '||p_object_type||' '||p_object_owner||'."'|| p_object_name||'"';

      IF (p_test_only = 'N')
      THEN
         BEGIN
            EXECUTE IMMEDIATE v_sql;
         EXCEPTION
            WHEN OTHERS
            THEN
               DBMS_OUTPUT.put_line ('Error dropping ' || p_object_name);
               DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_backtrace);
         END;
      ELSE
         DBMS_OUTPUT.put_line (v_sql);
      END IF;
   END;
BEGIN
   IF p_purge_before_date IS NOT NULL AND p_purge_keep_versions IS NULL
   THEN
      FOR r IN c_purge_before_date
      LOOP
         runsql (r.owner,r.object_name,r.type);
      END LOOP;
   ELSE
      IF p_purge_before_date IS NULL AND p_purge_keep_versions IS NOT NULL
      THEN
         FOR r IN c_purge_before_version
         LOOP
            runsql (r.owner,r.object_name,r.type);
         END LOOP;
      END IF;
   END IF;   
   END purge_dba_recylebin;
/

Ahora generamos el scheduler job que ejecutará cada una hora, y ejecutará la purga de la recyclebin. En este ejemplo creo el job para que corra cada una hora, y voy a mantener 24 horas de recyclebin en la base de datos.

BEGIN
  SYS.DBMS_SCHEDULER.CREATE_JOB
    (
       job_name        => 'SYS.DAILY_PURGE_RECYCLEBIN'
      ,start_date      => SYSTIMESTAMP
      ,repeat_interval => 'freq=hourly; byminute=0; bysecond=0;'
      ,end_date        => NULL
      ,job_class       => 'DEFAULT_JOB_CLASS'
      ,job_type        => 'PLSQL_BLOCK'
      ,job_action      => 'BEGIN purge_dba_recylebin(sysdate-1,NULL,''N''); END;'
-- el sysdate-1 le indico al procedure que quiero mantener 24hs de retención.
      ,comments        => NULL
    );
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'RESTARTABLE'
     ,value     => FALSE);
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'LOGGING_LEVEL'
     ,value     => SYS.DBMS_SCHEDULER.LOGGING_OFF);
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE_NULL
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'MAX_FAILURES');
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE_NULL
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'MAX_RUNS');
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'STOP_ON_WINDOW_CLOSE'
     ,value     => FALSE);
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'JOB_PRIORITY'
     ,value     => 3);
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE_NULL
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'SCHEDULE_LIMIT');
  SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
    ( name      => 'SYS.DAILY_PURGE_RECYCLEBIN'
     ,attribute => 'AUTO_DROP'
     ,value     => TRUE);

  SYS.DBMS_SCHEDULER.ENABLE(name => 'SYS.DAILY_PURGE_RECYCLEBIN');
END;
/

Para chequear el resultado de la corrida del scheduler, ejecutamos lo siguiente

set linesize 300
set pagesize 900
SELECT OWNER,
         JOB_NAME,
         LOG_DATE,
         STATUS,
         RUN_DURATION
    FROM dba_scheduler_job_run_details
   WHERE job_name = 'DAILY_PURGE_RECYCLEBIN'
ORDER BY log_date DESC;

Eso es todo. Ahora nos olvidamos de purgar manualmente la recyclebin

¡Hasta la próxima!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.