Inicio > Database > Operaciones de “FLASHBACK” en Oracle Database

Operaciones de “FLASHBACK” en Oracle Database

Desde la versión 9i del gestor se han introducido funcionalidades en la BBDD, que para muchos de sus usuarios no dejan de ser sorprendentes. Una de ellas es la “Flashback Query” que nos permite realizar “selects” que muestren los valores que existían en la BBDD en un momento anterior en el tiempo. En este post os explicaré esta funcionalidad juntamente con algunas relacionadas y trucos interesantes asociados a ella.

Además intentaré contestar a las preguntas más frecuentes que me hacen los clientes a los que muestro alguna de estas funcionalidades por primera vez…

Empecemos, primero os describo un poco las diferentes opciones de “Flasback” de que disponemos en una BBDD 11gR2 (en versiones anteriores es posible que sólo se disponga de un subconjunto de éstas):

Flashback Query

Nos permite ver los datos de la tabla en un momento del pasado. Con esta técnica podremos acceder a datos borrados o modificados por error.

Se basa en los datos de UNDO y por tanto lo tenemos activo “por defecto” en cualquier BBDD de cualquier versión (XE, Standard Edition o Enterprise Edition).

Flashback Version Query

Nos permite ver el histórico de cambios en una tabla, que modificaciones se han ido realizando en los datos durante un periodo de tiempo de manera ordenada para poder “deshacer” sólo algunos de ellos.

Se basa en los datos de UNDO y lo podremos usar en cualquier BBDD Oracle Enterprise Edition.

Flashback Transaction Query

Si en la anterior podíamos ver el histórico de cambios realizados en una tabla, esta funcionalidad nos permite ver el histórico de cambios realizados por una transacción. Igualmente que en el caso anterior con el sql necesario para “deshacer” sólo algunos de ellos.

Se basa en los datos de UNDO y lo podremos usar en cualquier BBDD Oracle Enterprise Edition.

Flashback Table

En este caso más que ver la tabla como era en un cierto tiempo anterior, la enviamos a un cierto tiempo anterior. Así pues con esta funcionalidad “rebobinamos” una única tabla de la BBDD.

Se basa en los datos de UNDO y lo podremos usar en cualquier BBDD Oracle Enterprise Edition.

Flashback Drop

En caso de borrar una tabla por accidente la podemos recuperar con esta técnica (y junto con ella sus constraints e índices). Se basa en la “Recycle Bin” (papelera de reciclaje) en la que se quedan por defecto las tablas borradas.

La cantidad de objetos borrados que se mantengan guardados en la papelera de reciclaje dependerá de la cantidad de espacio libre que tengamos en los tablespaces en que realizamos el borrado.

La papelera de reciclaje esta activa por defecto en cualquier BBDD de cualquier versión (XE, Standard Edition o Enterprise Edition).

Flashback Database

Finalmente con esta funcionalidad podemos realizar un “rebobinado” de la BBDD dejándola como se encontraba en un tiempo pasado. En caso que suceda algún proceso muy dañino en la BBDD (actualización de aplicaciones problemáticas o similares) podremos rebobinar toda la BBDD en un tiempo mucho menor que el que tardaríamos en recuperar una copia de un momento anterior y en aplicar el archivado necesario hasta el punto previo a la operación problemática. Destacar que esta funcionalidad no sólo se usar para recuperar desastres, por ejemplo, da mucho juego con las BBDD Standby, ya que permite abrirlas para lectura/escritura y volver a dejarlas en modo standby posteriormente.

Requiere tener activada la “flash recovery area”, el modo “flashback” activado y que el gestor sea “Enterprise Edition”.

Algunos detalles más de las “Flashback Query”…

A continuación os detallo algunas particularidades de las “Flashback Querys”, si queremos usar “Flasback Query” deberemos saber que:

  • Que no tenemos que hacer nada para activar esta funcionalidad, de hecho cuando Oracle nos muestra datos “consistentes” en las selects ya está “deshaciendo” los cambios de otras sesiones que habiendo cambiado los mismos datos que seleccionamos no los han “confirmado” aún o lo han hecho posteriormente al inicio de nuestra select. La técnica usada en estos casos es la misma que para el Flasback Query.

Por tanto, a la pregunta “Y que hago para activarlo?” la respuesta es nada, ya lo tienes activo.

  • Que el tiempo que podremos “ir hacia atrás”? dependerá de varios parámetros, como el UNDO_RETENTION, el tamaño del tablespace de UNDO y la cantidad de cambios que se producen en la BBDD.

El parámetro UNDO_RETENTION es una “petición” de cuánto tiempo desearíamos que se mantuvieran los datos de UNDO (lo que implica cuanto tiempo hacia atrás nos podemos mover) y digo que es una petición, porque si Oracle se queda sin espacio en el tablespace de UNDO no se mantendrá el tiempo que hemos definido (sobrescribirá los datos más viejos).

Dependiendo de la cantidad de cambios que se produzcan en la BBDD se generarán más o menos datos de UNDO y por tanto para un determinado tamaño de tablespace de UNDO podremos almacenar datos correspondientes a más o menos tiempo.

Destacar que en las últimas versiones del gestor se puede “forzar” a que se mantenga el tiempo definido en UNDO_RETENTION. En este caso si se llena el tablespace de UNDO ya no se permiten más transacciones.

Deberemos ajustar el tamaño del tablespace de UNDO para poder mantener el tiempo de UNDO_RETENTION requerido en función de los cambios que se generen normalmente (existen varias vistas internas del diccionario que permiten calcular ese valor). Y deberemos pensar que si por alguna razón se “dispara” la generación de UNDO (por cargas o updates masivos) posiblemente durante un tiempo nos quedaremos por debajo del valor de retención deseado.

Por tanto ante la pregunta “Y cuanto tiempo hacia atrás se puede ir?”, depende, es un valor ajustable y “variable” en función de que hagas en la BBDD.

  • El Flashback Query se puede aplicar en caso de INSERT/UPDATE/DELETE. En caso de realizar un TRUNCATE solo podremos optar por el “flashback database” el resto de opciones no funcionarán al no generar el truncate datos de undo.
  • Si realizamos DDL sobre la tabla es posible que dejemos de tener acceso a los datos anteriores de ésta. Esta afirmación dependera del DDL realizado y de la versión del gestor. En 11gR2 por ejemplo podemos añadir una columna sin que esto implique que perdamos acceso a los datos anteriores (la columna añadida se mostrará vacia), pero no podemos modificar las existentes, de hacerlo aparece el error: ORA-01466: unable to read data – table definition has changed

A continuación os muestro un ejemplo simple de Flashback Query. En este caso uso un timestamp para seleccionar de que momento quiero ver los datos, aunque también es posible usar un SCN (de hecho este último es más exacto que el timestamp). Creo una tabla con un valor y la fecha de inserción de éste y selecciono el contenido de esta en diferentes momentos del pasado:

SQL> desc time_test
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
VALUE                                              NUMBER(10)
TIME                                               DATE

SQL> insert into time_test values (1,sysdate);

1 row created.

SQL> commit;

Commit complete.

SQL> insert into time_test values (2,sysdate);

1 row created.

SQL> commit;

Commit complete.

SQL> insert into time_test values (3,sysdate);

1 row created.

SQL> commit;

Commit complete.

SQL> alter session set NLS_DATE_FORMAT = 'DD-MM-YYYY HH24:MI:SS';

Session altered.

SQL> select * from time_test;

VALUE      TIME
---------- -------------------
1          08-07-2011 14:34:24
2          08-07-2011 14:36:30
3          08-07-2011 14:39:02

SQL> SELECT * FROM TIME_TEST
2  AS OF TIMESTAMP
3  TO_TIMESTAMP('08-07-2011 14:35:00', 'DD-MM-YYYY HH24:MI:SS')
4  /

VALUE      TIME
---------- -------------------
1          08-07-2011 14:34:24

SQL> SELECT * FROM TIME_TEST
2  AS OF TIMESTAMP
3  TO_TIMESTAMP('08-07-2011 14:37:00', 'DD-MM-YYYY HH24:MI:SS')
4  /

VALUE      TIME
---------- -------------------
1          08-07-2011 14:34:24
2          08-07-2011 14:36:30

Y finalmente unos cuantos trucos útiles:

  • Si usamos una “Flashback Query” para solucionar alguna incidencia y visto que el acceso a los datos es posible sólo durante un cierto tiempo, es una buena práctica ejecutar un “CREATE TABLE tabla_recuperada AS SELECT FROM tabla AS OF …” tan pronto como podamos. Esto nos permitirá “trabajar” con los datos recuperados sin restricciones de tiempo.
  • Si el error es un delete podemos recuperar las filas perdidas directamente con sentencias del tipo:
INSERT INTO employees
    (SELECT * FROM employees
     AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '60' MINUTE)
    )
    MINUS SELECT * FROM employees);

que insertará en la tabla empleados los datos borrados en los últimos 60 minutos.

  • Si queremos que todas las sentencias en nuestra sesión se realicen en un momento pasado del tiempo sin tener que especificar el AS OF en cada una podemos usar el paquete:

DBMS_FLASHBACK.ENABLE_AT_TIME

o

DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER

  • Uno pequeño truco para desarrolladores: En caso de haber borrado/modificado el código de un paquete y que no tengamos backup, nos queda una posibilidad, que es realizar flashback de la tabla DBA_SOURCE en la que se almacena el código de éstos:
select text from dba_source
as of timestamp systimestamp - interval '60' minute 
where name='MI_CODIGO' order by line;

Con este procedimiento y modificando el timestamp podremos recuperar paquetes, procedimientos y funciones borradas en los últimos minutos (o quizás horas/días).

  • Finalmente, se pueden llegar a crear vistas que nos muestren una “visión del pasado”, pensando siempre que mientras no tengamos asegurado el UNDO_RETENTION no tendremos el 100% de seguridad de que estos datos sean accesibles en todo momento.
CREATE VIEW back_to_past AS
SELECT * FROM mytable AS OF
TIMESTAMP (sysdate - 1);
Categorías:Database Etiquetas: , ,
  1. Sebastián
    octubre 21, 2013 en 17:13

    muy interesante. No es lo que andaba buscando, pero me da pistas.

    Muchas Gracias.

  1. enero 2, 2013 en 09:41
  2. enero 2, 2014 en 09:46

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 )

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 )

Google+ photo

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

Conectando a %s

A %d blogueros les gusta esto: