Buscar este blog

Cargando...

martes, marzo 21, 2006

Uso de logminer.


En alguna ocasión he necesitado recuperar una transacción validada con COMMIT, pero no deseada o errónea. Pongo un ejemplo:

- Usuario borra una fila.
- Por accidente.
- No sabe de qué fila se trata, pero 'algo' ha dicho "registro borrado".
- (...borrado y validado).
- Ni idea de qué datos tenía la fila.
- Ni él, ni nadie.
- Desde ese momento, la fila X ha desaparecido sin rastro.

Con variaciones, éste caso es bastante frecuente, y si el usuario que ha borrado el registro es lo suficientemente rápido, existe una posibilidad de recuperar los datos perdidos.

Generalmente, todas las transacciones convencionales procesan la información pasando por las áreas de redo log. En estos archivos está toda la información correspondiente al nuevo cambio. Oracle basa toda su actividad en el buen funcionamiento del registro de redo log y, por tanto, en esta área únicamente almacena los datos físicos elementales para rehacer la operación. Por tanto, no se almacena información sobre los valores anteriores.

Lo cual sí sucede en el área de rollback, y ¡la gestión de rollback también pasa por redolog!.

Oracle dispone de un paquete, el LOG MINER que permite rastrear los redo logs (online y archivados) junto con la información de rollback disponible también en éstos. Una vez ejecutado el paquete que crea el fichero de diccionario de objetos, Oracle es capaz de interpretar esos redologs y mostrar información tan válida como el SQL generado y el SQL inverso para "reparar" la acción.



SQL> connect / as sysdba
Conectado.
SQL> show parameters utl

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
utl_file_dir                         string      c:\oraclefiles

SQL> exec DBMS_LOGMNR_D.BUILD( DICTIONARY_FILENAME =>'dictionary.ora', DICTIONARY_LOCATION => 'c:\oraclefiles');

Procedimiento PL/SQL terminado correctamente.

SQL> select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------
C:\ORACLE\ORADATA\ORCL\REDO04A.LOG
C:\ORACLE\ORADATA\ORCL\REDO04B.LOG
C:\ORACLE\ORADATA\ORCL\REDO05A.LOG
C:\ORACLE\ORADATA\ORCL\REDO05B.LOG
C:\ORACLE\ORADATA\ORCL\REDO06A.LOG
C:\ORACLE\ORADATA\ORCL\REDO06B.LOG

6 filas seleccionadas.

SQL> exec DBMS_LOGMNR.add_logfile('C:\ORACLE\ORADATA\ORCL\REDO04A.LOG');

Procedimiento PL/SQL terminado correctamente.

SQL> exec DBMS_LOGMNR.add_logfile('C:\ORACLE\ORADATA\ORCL\REDO05A.LOG');

Procedimiento PL/SQL terminado correctamente.

SQL> exec DBMS_LOGMNR.add_logfile('C:\ORACLE\ORADATA\ORCL\REDO06A.LOG');

Procedimiento PL/SQL terminado correctamente.

SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(DICTFILENAME =>'c:\oraclefiles\dictionary.ora');

Procedimiento PL/SQL terminado correctamente.

SQL> set pages 100
SQL> set lines 120
SQL> column sql_redo format a50
SQL> column sql_undo format a50

SQL> select sql_redo, sql_undo from v$logmnr_contents where rownum<10;

SQL_REDO                                           SQL_UNDO
-------------------------------------------------- --------------------------------------------------
insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '170,01' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '170,01' and "Importe MIN" = '
,"Detalle Vuelo") values ('170,01','1','170,01','1 170,01' and "Importe AVG" = '170,01' and "Ciudad"
70,01','170,01','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52149');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52149' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAA';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '112,95' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '112,95' and "Importe MIN" = '
,"Detalle Vuelo") values ('112,95','1','112,95','1 112,95' and "Importe AVG" = '112,95' and "Ciudad"
12,95','112,95','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52206');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52206' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAB';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '123,29' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '123,29' and "Importe MIN" = '
,"Detalle Vuelo") values ('123,29','1','123,29','1 123,29' and "Importe AVG" = '123,29' and "Ciudad"
23,29','123,29','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52331');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52331' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAC';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '178,55' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '178,55' and "Importe MIN" = '
,"Detalle Vuelo") values ('178,55','1','178,55','1 178,55' and "Importe AVG" = '178,55' and "Ciudad"
78,55','178,55','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52419');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52419' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAD';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '107,36' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '107,36' and "Importe MIN" = '
,"Detalle Vuelo") values ('107,36','1','107,36','1 107,36' and "Importe AVG" = '107,36' and "Ciudad"
07,36','107,36','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52488');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52488' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAE';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '120,5' and "Importe COUNT" = '1' a
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" nd "Importe MAX" = '120,5' and "Importe MIN" = '12
,"Detalle Vuelo") values ('120,5','1','120,5','120 0,5' and "Importe AVG" = '120,5' and "Ciudad" = 'M
,5','120,5','Madeira','Portugal','Mayores de 50 a± adeira' and "Pais" = 'Portugal' and "Rango Edad" =
os','Mujer','VUELO52561');                          'Mayores de 50 a±os' and "Sexo" = 'Mujer' and "De
                                                   talle Vuelo" = 'VUELO52561' and ROWID = 'AAALVmAAP
                                                   AAAAn8AAF';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '109,01' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '109,01' and "Importe MIN" = '
,"Detalle Vuelo") values ('109,01','1','109,01','1 109,01' and "Importe AVG" = '109,01' and "Ciudad"
09,01','109,01','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52690');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52690' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAG';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '174,91' and "Importe COUNT" = '1'
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" and "Importe MAX" = '174,91' and "Importe MIN" = '
,"Detalle Vuelo") values ('174,91','1','174,91','1 174,91' and "Importe AVG" = '174,91' and "Ciudad"
74,91','174,91','Madeira','Portugal','Mayores de 5 = 'Madeira' and "Pais" = 'Portugal' and "Rango Eda
0 a±os','Mujer','VUELO52693');                     d" = 'Mayores de 50 a±os' and "Sexo" = 'Mujer' and
                                                    "Detalle Vuelo" = 'VUELO52693' and ROWID = 'AAALV
                                                   mAAPAAAAn8AAH';

insert into "DISCOVERER9I"."EUL5_MV101651"("Import delete from "DISCOVERER9I"."EUL5_MV101651" where "
e SUM","Importe COUNT","Importe MAX","Importe MIN" Importe SUM" = '131,5' and "Importe COUNT" = '1' a
,"Importe AVG","Ciudad","Pais","Rango Edad","Sexo" nd "Importe MAX" = '131,5' and "Importe MIN" = '13
,"Detalle Vuelo") values ('131,5','1','131,5','131 1,5' and "Importe AVG" = '131,5' and "Ciudad" = 'M
,5','131,5','Madeira','Portugal','Mayores de 50 a± adeira' and "Pais" = 'Portugal' and "Rango Edad" =
os','Mujer','VUELO52951');                          'Mayores de 50 a±os' and "Sexo" = 'Mujer' and "De
                                                   talle Vuelo" = 'VUELO52951' and ROWID = 'AAALVmAAP
                                                   AAAAn8AAI';


9 filas seleccionadas.

6 comentarios:

xBrYaNx dijo...

Hola que tal muy interesante, pero si no tengo una direccion en utl_files, ya no puedo hacer la recuperacion? Que son esos utl_files?

Saludos,

angel dijo...

Es cierto. Los desastres informáticos son totalmente inesperados, desde un pico de tension hasta un virus informático que te hace perder el tiempo hasta la desesperación. Es terrible el tiempo que he perdido en limpiar el ordenador, ni siquiera con una restauración del sistema se ha corregido el problema. A golpe de HKEY_LOCAL_MACHINE/Run y RunOnce. Que horror, y ni que decir de los Adware, hay que ser cansinos. Cuantas veces se nos ha pasado por la cabeza que se nos estropea el ordenador y que tenemos que hacer una copia de seguridad cuanto antes. Nadie ni núnca se esta a salvo de una eventual pérdida de datos de discos duros de ahí la importancia de un buen sistema de copias de seguridad. Esta es la mejor forma de recuperar su informacion en un momento de desastre que generalmente coincide con las prisas a la hora de utilizar el sistema. Y si a pesar de todo es necesario una recuperacion de datos ó recuperar el disco duro porque no teníamos las copias actualizadas, le recomendamos consulte con una empresa especializada como es el caso de www.lineared.com en dónde le podrán recuperar los datos ó llevar a cabo la recuperacion del disco duro . No lo dude, esta es la forma mas eficaz y segura de recuperar discos duros .

Nayuribe dijo...

hola me gusta tu blog soy desarrolladora en Oracle, me encantaria intercambiar opiniones
Soy de Costa Rica

ibrais@gmail.com

Anónimo dijo...

Hola, me sirvio mucho tu post para comenzar con log miner , pero tengo una consulta, es posible encontrar las transacciones dentro de un determinado rango de fechas?
Ejecute los pasos que mencionas y al final probe lo siguiente:

SQL> EXECUTE sys.DBMS_LOGMNR.START_LOGMNR(DICTFILENAME =>'/usr/tmp/dictionary.dic',STARTTIME =
> TO_DATE('30-Oct-2007 12:30:00','DD-MON-YYYY HH:MI:SS'),ENDTIME => TO_DATE('30-Oct-2007 12:49:00',
'DD-MON-YYYY HH:MI:SS'));
BEGIN sys.DBMS_LOGMNR.START_LOGMNR(DICTFILENAME =>'/usr/tmp/dictionary.dic',STARTTIME => TO_DA

*
ERROR at line 1:
ORA-01291: falta el archivo log
ORA-06512: en "SYS.DBMS_LOGMNR", línea 53
ORA-06512: en línea 1

No entiendo porque me sale este error, cuando ya registre un redolog

Anónimo dijo...

Buenas Tardes,
Interesante la documentación acerca de la herramienta LogMiner Viewer.

Pero tengo una pregunta, sobre los resultados que se muestran despues de buscar las transacciones realizadas sobre una tabla especifica de la base de datos.

Resulta que tengo unos informes en formato html generados con logminer viewer y hay ciertos momentos de trabajo de un usuario en los que aparecen operaciones del tipo UNSUPPORTED, entonces solo aparece este texto para todas las columnas generadas en el archivo y al final me informa qué usuario genera esta transacción.

Qué significado tiene este tipo de operación (UNSUPPORTED) y cómo lo puedo explicar en un informe de auditoria?

Anónimo dijo...

UNSUPPORTED quizás sea porque las tablas contengan datos de tipo LOB...