Blog

Blog

Statspack ou l'ancêtre d'AWR

Hé oui, statspack a été remplacé par AWR (Automatic Workload Repository), mais cette fonctionnalité fait partie du diagnostic pack qui est une option même pour la version Enterprise. (Il faut d'ailleurs faire un peu attention, car cette fonctionnalité est installée même si elle n'a pas été payée...)
Pour ne pas payer ou risquer d'être en infraction, il reste le statspack. je n'ai aps trouvé de vraie doc sur ce statspck en 11g, mais sachez que la doc 9i est toujours d'actualité.

Installer Statspack

Hé oui, contrairement à AWR, il faut l'installer avant de l'utiliser. Autant vous dire que vous ne pourrez jamais sortir un rapport sur ce qu'il s'est passé hier sur la base de production...
Pour installer statspack, il suffit de lancer le script spcreate.sql qui se trouve sous $ORACLE_HOME/rdbms/admin.
sqlplus / as sysdba @?/rdbms/admin/spcreate
Le script devrait vous demander certaines informations comme le mot de passe du user perfstat, le tablespace d'espace temporaire et le tablespace par défaut du user perfstat.

Et c'est tout!

Faire un snapshot

Pour faire un snapshot, il suffit de lancer le script suivant (après s'être connecté avec le user perfstat) :
EXECUTE statspack.snap;

Faire un rapport

Pour faire un rapport, il faut lancer le script suivant (toujours connecté avec le user perfstat) :
@?/rdbms/admin/spreport
Ensuite, on peut analyser plus avant un ordre SQL en fournissant le hash value de la requête SQL au script suivant
@?/rdbms/admin/sprepsql

Programmer des snapshots réguliers

Comme on ne prévient pas quand on va en avoir besoin, il vaut mieux passer régulièrement des snapshots. Pour ça, on peut soit créer un script qui génère les snapshots et le lancer via un scheduler quelconque, soit utiliser Oracle pour les lancer. je préfère utiliser Oracle :-). En 9i, on utilisera DBMS_JOB, à partir de la 10g, on préfèrera DBMS_SCHEDULER.

Modifier les fenêtres de gather stat job en 11g

Je m'occupe d'une certaine plateforme de vote électronique. Comme chacun sait, un vote électronique est disponible H24 7j/7. Il a donc fallu que je me penche sur le recalcul automatique des stats Oracle pour m'assurer qu'ils n'allaient pas intervenir à un moment important du scrutin.

Oracle autotasks

En 11g, les tâches de maintenance Oracle sont lancées dans un scheduler. Ces tâches sont nommées "autotask" (le terme est important car sans lui, il est difficile de s'y retrouver dans la doc Oracle). Ces jobs de maintenance se lancent suivant des fenêtres de maintenance.

Gather stats

Le gather_stats_jobs d'Oracle 10g a été remplacé par une "tâche" que vous pouvez retrouver dans la vue dba_autotask_client. Pour savoir quand il se lance, il vous reste la requête suivante :
SELECT client_name, window_group
FROM dba_autotask_client
WHERE client_name='auto optimizer stats collection';
Vous récupérez donc un "window_group" (normalement, ça devrait s'appeler ORA$AT_WGRP_OS), vous pouvez requéter la table dba_scheduler_window_groups mais elle ne vous apprendra pas grand chose sur les heures de lancement de votre job En fait un "groupe de fenêtres" comporte différentes fenêtres (sic!). Bref, il faut requêter chaque fene^tre ensuite pour savoir quand votre job va se lancer :
SELECT window_group_name, window_name
FROM dba_scheduler_wingroup_members
WHERE window_group_name='ORA$AT_WGRP_OS';
Et voilà votre liste de fenêtres :

WINDOW_GROUP_NAME WINDOW_NAME
------------------------------ ------------------------------
ORA$AT_WGRP_OS MONDAY_WINDOW
ORA$AT_WGRP_OS TUESDAY_WINDOW
ORA$AT_WGRP_OS WEDNESDAY_WINDOW
ORA$AT_WGRP_OS THURSDAY_WINDOW
ORA$AT_WGRP_OS FRIDAY_WINDOW
ORA$AT_WGRP_OS SATURDAY_WINDOW
ORA$AT_WGRP_OS SUNDAY_WINDOW

Visualisation de mes fenêtres

A ce moment-là, vous devrez avoir une petite idée de quelle fenêtre vous voulez modifier. Si vous avez un doute, vous pouvez toujours demander le détail en requêtant dba_scheduler_windows :
SELECT window_name, repeat_interval, duration
FROM dba_scheduler_windows 
WHERE window_name IN ('SATURDAY_WINDOW','SUNDAY_WINDOW');

WINDOW_NAME
------------------------------
REPEAT_INTERVAL
--------------------------------------------------------------------------------
DURATION
---------------------------------------------------------------------------
SATURDAY_WINDOW
freq=daily;byday=SAT;byhour=6;byminute=0; bysecond=0
+000 20:00:00

SUNDAY_WINDOW
freq=daily;byday=SUN;byhour=6;byminute=0; bysecond=0
+000 20:00:00
On voit donc que la maintenance se lance à 6h00 et dure 20h00 les week-ends. Je vais donc pouvoir modifier mes fenêtres du samedi et du dimanche pour que la fenêtre de maintenance commence à 22h00 et dure 4h00. (C'est par défaut le comportant des jours ouvrés.)

Modification de mes fenêtres

Je fais donc ceci (et la même chose pour SUNDAY) :
BEGIN
  dbms_scheduler.disable(
    name  => 'SATURDAY_WINDOW');
  dbms_scheduler.set_attribute(
    name      => 'SATURDAY_WINDOW',
    attribute => 'DURATION',
    value     => numtodsinterval(4, 'hour'));
  dbms_scheduler.set_attribute(
    name      => 'SATURDAY_WINDOW',
    attribute => 'REPEAT_INTERVAL',
    value     => 'freq=daily;byday=SAT;byhour=22;byminute=0; bysecond=0');
  dbms_scheduler.enable(
    name => 'SATURDAY_WINDOW');
END;
/
Et voilà!

Pour aller un peu plus loin avec les stats

Il faut savoir que ce n'est pas parce que ces fenêtres de maintenance sont correctement settées que les statistiques seront forcément recalculées. En effet, Oracle est intelligent et ne recalcule les stats sur une table que s'il considère que c'est nécessaire (plus de 20% de modification sur la table par défaut).

Duplicate : RMAN-06217 et RMAN-04006

Vous avez une nouvelle machine qui doit héberger une standby et vous voulez qu'rman s'en occupe tout seul comme il sait si bien le faire. Vous avez donc créé un pfile minimal et avez démarré l'instance. la base est en nomount. (Ben oui, elle peut pas aller plus loin, y a pas de control file.) Les fichiers tnsnames et de mots de passe sont OK. Le listener tourne, bref tout marche, sauf que non!

Arrivée de la RMAN-06217

Vous tentez donc une connexion rman comme ça : (Dans mes exemples la primaire s'appelle rachel et la standby trenton)
rman target sys/xxx@rachel auxiliary /
et ça semble marcher :
Recovery Manager: Release 11.2.0.1.0 - Production on Mon Oct 3 10:25:57 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
connected to target database: RACHEL (DBID=YYY)
connected to auxiliary database: TRENTON (not mounted)
RMAN
puis, bous lancez votre duplicate et arrive l'erreur fatidique (sans avoir été invitée):

run 
{
allocate auxiliary channel t1 type disk;
allocate channel t2 type disk;
duplicate target database for standby from active database password file spfile;
}

using target database control file instead of recovery catalog
allocated channel: t1
channel t1: SID=95 device type=DISK

allocated channel: t2
channel t2: SID=13 device type=DISK

Starting Duplicate Db at 03-OCT-11
released channel: t1
released channel: t2
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 10/03/2011 10:26:15
RMAN-06217: not connected to auxiliary database with a net service name

Arrivée de la RMAN-04006

Vous remplissez donc consciencieusement votre tnsnames.ora. Vous faites même un petit tnsping pour être sûr :
tnsping trenton

TNS Ping Utility for Linux: Version 11.2.0.1.0 - Production on 03-OCT-2011 10:36:03

Copyright (c) 1997, 2009, Oracle.  All rights reserved.

Used parameter files:
/admin/oracle/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = yyy)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = TRENTON)))
OK (0 msec)
Fiers de vous, vous lancez donc la commande qui doit marcher :
rman target sys/xxx@rachel auxiliary sys/xxx@trenton

Recovery Manager: Release 11.2.0.1.0 - Production on Mon Oct 3 10:27:25 2011

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

connected to target database: RACHEL (DBID=YYY)
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-00554: initialization of internal recovery manager package failed
RMAN-04006: error from auxiliary database: ORA-12528: TNS:listener: all appropriate instances are blocking new connections
Et le pire, c'est que c'est logique! La BDD secondaire n'a pas pu s'enregistrer auprès du listener (ben oui, elle est toujours à l'état nomount), on ne peut donc pas se connecter en utilisant un service name!

La solution

D'après la note metalink Connection to Auxilary using connect string failed with ORA-12528 (Doc ID 419440.1) (Attention, authentification nécessaire), il faut modifier le tnsnames comme ça :

TRENTON =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = yyy)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = TRENTON)
      (UR=A)
    )
  )