Вы находитесь на странице: 1из 11

Recuperacin de datos mediante Flashback

Introduccin Este documento describe los pasos para realizar recuperaciones de datos mediante la tecnologa de Flashback proporcionada por Oracle. Qu nos pueden pedir Ver datos existentes en una tabla en un momento en el tiempo Recuperar datos existentes en una tabla en un momento en el tiempo Recuperar tabla/s borradas con drop table Ver DDL de objetos en un momento en el tiempo Exportar registros usando flashback_time con expdp

Ver datos existentes en un momento en el tiempo En ocasiones, despus de una modificacin de datos (insert, update, delete) en una tabla, nos piden ver la foto de los datos en un momento anterior al actual, para lo que necesitamos consultar los datos de los segmentos undo de la DB, con la siguiente sintaxis:
select [campo1,campo2, | * ] from table_name as of timestamp to_timestamp(fecha_requrida,'dd/mm/yyyy hh24:mi') [where condiciones]

Ejemplo:
SQL> select c1,c2 2 from t_padre 3 where c1 = 2; ninguna fila seleccionada SQL> select c1,c2 2 from t_padre as of timestamp to_timestamp('13/04/2012 11:30','dd/mm/yyyy hh24:mi') 3 where c1 = 2; C1 C2 ---------- ---------2 4 1 fila seleccionada.

Recuperar datos existentes en una tabla en un momento en el tiempo Si una vez consultada la foto del momento anterior, se decide que debe volverse a ese punto en el tiempo, tenemos que recuperar esos datos, bien deshaciendo la transaccin que ha provocado el cambio, o bien volviendo la tabla al punto en el tiempo seleccionado. Elegir una forma u otra de recuperar los datos depende principalmente de un factor: si desde el tiempo al que se quiere volver y el tiempo actual otro usuario/s han realizado otras modificaciones en la tabla. Ejemplo:
SQL> select * from t_padre; C1 C2 ---------- ---------1 2 2 4 3 6 4 8 4 filas seleccionadas. SQL> select * from t_hijo; C1 C3 ---------- ---------1 99 2 98 1 97 1 96 1 95 5 filas seleccionadas. SQL> select sysdate,current_scn from v$database; SYSDATE CURRENT_SCN ------------------- ----------------13/04/2012 11:38:58 50630104197 1 fila seleccionada. SQL> delete t_padre where c1 = 2; 1 fila suprimida. SQL> commit; Confirmacin terminada. SQL> select * from t_padre; C1 C2 ---------- ---------1 2 3 6 4 8 3 filas seleccionadas. SQL> select * from t_hijo; C1 C3 ---------- ---------1 99 98 1 97 1 96 1 95 5 filas seleccionadas.

NOTA: la tabla T_HIJO tiene una FK apuntando a T_PADRE, con la opcin ON DELETE SET NULL. Es importante revisar si existen este tipo de restricciones antes de preparar el procedimiento de recuperacin, ya

que en este caso no valdra slo con recuperar el registro borrado en T_PADRE, habra que restaurar tambin el registro 'hijo'. A) No se han realizado otras modificaciones en la tabla/s Si estamos seguros que no se han realizado otras modificaciones de registros en la tabla desde el momento al que queremos restaurar, podemos realizar un flashback a la tabla/s completas, siendo esta accin ms rpida que ir recuperando los datos deshaciendo las transacciones que los han modificado, si stas son muchas ==> varios updates, inserts, deletes... NOTA: para poder utilizar esta utilidad de Oracle es necesario que est activado el movimiento de registros en la tabla/s a recuperar.
SQL> flashback table t_padre,t_hijo 2 to timestamp to_timestamp('13/04/2012 11:30:00','dd/mm/yyyy hh24:mi:ss'); flashback table t_padre,t_hijo * ERROR en lnea 1: ORA-08189: no se puede realizar flashback en la tabla porque el movimiento de filas no est activado SQL> alter table t_padre enable row movement; Tabla modificada. SQL> alter table t_hijo enable row movement; Tabla modificada. SQL> flashback table t_padre,t_hijo 2 to timestamp to_timestamp('13/04/2012 11:30:00','dd/mm/yyyy hh24:mi:ss'); Flashback terminado. SQL> select * from t_padre; C1 C2 ---------- ---------1 2 2 4 3 6 4 8 4 filas seleccionadas. SQL> select * from t_hijo; C1 C3 ---------- ---------1 99 2 98 1 97 1 96 1 95 5 filas seleccionadas.

B) S se han realizado otras modificaciones en la tabla/s Si sabemos a ciencia cierta que otros usuarios han estado realizando modificaciones en los registros de la tabla/s a recuperar (o no estamos seguros de que no se haya realizado ningn otro cambio), o de todas las modificaciones realizadas slo queremos deshacer alguna/s de ellas, entonces no podemos volver a atrs toda la tabla, slo la transaccin/es requeridas. Esta opcin se conoce como Flashback Version Queries, y nos apoyamos en la vista FLASHBACK_TRANSACTION_QUERY. Primero debemos consultar el versions_xid de la transaccin a deshacer:

SQL> SELECT c1, c2, versions_xid, versions_operation 2 FROM t_padre 3 VERSIONS BETWEEN TIMESTAMP to_timestamp('13/04/2012 11:30','dd/mm/yyyy hh24:mi') 4 AND to_timestamp('13/04/2012 11:45','dd/mm/yyyy hh24:mi') 5 where c1=2; C1 C2 VERSIONS_XID V ---------- ---------- ---------------- 2 4 0004001E0000A991 D 2 4 2 filas seleccionadas.

Conociendo este valor, la vista FLASHBACK_TRANSACTION_QUERY nos proporciona el cdigo SQL para deshacer los cambios:
SQL> select commit_timestamp,logon_user,undo_change#,operation,table_name 2 from FLASHBACK_TRANSACTION_QUERY where XID=HEXTORAW('0004001E0000A991') 3 order by UNDO_CHANGE# desc; COMMIT_TIMESTAMP LOGON_USER UNDO_CHANGE# OPERATION TABLE_NAME ------------------- ----------- ------------ --------- ---------13/04/2012 11:40:40 EXPLOTACION 3 BEGIN 13/04/2012 11:40:40 EXPLOTACION 2 DELETE T_PADRE 13/04/2012 11:40:40 EXPLOTACION 1 UPDATE T_HIJO 3 filas seleccionadas. SQL> select undo_sql from FLASHBACK_TRANSACTION_QUERY 2 where xid=HEXTORAW('0004001E0000A991') 3 and operation in ('DELETE','UPDATE') 4 order by UNDO_CHANGE# desc; UNDO_SQL -------------------------------------------------------------------------------insert into "EXPLOTACION"."T_PADRE"("C1","C2") values ('2','4'); update "EXPLOTACION"."T_HIJO" set "C1" = '2' where ROWID = 'AAA9NhAAEAAANtjAAB'; 2 filas seleccionadas.

Recuperar tabla/s borradas con drop table Si se ha borrado la tabla de la DB, con el comando drop table table_name, an existe la posibilidad de recuperarla, ya que desde Oracle 10g la DB incorpora una recycle bin, similar a la parelera de reciclaje de Windows, en la que se almacena la tabla borrada (con los datos existentes en el momento de hacer el drop), y la recuperacin es muy sencilla:
SQL> drop table t_hijo; Tabla borrada. SQL> select * from t_hijo; select * from t_hijo * ERROR en lnea 1: ORA-00942: la tabla o vista no existe SQL> flashback table t_hijo to before drop; Flashback terminado. SQL> select * from t_hijo; C1 C3 ---------- ---------1 99 2 98 1 97 1 96 1 95 5 filas seleccionadas.

RECYCLEBIN Se llama as a la tabla del diccionario donde Oracle almacena aquellas tablas e ndices del usuario que han sido borrados y que son susceptibles de ser eliminados ==> una tabla o ndice cuando es borrado con drop pasa a Recyclebin.
SQL> show recyclebin ORIGNAME_PLUS_SHOW OBJECTNAME_PLUS_SHOW_RECYC OBJTYPE_PLUS_SHOW DROPTIME_PLUS_SHOW_ ------------------- ------------------------------ ------------------ ------------------T1 BIN$t0SgyI6AIDngRNSFZDhTpg==$0 TABLE 2012-01-24:12:41:30 SQL> select * from user_recyclebin; OBJECT_NAME ORIGINAL_NAME OPERATION TYPE TS_NAME CREATETIME DROPTIME DROPSCN ------------------------------ ------------- --------- ----- ------- ------------------------------------- -----------BIN$t0SgyI6AIDngRNSFZDhTpg==$0 T1 DROP TABLE USERS 2012-01-18:13:32:10 2012-0124:12:41:30 45016403868 1 fila seleccionada.

Tambin existe la tabla dba_recyclebin, que contiene todas las tablas e ndices que pueden ser recuperados de todos los usuarios. Los objetos permanecern en recyclebin de forma indefinida o hasta que Oracle los elimina si necesita espacio en los tablespaces donde se ubican (antes de autoextender un tablespace que est al lmite de su capacidad, Oracle elimina objetos del recyclebin, primero los ms antiguos, empezando por los ndices). A este concepto se le denomina presurizacin (o compresin) del espacio.

Los objetos pueden eliminarse manualmente del recyclebin de varias formas: Borrar objectos de forma individual

PURGE TABLE | INDEX ORIGINAL_NAME;


SQL> purge table t1;

PURGE TABLE | INDEX OBJECT_NAME;


SQL> purge table "BIN$t0SgyI6AIDngRNSFZDhTpg==$0"

Borrar todos los objetos de un tablespace PURGE TABLESPACE TB_NAME; Borrar todos los objetos de un tablespace slo para el usuario x PURGE TABLESPACE TB_NAME USER XXX; Borrar todos los objetos del recyclebin del usuario que lanza la sentencia PURGE RECYCLEBIN; Borrar TODO el contenido del recyclebin (como sys) PURGE DBA_RECYCLEBIN; - Consideraciones: 1) Cuando borramos con DROP TABLE | INDEX NAME PURGE el objeto se borra definitivamente ==> no va a recyclebin 2) Cuando borramos un tablespace con DROP TABLESPACE TB_NAME INCLUDING CONTENTS esos objetos tampoco van a recyclebin 3) Cuando borramos un usuario con DROP USER NAME sus objetos tampoco va a recyclebin 4) Hay que tener privilegio flashback sobre el objeto que queremos recuperar

Ver DDL de objetos en un momento en el tiempo En ocasiones se hace una modificacin DDL de un objeto (tabla, index, trigger, procedure, ), y necesitamos recuperar el DDL original, anterior al cambio, para dar marcha atrs ante posibles fallos del aplicativo. Para esto utilizamos el package DBMS_FLASHBACK, habilitando un punto en el tiempo sobre el que consultar el DDL existente en el diccionario de datos en ese preciso momento.
SQL> select sysdate,current_scn from v$database; SYSDATE CURRENT_SCN ------------------- ----------------20/04/2012 10:09:04 50957802098 1 fila seleccionada. SQL> desc t_hijo Nombre Nulo? ----------------------------------------- -------C1 C3 SQL> alter table t_hijo add (c4 date); Tabla modificada. SQL> desc t_hijo Nombre Nulo? ----------------------------------------- -------C1 C3 C4 Tipo ---------------------NUMBER NUMBER DATE Tipo ---------------------NUMBER NUMBER

SQL> set wrap on SQL> select DBMS_METADATA.GET_DDL ('TABLE', 'T_HIJO', 'EXPLOTACION') from dual; DBMS_METADATA.GET_DDL('TABLE','T_HIJO','EXPLOTACION') -----------------------------------------------------------------------------------------CREATE TABLE "EXPLOTACION"."T_HIJO" ( "C1" NUMBER, "C3" NUMBER, "C4" DATE ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING TABLESPACE "USERS" ENABLE ROW MOVEMENT 1 fila seleccionada. SQL> begin 2 DBMS_FLASHBACK.ENABLE_AT_TIME (to_date('20/04/2012 10:00','dd/mm/yyyy hh24:mi')); 3 end; 4 / Procedimiento PL/SQL terminado correctamente. SQL> select DBMS_METADATA.GET_DDL ('TABLE', 'T_HIJO', 'EXPLOTACION') from dual; DBMS_METADATA.GET_DDL('TABLE','T_HIJO','EXPLOTACION') -----------------------------------------------------------------------------------------CREATE TABLE "EXPLOTACION"."T_HIJO" ( "C1" NUMBER, "C3" NUMBER ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING TABLESPACE "USERS" ENABLE ROW MOVEMENT 1 fila seleccionada.

SQL> begin 2 DBMS_FLASHBACK.disable; 3 end; 4 / Procedimiento PL/SQL terminado correctamente.

Exportar registros usando flashback_time con expdp Si en lugar de tener que ver los registros que haba en una tabla, lo que tenemos que hacer es llevarlos a otra DB, podemos utilizar la tecnologa flashback de Oracle para crear una nueva tabla con los datos que existan en un momento en el tiempo (create tabla t_copia as select * from t as of timestamp...) y hacer un export de esta nueva tabla; o bien podemos realizar esos 2 pasos en uno slo utilizando la caracterstica flashback_time presente en expdp:
SQL> select count(*) from t_hijo; COUNT(*) ---------5 1 fila seleccionada. SQL> select sysdate,current_scn from v$database; SYSDATE CURRENT_SCN ------------------- ------------23/04/2012 10:15:43 51082607876 1 fila seleccionada. SQL> 2 3 4 5 6 7 8 9 10 11 12 declare x number(1); y number(3); begin for x in 1..9 loop for y in 1..999 loop insert into t_hijo values(x,y,sysdate); end loop; end loop; commit; end; /

Procedimiento PL/SQL terminado correctamente. SQL> select count(*) from t_hijo; COUNT(*) ---------8996 1 fila seleccionada.

Queremos recuperar los datos de la tabla que existan a las 10:15, para ello ponemos ese valor en la lnea FLASBACK_TIME del fichero de parmetros:
clase:/SalvaDP/ficheros$ cat params.dp DUMPFILE=exp_flashbck.dmp NOLOGFILE=Y TABLES=EXPLOTACION.T_HIJO FLASHBACK_TIME="TO_TIMESTAMP('23/04/2012 10:15:00','DD/MM/YYYY HH24:MI:SS')" clase:/SalvaDP/ficheros$ export ORACLE_SID=BDCCLASE clase:/SalvaDP/ficheros$ expdp datapump directory=datapump parfile=params.dp Export: Release 11.1.0.7.0 - 64bit Production on Monday, 23 April, 2012 10:32:31 Copyright (c) 2003, 2007, Oracle. Password: All rights reserved.

Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production With the Partitioning option Starting "DATAPUMP"."SYS_EXPORT_TABLE_01": datapump/******** directory=datapump parfile=params.dp Estimate in progress using BLOCKS method... Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 256 KB

10

Processing object type TABLE_EXPORT/TABLE/TABLE Processing object type TABLE_EXPORT/TABLE/INDEX/INDEX Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS . . exported "EXPLOTACION"."T_HIJO" 5.851 KB 5 rows Master table "DATAPUMP"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for DATAPUMP.SYS_EXPORT_TABLE_01 is: /SalvaDP/ficheros/exp_flashbck.dmp Job "DATAPUMP"."SYS_EXPORT_TABLE_01" successfully completed at 10:33:31

Y como puede verse en el log del expdp, los datos exportados son los 5 registros existentes en el punto en el tiempo elegido. NOTA: flashback_time no puede utilizarse si se han realizado operaciones DDL sobre la tabla/s a exportar: alter para aadir / borrar campos, modificaciones en constraints, ...

11

Вам также может понравиться