Allô « Health Monitor » ? Ma base de données est fatiguée !

Une base de données, tout comme les DBA(s) chargés de son administration, peut parfois montrer quelques signes de « faiblesse ».
Plusieurs solutions s’offrent alors afin d’identifier les « maux » responsables, dans l’optique qu’elle retrouve toute sa santé:
Un centre médical spécialisé, peut par exemple être sollicité.
« Health Monitor » est un environnement inclus par le serveur de base de données « Oracle », depuis sa version « 11G ».
Il permet de mener des diagnostics sur différents composants (Fichiers, Mémoire, Transactions, Métadonnées, « ASM », « Dataguard », etc..) et de générer des rapports et des recommandations sur les résultats obtenus.
Aujourd’hui, nous allons entrevoir les possibilités de « Health Monitor », afin de comprendre comment utiliser les différents types de vérifications possibles et surtout, comment générer et exploiter les rapports de diagnostiques et conseils obtenus.
La base de données sur laquelle s’appuieront les différentes démonstrations est une « CDB » (Container Database) en version 12.1.0.2.0 Enterprise Edition
 
Quelles sont les vérifications possibles?
L’interrogation de la vue « v$HM_CHECK » va nous permettre de faire connaissance avec l’ensemble des vérifications qu’il est possible de réaliser base ouverte et base fermée.
Avec « Oracle 12c », 34 vérifications sont disponibles (une vingtaine de vérifications étaient possibles avec « Oracle 11G »).
Certaines d’entre-elles n’étant utiles que dans des contextes bien particuliers (« Dataguard » – Stockage géré via « ASM » – etc..).

SQL> select name, offline_capable from v$hm_check;
NAME								O
--------------------------------------------------------------- -
HM Test Check							Y
DB Structure Integrity Check					Y
CF Block Integrity Check					Y
Data Block Integrity Check					Y
Redo Integrity Check						Y
Logical Block Check						N
Transaction Integrity Check					N
Undo Segment Integrity Check					N
No Mount CF Check						Y
Mount CF Check					                Y
CF Member Check 						Y
NAME								O
---------------------------------------------------------------- -
All Datafiles Check						Y
Single Datafile Check						Y
Tablespace Check Check				            	Y
Log Group Check 						Y
Log Group Member Check					        Y
Archived Log Check						Y
Redo Revalidation Check 					Y
IO Revalidation Check						Y
Block IO Revalidation Check					Y
Failover Check							Y
Txn Revalidation Check						N
NAME								 O
---------------------------------------------------------------- -
Failure Simulation Check					Y
Dictionary Integrity Check					N
ASM Mount Check 						Y
ASM Allocation Check						Y
ASM Disk Visibility Check					Y
ASM File Busy Check						Y
ASM Toomanyoff Check					        Y
ASM Insufficient Disks Check					Y
ASM Insufficient Mem Check					Y
ASM DGFDM Check No DG Name				        Y
ASM DG Force Dismount Check				        Y
NAME								O
---------------------------------------------------------------- -
ASM Sync IO Fail Check					        Y

 
La colonne « offline_capable » de la vue « v$HM_CHECK » nous indique si oui ou non, la vérification doit être effectuée base ouverte.
Bien que les intitulés de la majorité des vérifications soient relativement clairs, il existe une colonne nommée « description » dans la vue « v$HM_CHECK ».
Celle-ci va nous permettre, pour chacune des vérifications possibles, d’être certain de son objectif.
Prenons l’exemple de la vérification nommée « ASM Insufficient Disks Check ». Quel est son objectif?

SQL> select description from v$hm_check where name='ASM Insufficient Disks Check';
DESCRIPTION
---------------------------------------------------------------------------
Diagnose mount failed because there were insufficient disks

A quoi peut bien correspondre la vérification nommée « Failover Check »?

SQL> select description from v$hm_check where name='Failover Check';
DESCRIPTION
---------------------------------------------------------------------------
Check if failover has happened

Et au sujet de « All Datafiles Check », qu’en est-il?

SQL> select description from v$hm_check where name ='All Datafiles Check';
DESCRIPTION
---------------------------------------------------------------------------
Checks all datafiles in the database

Je vous invite à vous familiariser avec les nombreuses vérifications disponibles. Les connaitre peut parfois faire gagner un temps précieux, lors d’investigations à mener au sujet d’incidents en « Production ».
 
– Comment exécuter manuellement une vérification particulière?
Tout d’abord, il faut savoir que seules les vérifications non internes (« select internal_check from v$hm_check where name=<Ma_Vérification> » doit être égal à « N ») peuvent être effectuées manuellement.
Dans le cas où vous tenteriez d’exécuter manuellement une vérification dite interne, l’erreur suivante serait d’actualité:

ERROR at line 1:
ORA-51001: check [All
Datafiles Check] not found in
HM catalog
ORA-06512: at "SYS.DBMS_HM",
line 191
ORA-06512: at line 1

Afin d’exécuter manuellement une des vérifications disponibles, nous allons utiliser la procédure nommée « RUN_CHECK », disponible dans le package nommé « DBMS_HM ».
Nous allons illustrer cela, en exécutant la vérification nommée « Dictionary Integrity Check », précédemment mentionnée.
Pour exécuter « DBMS_HM.RUN_CHECK », il suffit de saisir la vérification souhaitée et référencée dans la vue v$HM_CHECK, un nom à associer à l’exécution (celui-ci permettra de récupérer le rapport ultérieurement), ainsi que les différents paramètres d’entrée contrôlant l’exécution.
1. Quels sont les paramètres nécessaires à l’exécution de la vérification nommée « Dictionary Integrity Check » ?
Pour le savoir, il suffit d’utiliser la vue « V$HM_CHECK_PARAM »:

SQL> select distinct name, description from v$hm_check_param where check_id=(select id from v$hm_check where name='Dictionary Integrity Check');
NAME
------------------------------
DESCRIPTION
------------------------------
CHECK_MASK
Check mask
TABLE_NAME
Table name

Deux paramètres d’entrée sont attendus ici. Quelles sont leurs valeurs par défaut?

SQL> select distinct default_value from v$hm_check_param where name='CHECK_MASK';
DEFAULT_VALUE
------------------------------
ALL
SQL> select distinct default_value from v$hm_check_param where name='TABLE_NAME';
DEFAULT_VALUE
------------------------------
ALL_CORE_TABLES

2.Exécutons désormais notre vérification:
Nous décidons d’exécuter notre vérification, sans indiquer aucun des deux paramètres d’entrée. De ce fait, la vérification de l’intégrité du dictionnaire portera donc sur l’ensemble des tables, et sera exhaustive.

SQL> exec dbms_hm.run_check('Dictionary Integrity Check','DicoIntegrityCheck');
PL/SQL procedure successfully completed.

Dans la suite de cet article, nous allons voir comment visualiser les résultats de notre vérification,  en utilisant « ADRCI ».
Avant cela, prenons un peu d’avance en générant le rapport (au format « XML ») de notre vérification et ce, en utilisant la fonction « get_run_report » du package « DBMS_HM »:

SQL> select dbms_hm.get_run_report('DicoIntegrityCheck') from dual;

 
– Visualiser les rapports obtenus via « ADRCI 
1. Invoquons « ADRCI » et plaçons-nous dans le « ADR Homes » relatif à la base de données dans laquelle nous avons contrôlé l’intégrité du dictionnaire:
 

[oracle@localhost oracle]$ adrci
ADRCI: Release 12.1.0.2.0 - Production on Sun Jul 12 12:18:35 2015
Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.
ADR base = "/home/oracle/app/oracle"
adrci> show homes
ADR Homes:
diag/rdbms/cdb1/cdb1
diag/clients/user_oracle/host_61728193_82
diag/diagtool/user_oracle/adrci_61728193_82
diag/tnslsnr/localhost/listener
adrci> set homepath diag/rdbms/cdb1/cdb1
adrci> show homes
ADR Homes:
diag/rdbms/cdb1/cdb1
adrci>

2.Répertorions désormais toutes les exécutions du vérificateurs enregistrées dans le référentiel « ADR » et visibles depuis la vue « v$HM_RUN »:
Pour cela, il suffit d’utiliser la commande « hm_run »:

adrci> show hm_run;
ADR Home = /home/oracle/app/oracle/diag/rdbms/cdb1/cdb1:
**********************************************************
HM RUN RECORD 1
**********************************************************
   		RUN_ID                        1341
   		RUN_NAME                      DicoIntegrityCheck
   		CHECK_NAME                    Dictionary Integrity Check
   		NAME_ID                       24
   		MODE                          0
   		START_TIME                    2015-07-12 11:53:55.003922 -07:00
   		RESUME_TIME                   <NULL>
   		END_TIME                      2015-07-12 11:55:08.336681 -07:00
   		MODIFIED_TIME                 2015-07-12 12:03:09.242624 -07:00
   		TIMEOUT                       0
   		FLAGS                         0
   		STATUS                        5
   		SRC_INCIDENT_ID               0
   		NUM_INCIDENTS                 0
   		ERR_NUMBER                    0
REPORT_FILE                   /home/oracle/app/oracle/diag/rdbms/cdb1/cdb1/hm/HMREPORT_DicoIntegrityCheck.hm
1 rows fetched

3. Visualisons désormais le rapport qui nous intéresse (« RUN_NAME = DicoIntegrityCheck »):
Pour cela, il suffit d’utiliser la commande « show report hm_run < RUN_NAME> » :

adrci> show report hm_run DicoIntegrityCheck
(….)
<FINDING>
           		 <FINDING_NAME>Dictionary Inconsistency</FINDING_NAME>
            		<FINDING_ID>4345</FINDING_ID>
            		<FINDING_TYPE>FAILURE</FINDING_TYPE>
            		<FINDING_STATUS>OPEN</FINDING_STATUS>
            		<FINDING_PRIORITY>CRITICAL</FINDING_PRIORITY>
           		 <FINDING_CHILD_COUNT>0</FINDING_CHILD_COUNT>
           		 <FINDING_CREATION_TIME>2015-07-12 11:54:55.591654 -07:00</FINDING_CREATION_TIME>
<FINDING_MESSAGE>SQL dictionary health check: foreign key file# not found in file$ 3 on object TAB$ failed</FINDING_MESSAGE>
<FINDING_MESSAGE>Damaged rowid is AAAAACAABAAAIK4AAE - description: Object SYS.BIN$AR2gEsi8MM3gVQAAAAAAAQ==$0 is referenced</FINDING_MESSAGE>
</FINDING>
        (….)

 
Nous avons donc entrevus les possibilités de « Health Monitor ».
Ce « centre médical » pourra, dans bien des cas, émettre des résultats de diagnostiques qui devraient garantir une pleine santé à vos bases de données.
Grâce à cela, nous DBA(s), devrions être assez sereins pour être dans le même cas 😉 …