Introduction
L’idée saugrenue de jouer avec les tables externes[1] m’est venue de la volonté de pouvoir corréler[2] les statistiques systèmes et les statistiques provenant d’Oracle.
Ce que je souhaitais obtenir avec ce système était l’accès complet à l’historique de sar au travers d’un langage de manipulation de données, le SQL. Enfin un script shell viendra compléter l’arsenal et rendra opérant ce système. Attention, ce script sera appelé à chaque accès de la table.
Pour des raisons de sécurité, je vous incite fortement à lire la documentation oracle sur les risques[3] liés à l’utilisation de la clause PREPROCESSOR
.
Ingrédients
- Une tasse de café
- Un siège
- Un système *nix où sar est actif
- Une base de données Oracle
- Les droits DBA
- Un copier/coller fonctionnel
Préparation
Pour que ce système ne soit pas trop intrusif, j’ai fait le choix de créer un utilisateur dédié: systat. La suppression n’en sera que plus aisée.
Le mot de passe ne sera probablement pas en accord avec votre politique de sécurité, corrigez l’assaisonnement à votre gout.
CREATE USER systat IDENTIFIED BY systat ACCOUNT LOCK;
Pour que mon petit bonhomme puisse faire quelque chose, je lui donne des droits, juste ce qu’il faut, sur des dossiers créés ci-dessous.
Le premier dossier hébergera le(s) script(s), le second, les fichiers de log.
CREATE DIRECTORY dbabin AS '/home/oracle/dba/bin'; CREATE DIRECTORY dbatmp AS '/home/oracle/dba/tmp';
Voici maintenant les droits spécifiques à chaque dossier.
GRANT READ, EXECUTE ON DIRECTORY dbabin TO systat; GRANT READ, WRITE ON DIRECTORY dbatmp TO systat;
Pour ne pas rendre indigeste cet article, je n’ai gardé que la table du load average.
Vous pourrez créer une table pour les autres métriques selon vos besoins, le principe reste le même.
CREATE TABLE systat.ldavg ( host varchar2(255), last_snap number, snap_time timestamp, runq_sz number, plist_sz number, ldavg_1 number(6,2), ldavg_5 number(6,2), ldavg_15 number(6,2) ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY dbabin ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE NOBADFILE NODISCARDFILE LOGFILE dbatmp:'loadavg.log' PREPROCESSOR dbabin:'loadavg' FIELDS TERMINATED BY ";" LRTRIM ( host, last_snap unsigned integer external (4), snap_time char date_format timestamp mask 'yyyy-mm-dd hh24:mi:ss', runq_sz unsigned integer external (4), plist_sz unsigned integer external (4), ldavg_1 decimal external, ldavg_5 decimal external, ldavg_15 decimal external ) ) LOCATION(dbabin:'loadavg') ) REJECT LIMIT UNLIMITED /
Et enfin, parce que je n’aime pas les choses compliquées, un synonyme est le bienvenu.
CREATE SYNONYM loadavg FOR systat.ldavg;
Voilà pour la partie SQL, il me reste à présenter le script shell /home/oracle/dba/bin/loadavg
#!/bin/env bash # MAIN { unalias -a declare -x PATH=/bin:/usr/bin test -d /var/log/sa && ls -tr /var/log/sa/sa?? | xargs -rI@ sadf -td @ -- -q | sed 's/,/\./g' }
Je positionne le bit d’exécution sur le script avec la commande chmod +x /home/oracle/dba/bin/loadavg
et maintenant je peux m’amuser avec mon nouveau jouet.
[1]: Managing External Tables
[2]: correlation does not imply causation
[3]: Guidelines for Securing the ORACLE_LOADER Access Driver