Oracle Flashback Query
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.
Contenido
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.