Blog

Blog

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).