Oracle Flashback Query

De Dos Ideas.
Saltar a: navegación, buscar

Mediante Flashback Query podemos realizar una consulta y acceder a los datos como estaban en un momento del pasado.

Tener en cuenta que esta consulta no “efectiviza” los datos del pasado en el presente, sino que solo los “muestra”. Pero a no desesperar, que en caso de ser necesario, se puede realizar utilizando cursores.

Flashback Query esta implementado usando las estructuras de undo (rollback) que Oracle ya viene utilizando para el soporte transaccional.

La base de datos debe correr con Automatic Undo Management (AUM) y deben estar seteados los siguientes parámetros:

undo_management = auto
undo_tablespace = UNDOTBS1
undo_retention = 1200

undo_tablespace debe tener configurado el nombre del UNDO TABLESPACE creado para contener los segmentos de undo.

undo_retention especifica cuanto tiempo (en segundos) las transacciones comiteadas deben ser retenidas en los segmentos de undo antes de ser sobrescritas. Igualmente, si el tablespace de undo no es lo suficientemente grande como para mantener ese tiempo todas las transacciones comiteadas, Oracle las sobrescribe igual. Y si no se generan muchas transacciones y hay espacio de undo suficiente, las transacciones comineadas estan por tiempo indetermnado. O sea que el undo_retention es un valor de referencia pero no es garantia.

Entonces como referencia, el valor de undo_retention es el límite que tenemos para realizar el flashback.

El usuario que necesite realizar flashback debe tener permiso de ejecución sobre el package DBMS_FLASHBACK.

Los flashback time son redondeados cada 5 minutos, esto quiere decir que podemos recuperar información pasados 5 minutos, 10 minutos, 15 minutos, etc Si solicitamos información de 7 minutos atrás, nos va a traer información de 10 minutos atrás.

Preparación de Ambiente

Parámetros de Configuración

sys@LAB10G> select name, value from v$parameter where name like 'undo%';
NAME                 VALUE
-------------------- ----------
undo_management      AUTO
undo_tablespace      UNDOTBS1
undo_retention       900

Privilegios

sys@LAB10G> grant execute on dbms_flashback to scott;
Concesion terminada correctamente.


Creación de Tabla de Prueba

sys@LAB10G> connect scott/tiger
Conectado.
scott@LAB10G> create table emp_flash as select * from emp;
Tabla creada.
scott@LAB10G> select count(1) from emp_flash;
  COUNT(1)
----------
        14

Ejemplo

Flashback query a fecha

scott@LAB10G>  select to_char(sysdate, 'dd-mm-yyyy hh24:mi') fecha from dual;
FECHA
----------------
23-08-2007 17:08
scott@LAB10G> select count(1) from emp_flash;
  COUNT(1)
----------
        14
scott@LAB10G> delete from emp_flash;
14 filas suprimidas.
scott@LAB10G> commit;
Confirmación terminada.
scott@LAB10G> select count(1) from emp_flash;
  COUNT(1)
----------
         0
Dejo pasar un tiempo...
scott@LAB10G> exec dbms_flashback.enable_at_time(to_date(‘23-08-2007 17:08,’DD-MM-YYYY HH24:MI’));
Procedimiento PL/SQL terminado correctamente.
scott@LAB10G> select count(1) from emp_flash;
 COUNT(1)
----------
       14
scott@LAB10G> execute dbms_flashback.disable;
Procedimiento PL/SQL terminado correctamente.
scott@LAB10G> select count(1) from emp_flash;
 COUNT(1)
----------
        0

Flashback query a SCN

El mismo procedimiento que para fecha pero se utilizan los siguientes procedimientos:

scott@LAB10G> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
                 1004135
scott@LAB10G> exec dbms_flashback.enable_at_system_change_number(1004135);
Procedimiento PL/SQL terminado correctamente.


Flashback Query para recuperar datos perdidos

Estamos en el estado en que se borraron todos los datos de emp_flash.

scott@LAB10G> select count(1) from emp_flash;
  COUNT(1)
----------
         0
scott@LAB10G> DECLARE
 2     cursor c_flash IS select * from emp_flash;
 3     r_emp  emp_flash%ROWTYPE;
 4  BEGIN
 5     dbms_flashback.enable_at_time(to_date(‘23-08-2007 17:08,’DD-MM-YYYY HH24:MI’));
 6
 7     OPEN c_flash;
 8
 9     dbms_flashback.disable;
10
11     LOOP
12         fetch c_flash into r_emp;
13         exit when c_flash%notfound;
14         insert into emp_flash
15         values
16         (r_emp.empno, r_emp.ename, r_emp.job, r_emp.mgr,
17          r_emp.hiredate, r_emp.sal, r_emp.comm, r_emp.deptno);
18     END LOOP;
19
20     CLOSE c_flash;
21     commit;
22  END;
23  /
Procedimiento PL/SQL terminado correctamente.


scott@LAB10G> select count(1) from emp_flash;
  COUNT(1)
----------
        14

Mientras la sesion está en el modo Flashback Quero, solo podemos realizar sentencias SELECT. Las sentencias DML (DELETE, UPDATE, INSERT) no están permitidas hasta que no se ejecuta DBMS_FLASHBACK.DISABLE.

Para poder tomar los datos pasados y hacerlos actuales nuevamente, sólo lo podemos hacer usando un cursor.

El cual se puede abrir en modo Flashback Query, deshabilitar el modo Flashback Query, y el contenido del mismo permanece en memoria y puede usarse para realizar la sentencia DML deseada.

Ver también