Aucun message portant le libellé EVENT. Afficher tous les messages
Aucun message portant le libellé EVENT. Afficher tous les messages

mercredi 22 septembre 2010

OOW 2010 - Jour 3

Trop souvent les entreprises négligent complètement la prise de copie de sécurité et, ceux qui en prennent, négligent les essais de recouvrement. Pourquoi les gens aiment tant jouer avec le risque ? Personnellement, ça me renverse! Jamais je ne pourrais avoir la conscience tranquille tant et aussi longtemps que je n'aurais pas effectué des copies de sécurité et réaliser des scénarios de recouvrement. Ceci devrait être la ou l'une des premières règles qu'un DBA devrait suivre. D'autant plus, pouvez-vous bien me dire pourquoi qu'il y a tant d'entreprises qui n'utilisent pas RMAN ? Cet utilitaire a fait ses preuves depuis plusieurs années et aucun autre utilitaire ne peut être aussi fiable que lui.

Je vous parle de sauvegarde et de recouvrement car aujourd'hui, j'ai eu l'opportunité d'assister à des conférences au sujet de " Recovery Manager ". Le premier conférencier nous à présenter une multitude de scénarios de recouvrement. Certains dont je classifierais de classique et d'autres plutôt tordus qui ne sont pas supporté par Oracle. Ces derniers sont plutôt pratiques quand nous n'avons vraiment pas le choix et qu'il faut ressusciter une base de données. Voici ce qui peut être utile pour effectuer un recouvrement incomplet et forcer l'ouverture de la base de données :
  • _ALLOW_RESETLOGS_CORRUPTION=TRUE
  • _CORRUPTED_ROLLBACK_SEGMENTS=(RBS1,RBS2,..)
  • UNDO_MANAGEMENT=MANUAL
  • EVENT = "10015 TRACE NAME ADJUST_SCN LEVEL 1"

Quand il n'y a vraiment plus de possibilité alors vous pouvez vous en remettre au support d'Oracle puis utiliser " Data Unloader (DUL) ". Cet utilitaire permet de lire les données directement dans les fichiers de données sans passer par le noyau d'Oracle.

Autres points d'intérêt abordés lors des conférences :

  • Il est possible de recréer un fichier de paramètre (pfile) à partir de la mémoire. Il suffit d'exécuter la commande " CREATE PFILE " et spécifier à la toute fin " FROM MEMORY ".
  • DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER() retourne le SCN en cours de la base de données.
  • Il est possible de restaurer un fichier de données lors de la perte de celui-ci et que vous n'avez pas de sauvegarde de ce fichier. Si le fichier de données est inscrit dans le fichier de contrôle, la commande RESTORE créée le fichier de données dans l'emplacement d'origine et la commande RECOVER applique les journaux nécessaires pour le fichier de données.
  • Si vous soupçonnez une corruption de blocs de données, DBVERIFY est un utilitaire qui effectue une vérification de l'intégrité de la structure des données physiques sur une base de données.
  • La commande BLOCKRECOVER peut restaurer et récupérer des blocs individuels au sein d'un fichier de données. Cette procédure est utile quand seulement un petit nombre de blocs sont corrompus.
  • Le package DBMS_BACKUP_RESTORE est utilisé comme une interface PL/SQL en ligne de commande pour le remplacement des commandes natives RMAN.

Oracle ORION

Oracle ORION est un outil pour vérifier les performances de type I/O pour les systèmes de stockage qui sont destinés à être utilisés pour les bases de données Oracle. Les résultats obtenus sont utiles pour comprendre les capacités de performance d'un système de stockage, soit pour découvrir les causes qui pourraient influer sur le rendement d'une base de données Oracle. ORION est un outil autonome, on n'a pas à créer et d'exécuter une base de données Oracle pour l'utiliser.


Pour le plaisirs, je vous invite à regarder les vidéos suivants sur youtube.com :

mardi 15 juin 2010

Enlever un énoncé SQL de la cache (SHARED POOL)

Voici un script que j'utilise pour supprimer une requête (énoncé SQL) de la cache partagée nommé "shared pool". Ce script est fort utile lorsque vous effectuez du "tuning" de requête.

REM *******************************************************************
REM * Script: FlushSQL.sql
REM * Titre : Chercher et générer la commande pour enlever un énoncé
REM * SQL du SHARED POOL
REM * Auteur: Eric Cloutier
REM * Date modif. : 15-06-2010
REM * Parametres :
REM * Aucun
REM *******************************************************************
set pagesize 9999 feed off linesize 200 trimspoo on verify off
--
-- Sous 10g (10.2.0.4) :
-- Alter session set events '5614566 trace name context forever';
--
spool FlushSQL.log

Accept sql_text prompt 'Inscrire une partie de la requête (LIKE est utilisé alors inscrire %): '

col cmd_sql format a80
col username format a20
col executions format 999999
col sql_text format a30 wrap

select 'exec sys.dbms_shared_pool.purge('''||address||','||hash_value||''',''C'',1);' cmd_sql,
sql_id, child_number, executions, u.username, sql_text
from v$sql s, dba_users u
where upper(sql_text) like upper(nvl('&sql_text',sql_text))
and sql_text not like '%from v$sql where sql_text like nvl(%'
and u.user_id = s.parsing_user_id
/

spool off
set feed on linesize 5000
Prompt
Prompt -- Résultat dans le fichier : FlushSQL.log
Prompt

Cette fonctionnalité peut être utilisé en 10g (10.2.0.4) cependant, vous devez initialiser un "event" soit à la session ou au niveau de la base de données que qu'elle fonctionne.

Un merci particulier à Kerry Osborne pour son blog.

mercredi 24 mars 2010

Comportement des statistiques systèmes en mode RAC

Lors de la collecte des statistiques systèmes d'un environnement RAC, on peut déclencher la collecte à partir de n'importe quelle instance. Tout s'effectue correctement... À vrai dire, pas exactement car les autres instances attachées au cluster ne prennent pas en compte les nouvelles valeurs.

Je me suis aperçu de ce problème quand une requête est devenue gourmande. Le plan d'exécution de la requête était complètement différent sur 2 instances. En me connectant sur l'une des instances du cluster, j'ai vérifié les valeurs des statistiques (select * from sys.aux_stats$). C'est à ce moment que j'ai remarqué qu'elles avaient été régénérées récemment et l'un de mes collègues me l'a confirmé. J'ai aussi eu la confirmation que la lenteur avait été observée depuis la date de la régénération des statistiques. Donc, je pouvais déduire que la collecte de statistiques systèmes était l'élément déclencheur.

Que se soit sur l'une ou l'autre des instances du cluster, les mêmes statistiques sont supposées être utilisées dont je suspecte que le problème soit au niveau de la mémoire ou d'une certaine cache. J'ai tenté une simple purge du "shared pool" et celle des données mais sans succès. Comme à l'habitude, j'ai fait une petite recherche sur Metalink et effectivement, il y a un problème de répertorier sur la base de données 10.2.0.3. (ID 7645777.8) concernant un plan d'exécution différent sur des instances RAC. La solution : Recycle the instances... Qu'est-ce que cela veut dire exactement ?!? J'imagine que c'est l'équivalent d'un redémarrage d'instance et, si c'est le cas, et bien, je ne peux pas me le permettre. Vu que ce bug concerne les statistiques systèmes alors, j'ai décidé de pousser la vérification en influençant l'optimisateur pour qu'il n'utilise pas les statistiques liées au CPU. Pour ce faire, j'ai utilisé le hint "NO_CPU_COSTING". Les résultats furent concluants, j'ai obtenu le même plan d'exécution que sur l'instance où la requête est optimale.

Tant qu'à pousser, j'ai décidé d'effectuer une trace de l'optimisateur sur l'exécution de la requête sur chacune des instances avec la commande :

ALTER SESSION SET EVENTS '10053 trace name context forever, level 1'

Les 2 fichiers de trace ont démontrés que les statistiques systèmes sont différentes donc ça confirme que l'optimisateur n'utilise pas les mêmes valeurs d'une instance à l'autre... Inquiétant ?

Après réflexion, je me suis dit, pourquoi ne pas répéter ou presque les mêmes étapes de collecte de statistiques systèmes mais cette fois-ci, en étant connecté sur l'instance n'ayant pas le même comportement ou si vous préférez, le même plan d'exécution. Alors, j'ai effectué ceci :

-- Établir une connexion sur l'instance qui n'utilise pas les nouvelles valeurs
connect sys@inst1 as sysdba

-- Prendre une copie des statistiques actuelles
Drop table stats_bkp;
EXECUTE DBMS_STATS.CREATE_STAT_TABLE ('SYS','stats_bkp','SYSAUX');
EXECUTE DBMS_STATS.EXPORT_SYSTEM_STATS (stattab => 'stats_bkp', statid => 'stats_bkp', statown => 'SYS');
select * from sys.stats_bkp;

-- Charger les valeurs
execute DBMS_STATS.DELETE_SYSTEM_STATS;
EXECUTE DBMS_STATS.IMPORT_SYSTEM_STATS (stattab => 'stats_bkp', statid => 'stats_bkp', statown => 'SYS');
select * from sys.aux_stats$;


-- Initialiser les espaces mémoires
Alter system flush shared_pool;
Alter system flush buffer_cache;


Et bien oui, ça fonctionne! La requête a maintenant le même plan d'exécution que sur l'autre instance. Stop! Le problème s'est déplacé sur l'autre instance... oups! Ok, alors, je vais refaire la même chose, mais cette fois-ci sur l'instance où le problème s'est déplacé. Suite à l'exécution des commandes précédentes, le plan d'exécution est redevenu celui d'auparavant et, sans impacter le plan d'exécution sur l'autre instance.

Je crois qu'un redémarrage de l'instance aurait pu régler le problème sauf que lorsque nous sommes sur un environnement de production, cela n'est pas toujours une solution et ce, même si c'est un environnement RAC à moins que vous preniez le temps de déplacer tous les services vers une autre instance puis que vous patientez jusqu'à ce que toutes les sessions se soient reconnectés vers la nouvelle instance.

jeudi 19 février 2009

Attends ! Ben oui, je n'ai que ça à faire !

Voici un script que j’aime bien utilisé pour visualiser les événements d’attente propre à une session qui est en cours d’exécution :

REM ****************************************************
REM * Script: sess_wait.sql
REM * Titre : Afficher les wait events d'une session
-- ****************************************************
set pagesi 999 feed off linesi 500 trimspoo on veri off

col event format A40

-- ****************************************************
-- Afficher les sessions en cours
-- ****************************************************
select SID,
substr(username,1,15) username,
status,
substr(machine,1,20) machine,
program
from v$session
where username is not null
and status != 'KILLED'
order by program, username, status;

-- Choisir une session
Accept L_sid prompt 'Entrez le SID (Enter = Tous) : '

-- ****************************************************
-- Afficher les événements propres à la session choisie
-- ****************************************************
Select substr(event,1,30) event,total_waits,time_waited
from v$session_event
where sid=nvl('&L_sid',sid)
order by total_waits;

-- ****************************************************
-- Afficher l'événement d'attente actuel de la session
-- ****************************************************
Select *
from v$session_wait
where sid=nvl('&L_sid',sid);