Il peut arriver qu'il soit nécessaire d'enquêter sur les modifications récentes apportées à la base de données et de signaler ce qui a été modifié, quand et par qui. Pendant des années, le package DBMS_LOGMNR d'Oracle a été disponible pour de telles tâches, mais ses invocations n'ont pas été entièrement couvertes. Les méthodes conventionnelles utilisent la procédure ADD_LOGFILE() pour préparer Log Miner à utiliser avec un appel de base à la procédure START_LOGMNR. Cela démarre l'utilitaire avec le SCN actuel comme point de départ. Il existe une autre façon de démarrer Log Miner, en sélectionnant un SCN de démarrage valide et en le fournissant à l'appel START_LOGMNR(). Dans cet article, vous verrez comment cela peut être fait et, ce faisant, vous révélerez un éventuel domaine de préoccupation concernant les allocations PGA.
En regardant un script "plain vanilla" pour démarrer Log Miner, les appels de procédure habituels sont effectués pour démarrer Log Miner avec le SCN actuel :
---- run_logmnr.sql---- Ajouter des fichiers journaux et définir DBMS_LOGMNR sur-- extraire en continu les journaux d'archives--définir la taille de ligne 200 trimspool sur la taille de page 0---- Ajouter les fichiers journaux existants---- Omettre les fichiers journaux de secours- -select 'exec dbms_logmnr.add_logfile('''||member||''')'from v$logfilewhere type <> 'STANDBY'and member in (select min(member) from v$logfile group by group#)spool /tmp/add_logfiles.sql/spool off@/tmp/add_logfiles---- Démarrer logmnr en mode minage continu--exec dbms_logmnr.start_logmnr(options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.CONTINUOUS_MINE + DBMS_LOGMNR.COMMITTED_DATA_ONLY)
Notez que tous les journaux redo disponibles sont ajoutés avant le démarrage de Log Miner. Il existe une autre méthode qui fournit un SCN de démarrage à l'appel start_logmnr, tant que la base de données fonctionne en mode ARCHIVELOG :
BEGIN DBMS_LOGMNR.START_LOGMNR( startScn =>, endScn => , OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY + DBMS_LOGMNR.CONTINUOUS_MINE);END;/
Fait intéressant, le SCN final n'est pas nécessaire pour démarrer une session Log Miner. La base de données doit être en mode ARCHIVELOG pour que l'option CONTINUOUS_MINE puisse être spécifiée, car Log Miner ajoutera automatiquement chaque fichier journal archivé disponible lors de son exécution. L'utilisation de cette méthode permet d'utiliser un SCN spécifique pour lancer n'importe quelle recherche ; en spécifiant la recherche entre parenthèses SCN de fin afin que seul un sous-ensemble limité de données soit renvoyé à la vue V$LOGMNR_CONTENTS et fournisse un point d'arrêt pour la recherche, afin qu'une requête de la vue puisse se terminer.
C'est une tâche simple de surveiller la progression de Log Miner en vérifiant le journal d'alerte de la base de données lorsque les entrées marquées par "LOGMINER" sont enregistrées. Une entrée complète comprendra une ligne BEGIN et une ligne END, comme indiqué ci-dessous :
Mon Oct 07 12:48:22 2019LOGMINER :Terminer l'exploration du fichier journal pour la session -2147482111 thread 1 séquence 9776, /oracle/archive/awcis/awcis_0000009776_0001_1008544071.arcMon Oct 07 12:48:22 2019LOGMINER :Commencer l'exploration du fichier journal pour la session - 2147482111 Thread 1 séquence 9777, /oracle/archive/awcis/awcis_000000977_0001_1008544071.arcmon 07 oct :48:36 LOGMINER 2019 :début de l'exploration du fichier journal pour la session -2147482111 thread 1 séquence 9778, /oracle/archive/awcis/awcis_0000009778_0001_1008544071.arcMon Oct 07 12:48:49 2019LOGMINER :fin de l'exploration du fichier journal pour la session -2147482197 thread 1 séquence oracle/archive/awcis/awcis_0000009778_0001_1008544071.arcMon Oct 07 12:48:49 2019LOGMINER :Commencer l'exploration du fichier journal pour la session -2147482111 thread 1 séquence 9779, /oracle/archive/awcis/awcis_0000009779_0004_4071.5Pour les sessions Oracle locales, les nombres sont des entiers positifs ; pour les sessions distantes, initiées par des utilitaires tels que Perl, Python, C/C++ ou d'autres langages, des entiers négatifs seront vus (les entrées présentées ci-dessus ont été initiées par un script Python). Les noms des fichiers journaux parcourront à la fois les journaux redo en ligne et les copies archivées disponibles.
Le démarrage de Log Miner de cette manière peut également générer des erreurs telles que "fichier journal manquant" lorsque le SCN ou la plage SCN de départ sélectionné n'est plus disponible dans le flux de rétablissement. Les requêtes de longue durée peuvent rencontrer de telles erreurs. De plus, si le SCN est hors de portée par rapport aux fichiers journaux disponibles, Log Miner ne démarrera pas, lançant :
ERREUR à la ligne 1 :ORA-01292 :aucun fichier journal n'a été spécifié pour la session LogMiner actuelleORA-06512 :à "SYS.DBMS_LOGMNR", ligne 58ORA-06512 :à la ligne 2Pour aider à éliminer de telles erreurs, la sélection du FIRST_CHANGE# dans la vue V$LOG fournira des points de départ valides pour une session Log Miner ; l'utilisation d'une requête similaire sur V$ARCHIVED_LOG renverra tous les SCN de départ disponibles pour les copies de restauration archivées.
Ce n'est pas la seule complication liée à l'utilisation de Log Miner de cette manière. En fonction de la quantité d'informations à renvoyer, le processus Logmminer peut allouer de grandes quantités de mémoire PGA qui peuvent, si pga_aggregate_limit est petit, générer l'erreur suivante :
ORA-04036 :La mémoire PGA utilisée par l'instance dépasse PGA_AGGREGATE_LIMITheureusement ce n'est pas une erreur fatale. Comme les ressources PGA ne sont plus nécessaires, la mémoire peut être restituée à la base de données pour être utilisée ailleurs. Cependant, cela peut prendre un peu plus de temps que souhaité pour que cette mémoire soit libérée dans le pool de mémoire. Une option consiste à définir pga_aggregate_limit supérieur à la somme des sessions Log Miner, ce qui peut empêcher l'erreur de se produire. Comment savez-vous quelle mémoire est allouée à ces sessions ? Une vue, V$PROCESS_MEMORY_DETAIL, est disponible dans la base de données. Mais tenter d'interroger cette vue sans préparation renverra :
aucune ligne sélectionnée.Il s'agit d'un problème relativement mineur, mais il nécessite l'utilisation de l'utilitaire oradebug. Les étapes suivantes chargeront les données dans V$PROCESS_MEMORY_DETAIL :
---- Définir l'identifiant de la session actuelle-- oradebug setmypid---- Utiliser le PID du processus souhaité-- vider les données de la mémoire---- Cela remplit V$PROCESS_MEMORY_DETAIL--oradebug pga_detail_get- --- Interrogez la vue pour obtenir les données souhaitées -- sélectionnez * From v$process_memory_detail;---- Pour remplir à nouveau la vue avec des données plus récentes -- exécutez simplement l'instruction oradebug pga_detail_get-- oradebug pga_detail_get Un script pour effectuer ces actions est illustré ci-dessous :
---- Configurer l'environnement pour les appels oradebug--oradebug setmypidset echo off trimspool onset verify offundefine p_1undefine p_2undefine s1undefine s2variable p1 numbervariable p2 numbercolumn sys_date new_value sysdt noprintselect to_char(sysdate, 'RRRRMMDDHH24MISS') sys_date from dual;-- -- Récupère l'identifiant du processus de la session--column pid new_value p_1select pid from v$process where addr in (select paddr from v$session where username =' ' and sid =(select max(sid) From v$session where username =' '));begin :p1 :=&p_1;end;/---- Vider les détails du processus vers v$process_memory_detail--oradebug dump pga_detail_get &p_1spool &p_1._pga_stats_&sysdt..log--- - Obtenir des informations de session pour --COLUMN alme HEADING "Allocated MB" FORMAT 99999D9COLUMN usme HEADING "Used MB" FORMAT 99999D9COLUMN frme HEADING "Freeable MB" FORMAT 99999D9COLUMN mame HEADING "Max MB" FORMAT 99999D9COLUMN username FORMAT a25COLUMN program FORMAT a22COLUMN sid FORMAT a5COLUMN spid FORMAT a8column pid_remote format a12SET LINESIZE 300SELECT s.username, SUBSTR(s.sid,1,5) sid, p.spid, logon_time, SUBSTR(s.program,1,22) program , s.process pid_remote, s.status, ROUND(pga_used_mem/1024/1024) usme, ROUND(pga_alloc_mem/1024/1024) alme, ROUND(pga_freeable_mem/1024/1024) frme, ROUND(pga_max_mem/1024/1024) mameFROM v$session s, v$process pWHERE p.addr=s.paddrAND s.username =' 'ORDER BY pga_max_mem,logon_time;---- Veille 30 secondes---- Récupérer les informations de session--exec dbms_lock.sleep(30) colonne sid nouvelle_valeur s1 noprintSELECT s.username, SUBSTR(s.sid,1,5) sid, p.spid, logon_time, SUBSTR(s.program,1,22) programme , s.process pid_remote, s.status, ROUND( pga_used_mem/1024/1024) usme, ROUND(pga_alloc_mem/1024/1024) alme, ROUND(pga_freeable_mem/1024/1024) frme, ROUND(pga_max_mem/1024/1024) mameFROM v$session s,v$process pWHERE p.addr=s.paddrAND s.username =' 'ORDER BY pga_max_mem,logon_time;exec dbms_lock.sleep(10)select max(sid) sid from v$session where username =' ' ;---- Obtenir des informations sur la mémoire du processus--COLUMN category HEADING "Catégorie"COLUMN alloué HEADING "Octets alloués"COLUMN used HEADING "Octets utilisés"COLUMN max_allocated HEADING "Max octets alloués"SELECT pid, catégorie, alloué, utilisé, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$process WHERE addr in (select paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)SELECT pid, catégorie, alloué, utilisé, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$process WHERE addr in (select paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)select pid from v$process whe re addr in (select paddr from v$session where username =' ' and sid =(select max(sid) from v$session where username =' '));---- Enregistrer la première passe de pga stats--CREATE TABLE tab1 ASSELECT pid, category, name, heap_name, bytes, allocation_count, heap_descriptor, parent_heap_descriptorFROM v$process_memory_detailWHERE pid =&p_1AND category ='Other';---- Obtenir une seconde passe de pga stats--oradebug dump pga_detail_get &p_1exec dbms_lock.sleep(120)---- Enregistrer la deuxième passe des statistiques pga--CREATE TABLE tab2 ASSELECT pid, category, name, heap_name, bytes, allocation_count, heap_descriptor, parent_heap_descriptorFROM v$process_memory_detailWHERE pid =&p_1AND category ='Other'; ---- Démarrer les rapports finaux---- Informations sur le tas PGA--Catégorie de COLONNE HEADING "Catégorie" Nom de la COLONNE HEADING "Nom" COLONNE heap_name HEADING "Nom du tas" COLONNE q1 HEADING "Mémoire 1ère" Format 999 999 999 999 COLONNE q2 HEADING "Mémoire 2e "Format 999,999,999,9 99COLUMN diff HEADING "Différence" Format S999,999,999,999SET LIGNES 150SELECT tab2.pid, tab2.category, tab2.name, tab2.heap_name, tab1.bytes q1, tab2.bytes q2, tab2.bytes-tab1.bytes diffFROM tab1, tab2WHERE tab1.category =tab2.categoryAND tab1.name =tab2.nameAND tab1.heap_name =tab2.heap_nameand tab1.pid =tab2.pidAND tab1.bytes <> tab2.bytesORDER BY 1, 7 DESC;---- Logminer PGA info- -COLUMN heap_name HEADING "nom du tas"COLUMN name HEADING "Type"COLUMN allocation_count HEADING "Count"COLUMN bytes HEADING "Sum"COLUMN avg HEADING "Average" FORMAT 99999D99SELECT pid, heap_name, name, allocation_count, bytes, bytes/allocation_count avgFROM tab2WHERE heap_name like 'Logminer%';spool offdrop table tab1 purge;drop table tab2 purge; Enregistrez ce code en tant que script et modifiez le texte pour remplacer les chaînes
par le compte d'utilisateur exécutant Log Miner. Le script cible spécifiquement la mémoire Logminer afin qu'elle puisse être surveillée pour les augmentations. Il peut également être modifié pour rechercher d'autres zones de mémoire problématiques. Commentez les commandes "drop table" pour conserver tab1 et tab2 pour des recherches ultérieures, si vous le souhaitez, car d'autres zones de mémoire peuvent être intéressantes. Vérifiez également le support Oracle pour les problèmes connus liés à PGA. Ces rapports contiendront probablement des requêtes à utiliser pour enquêter sur des problèmes spécifiques à l'aide de V$PROCESS_MEMORY_DETAIL. Pour plus de commodité, ces requêtes supplémentaires peuvent être ajoutées au code ci-dessus pour signaler toutes les zones suspectes de la mémoire de processus. Ces données seront déterminantes pour prouver la nécessité d'appliquer des correctifs ponctuels spécifiques à la base de données. Log Miner peut être un outil très utile pour enquêter sur les actions passées actuelles et relativement récentes dans la base de données. Il peut être nécessaire de surveiller les allocations PGA pendant que les sessions Log Miner sont actives afin qu'une action préventive telle que l'augmentation de la limite pga_aggregate_limit puisse être exécutée et que les sessions ne soient pas interrompues brusquement. "Un prévenu est un prévenu", comme le dit le dicton, et même si les administrateurs de base de données n'ont pas quatre bras, savoir ce qui pourrait arriver est toujours une connaissance qui vaut la peine d'être acquise.
Voir tous les articles de David Fitzjarrell