LogMiner 1 : initialisation et démarrage; pas si simple que ça - LogMiner 1 : initialization and startup; not that simple
Introduction
LogMiner est un outil Oracle extrêmement puissant. Il permet d'auditer les opérations DML et DDL survenues sur une base, identifier qui les a exécutées, quand mais aussi comment les annuler voir les réexécuter. Bref, la richesse de cet outil fait que vous devez le connaître en tant que DBA mais son utilisation n'est pas si simple que cela. J'en veux pour preuve que la documentation que j'avais rédigée sur Oracle 11g n'est plus utilisable sur Oracle 12c, peut-être à cause de la nouvelle architecture multi-tenants qui a entraîné de grands bouleversements dans les outils Oracle.
Ayant récupéré une VM Oracle 19, j'ai voulu retravailler sur LogMiner car cet outil est vraiment très utile. Nous verrons que son initialisation est toujours aussi complexe, d'autant plus que la doc Oracle n'est pas très friendly pour les débutants.
Attention aux infos suivantes
- Oracle 19c : pas de nom de table ou de colonne de plus de 30 caractères
- vue V$LOGMNR_CONTENTS :
- vous devez avoir le privilège SYSDBA ou LOGMINING pour la requêter
- ses enregistrements sont triés par le SCN des opérations
- elle est différente des autre vues Oracle car les données ne sont pas présentes par défaut dans cette vue mais sont extraites à chaque requête depuis les redo logs du disque dur
Autres articles sur LogMiner :
- LogMiner 2 : les archived redologs, le mode archive log, la FRA
- LogMiner 3 : infos utiles pour les ordres DML et DDL
- LogMiner 4 : impossible de récupérer le contenu d'une table droppée par erreur
Points d'attention
N/A.
Base de tests
Une base Oracle 19c multi-tenants.
Exemples
============================================================================================
Activation des supplemental logging
============================================================================================
Ma base est une 19c, architecture multi-tenants.
SQL> select banner, cdb from v$version, v$database;
BANNER CDB
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production YES
Première chose à faire, modifier le paramètre d'affichage des dates pour avoir l'heure.
L'activation des supplemental logging est un pré-requis au lancement de LogMiner. De ce que j'ai compris, "SUPPLEMENTAL LOG DATA" signifie qu'on veut ajouter dans les redo log (LOG) des informations (DATA) supplémentaires (SUPPLEMENTAL) sur les enregistrements modifiés par les opérations DML et sur les opérations DDL. Par défaut, ils ne sont pas activés.
J'ai essayé de lancer la requête ci-dessous mais ça coince... Pourtant ici https://docs.oracle.com/en/database/oracle/oracle-database/19/sutil/oracle-logminer-utility.html#GUID-D2DDD67C-E1CC-45A6-A2A7-198E4C142FA3 Oracle nous conseille cet ordre SQL.
Si je me mets dans une PDB, c'est pas mieux, l'opération doit se faire dans le CDB$ROOT.
Je repasse dans le CDB$ROOT et, en cherchant sur le net, je tombe sur cette commande qui marche mieux: visiblement il faut dire à Oracle quoi logger en plus quand des opérations DML ont lieu.
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, FOREIGN KEY, UNIQUE INDEX) COLUMNS;
On vérifie que c'est OK. Extrait de la doc : "IMPLICIT - Minimal supplemental logging is enabled because all or a combination of primary key, unique key, and foreign key supplemental logging is enabled".
Pour supprimer les supplemental logging, il existe une commande d'après la doc Oracle qui, pas de chance, ne marche pas... décidemment, cette doc n'est pas facile à utiliser.
============================================================================================
Spécifier un dictionnaire LogMiner
============================================================================================
La prochaine étape est de dire à LogMiner quel dictionnaire de données il doit utiliser. C'est indispensable pour que les id des objets affichés dans LogMiner soient remplacés par leur nom, pour plus de lisibilité. Oracle préconise d'utiliser le catalogue en ligne, c'est à dire le dictionnaire de données : "To direct LogMiner to use the dictionary currently in use for the database, specify the online catalog as your dictionary source when you start LogMiner." Nous avons le choix : soit on utilise DBMS_LOGMNR_D.BUILD pour créer un dictionnaire pour LogMiner puis on démarre l'outil soit on spécifie le dictionnaire à utiliser quand on démarre LogMiner.
Démarrons LogMiner en lui disant d'utiliser le catalogue en ligne. Et zut, erreur : pb de logfile introuvable.
J'essaye une autre syntaxe, avec des dates de début et de fin mais encore un échec. Nous sommes le 1er juin 2021.
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR( STARTTIME => '30-May-2021 08:30:00', ENDTIME => '01-Jun-2021 08:45:00', OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG );
OK, je regarde alors quelles sont les dates min et max dans les redo logs utilisés.
Ca coince encore!
Bon, visiblement il faut que je dise d'abord à Oracle quels sont les fichiers redo logs à utiliser pour son dictionnaire de données. La liste des redologs non archivés est la suivante.
Attention au piège : pour le premier fichier à ajouter, utilisez la procédure DBMS_LOGMNR.NEW alors que pour les autres ce sera DBMS_LOGMNR.ADDFILE. Je n'ajoute que les redologs non archivés; pour les archivés nous verrons un autre jour.
Une fois les fichiers redologs paramétrés, LogMiner accepte enfin de démarrer.
============================================================================================
La vue V$LOGMNR_CONTENTS
============================================================================================
Il existe plusieurs vues dynamiques de performances pour LogMiner. La plus importante est V$LOGMNR_CONTENTS.
SQL> select distinct object_name from dba_objects where object_name like 'V$%LOGMNR%' or object_name like 'CDB%LOGMNR%' order by 1;
OBJECT_NAME
-----------------------------------
CDB_LOGMNR_LOG
CDB_LOGMNR_PROFILE_PLSQL_STATS
CDB_LOGMNR_PROFILE_TABLE_STATS
CDB_LOGMNR_PURGED_LOG
CDB_LOGMNR_SESSION
V$LOGMNR_CONTENTS
V$LOGMNR_DICTIONARY
V$LOGMNR_DICTIONARY_LOAD
V$LOGMNR_LATCH
V$LOGMNR_LOGFILE
V$LOGMNR_LOGS
V$LOGMNR_PARAMETERS
V$LOGMNR_PROCESS
V$LOGMNR_SESSION
V$LOGMNR_STATS
V$LOGMNR_TRANSACTION
16 rows selected.
La vue V$LOGMNR_CONTENTS est-elle accessible depuis le CDB$ROOT? Oui!, c'est bon, l'initialisation de LogMiner est terminée, on peut enfin interroger l'historique des opérations de notre base :-)
Comme vous le voyez, cette vue est très riche.
Oh, j'ai perdu plein d'opérations avec ma tentative de création d'une table... Comment cela s'explique-t-il? Vous avez-une idée?
SQL> select count(*) FROM V$LOGMNR_CONTENTS;
A noter que la vue V$LOGMNR_CONTENTS n'est pas accessible depuis une PDB mais on peut quand même faire un DESC dessus.
SQL> select count(*) FROM V$LOGMNR_CONTENTS;
SQL> desc V$LOGMNR_CONTENTS
Ah, c'est pas si simple que ça... Bon, je ne vais pas aller plus loin, c'est une optimisation de LogMiner et le but de l'article est de présenter les étapes indispensables pour démarrer cet outil.
============================================================================================
Interroger l'historique de la base avec V$LOGMNR_CONTENTS
============================================================================================
OK, rien avec le user HR... eh bien on va créer des opérations DML avec ce user et voir si elles apparaissent bien dans la vue. A noter qu'avant l'Insert je fais un Truncate de la table zz1 qui contenait 100 000 rows.
SQL> show con_name
SQL> insert into zz1 values (1000, 'DUPONT', 'MICHEL', 1000);
SQL> commit;
Je me reconnecte comme SYS et là, je découvre que ma session LogMiner s'est terminée quand j'ai changé de user.
SQL> select SEG_OWNER, OPERATION, COUNT(*)
Bon, on redémarre LogMiner.
Ah oui, il faut TOUT refaire!
Ne me demandez pas pourquoi en quelques minutes on est passé de 86574 à 688960 enregistrements. J'ai fais un Truncate sur une table de 100 000 rows en plus de l'Insert, c'est tout...
Ah, le résultat est nettement plus excitant, j'ai des opérations du user HR :-) L'opération DDL doit être le Truncate. Bizarrement j'ai aussi une opération du user HR02 et de users qui n'étaient pas présents dans le Select précédent...
25 rows selected.
============================================================================================
Fin de la session LogMiner
============================================================================================
Pour fermer la session LogMiner, soit vous clôturez votre session Oracle soit vous exécutez la procédure DBMS_LOGMNR.END_LOGMNR soit vous exécutez la procédure DBMS_LOGMNR.ADD_LOGFILE avec l'option NEW.
Une fois celle-ci appelée, la vue V$LOGMNR_CONTENTS n'est plus accessible.
SQL> EXECUTE DBMS_LOGMNR.END_LOGMNR;
PL/SQL procedure successfully completed.
SQL> select count(*) from V$LOGMNR_CONTENTS;
select count(*) from V$LOGMNR_CONTENTS
*
ERROR at line 1:
ORA-01306: dbms_logmnr.start_logmnr() must be invoked before selecting from v$logmnr_contents
Conclusion
On s'arrête là pour aujourd'hui, l'objectif était "juste" de voir comment démarrer LogMiner. Comme dit, ce n'est pas si simple, surtout que la doc, si elle est exhaustive, ne vas pas directement à l'essentiel.