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:ORACLEORADATAORCLREDO04A.LOG
C:ORACLEORADATAORCLREDO04B.LOG
C:ORACLEORADATAORCLREDO05A.LOG
C:ORACLEORADATAORCLREDO05B.LOG
C:ORACLEORADATAORCLREDO06A.LOG
C:ORACLEORADATAORCLREDO06B.LOG

6 filas seleccionadas.

SQL> exec DBMS_LOGMNR.add_logfile(‘C:ORACLEORADATAORCLREDO04A.LOG’);

Procedimiento PL/SQL terminado correctamente.

SQL> exec DBMS_LOGMNR.add_logfile(‘C:ORACLEORADATAORCLREDO05A.LOG’);

Procedimiento PL/SQL terminado correctamente.

SQL> exec DBMS_LOGMNR.add_logfile(‘C:ORACLEORADATAORCLREDO06A.LOG’);

Procedimiento PL/SQL terminado correctamente.

SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(DICTFILENAME =>’c:oraclefilesdictionary.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.

Comments

  1. xBrYaNx
    • 14 enero, 2007
    • 12:17 pm
    • Reply

    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,

  2. Nayuribe
    • 12 septiembre, 2007
    • 4:09 pm
    • Reply

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

    ibrais@gmail.com

  3. Anónimo
    • 31 octubre, 2007
    • 3:58 pm
    • Reply

    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

  4. Anónimo
    • 31 enero, 2008
    • 9:26 pm
    • Reply

    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?

  5. Anónimo
    • 14 febrero, 2008
    • 11:36 am
    • Reply

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

  6. luz e Cano
    • 12 septiembre, 2012
    • 8:06 pm
    • Reply

    Hola..

    Es un ejemplo de fácil entendimiento.

    Mil gracias,

  7. dekano
    • 17 septiembre, 2015
    • 4:34 pm
    • Reply

    Muchas gracias de verdad, mi primera toma de contacto con esto, bien explicado y conseguido ayudarme en el problema que tenia

Deja una respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.