Statistique et Reorg

From Tuxunix
Jump to: navigation, search

Statistique

Runstat est le collecteur de statistique DB2, permettant d'optimiser les chemins d'accès, et de déterminer si le besoin de réorg est nécessaire sur des tables ou index.

Vérifier la date des dernières stats d'accès sur les tables

#> db2 "select TABNAME,STATS_TIME,CARD from syscat.tables"
TABNAME               STATS_TIME                                  CARD
---------------------------------------------------------------------------
SYSTABLES          2010-01-20-15.22.46.514272                612
SYSCOLUMNS         2010-01-19-20.37.46.607328                6831
...
  • Si "-" à la place d'une date, alors jamais de stat passé (normal si table système).
  • Le champ CARD donne le nombre d'enregistrement dans les tables.

Vérifier la date des dernières stats d'accès sur les indexes

#> db2 "select TABNAME,STATS_TIME,CARD,VOLATILE from syscat.tables"
TABNAME        STATS_TIME                  CARD            VOLATILE
------------------------------------------------------------------------
SYSTABLES    2010-01-20-15.22.46.514272    612
  • Volatile signifie si une table bouge beaucoup en d'autre terme, qu'elle à de nombreux mis à jour ou suppression d'enregistrement.


Les statistique peuvent être réaliser en automatique, pour vérifier taper la commande suivante :

#> db2 get db cfg for nomBase
 Automatic maintenance                      (AUTO_MAINT) = ON
  Automatic database backup            (AUTO_DB_BACKUP) = OFF
  Automatic table maintenance          (AUTO_TBL_MAINT) = ON
    Automatic runstats                  (AUTO_RUNSTATS) = ON
      Automatic statement statistics  (AUTO_STMT_STATS) = OFF
    Automatic statistics profiling    (AUTO_STATS_PROF) = OFF
      Automatic profile updates         (AUTO_PROF_UPD) = OFF
    Automatic reorganization               (AUTO_REORG) = OFF

Dans ce cas vos stats sont à jours. Il est possible de planifier une plage horaire pour l'exécution de runstats...

Définir une plage de maintenance pour la mise à jour des statistiques

Ceci peut ce faire soit par db2cc ou via un fichier XML à placer dans le répertoire tmp de l'instance (/home/nomInstance/sqllib/tmp).

  • Voici un exemple de fichier XML :
<OnlineWindow Occurrence="During" startTime="22:00:00" duration="2">
 <DaysOfWeek>All</DaysOfWeek>
 <DaysOfMonth>All</DaysOfMonth>
 <MonthsOfYear>All</MonthsOfYear>
</OnlineWindow>

A celui-ci vous pouvez ajouter des policy :

- comme par example exclure des tables :

<RunstatsTableScope>
 <FilterCondition>TABSCHEMA NOT LIKE 'EMP%' </FilterCondition>
</RunstatsTableScope>
  • Pour que DB2 le prenne en compte il faut appeler la procédure suivante :
db2 "call sysproc.automaint_set_policyfile('MAINTENANCE_WINDOW','DB2MaintenanceWindowPolicy.xml')"


Problème collecte statistique

#> db2 RUNSTATS ON TABLE "test"."XXXX" FOR SAMPLED DETAILED INDEX "test"."PK_test" ;
SQL2314W Some statistics are in an inconsistent state. The newly collected
"INDEX" statistics are inconsistent with the existing "TABLE" statistics.
SQLSTATE=01650
  • SQL2314W => Il faut mettre a jour les statistiques de la tables, comme ceci :
#> db2 RUNSTATS ON TABLE "test"."XXXX" AND INDEXES ALL

Ensuite vous pourrez relancer la 1er commande :)


Reorg

  • C'est quoi ca ???

Avec le temps, nous nous retrouvons souvent avec des tables fragmentées, des indexes se trouvant sur plusieurs pages mémoires, etc ce qui va provoqué une augmentation du nombre de pages lues pour trouver une donnée. La réorganisation permettra donc d’améliorer les performances mais également de limiter l’utilisation de place inutile.

2 modes :

Fonctionnement de la méthode OFFLINE :

Elle se base sur une copie totale de la table en la reconstruisant de manière organiser.

1. Classement des lignes de la table suivant un index si spécifié, sinon on peut faire un scan des indexes pour choisir lequel utiliser ou finalement un scan de la table complet pour décider de la réorganisation.

2. Reconstruction organiser de la table dans l’espace de tables ou dans l’espace temporaire.

3. Remplacement de l’ancienne table par la copie organisée.

4. Recréation des indexes.

Fonctionnement de la méthode ONLINE :

La réorganisation ne se fait pas en une fois mais par bloc en utilisant un espace temporaire.

1. Sélection d’un nombre N de pages.

2. Les pages sélectionnées sont déplacées dans l’espace temporaire et le processus attend que toutes les données ne soient plus accéder.

3. Les données sont réécrites de manière organisées dans la table.

4. Enfin la table est coupée afin de récupèrer l’ensemble de l’espace non utilisée.


Déterminer le besoin de reorg

Voici la commande qui vous permettra de récolter un tableau qui vous informera si le besoin de réorg est nécessaire sur des tables et/ou des indexes :

#> db2 reorgchk update (current) statistics;

Vue du tableau :

Doing RUNSTATS ....


Table statistics:

F1: 100 * OVERFLOW / CARD < 5
F2: 100 * (Effective Space Utilization of Data Pages) > 70
F3: 100 * (Required Pages / Total Pages) > 80

SCHEMA.NAME                     CARD     OV     NP     FP ACTBLK    TSIZE  F1  F2  F3 REORG
----------------------------------------------------------------------------------------
Table: XXX.Contact              184      0      1      1      -     6072   0   - 100 *--
Table: XXX.Personne              99      0      1      1      -     2475   0   - 100 ---
  • F1 = Si dépassement taille varchar, alors déplacement de l'enregistrement dans une nouvelle table (overflow), réorg obligatoire!
  • F2/F3 = Trou dans les tables
  • Si table à réorg les indexes de ca table sont automatiquement mis à jour, donc pas besoin de relancer une reorg sur les indexes!
Index statistics:

F4: CLUSTERRATIO or normalized CLUSTERFACTOR > 80
F5: 100 * (Space used on leaf pages / Space available on non-empty leaf pages) > MIN(50, (100 - PCTFREE))
F6: (100 - PCTFREE) * (Amount of space available in an index with one less level / Amount of space required for all keys) < 100
F7: 100 * (Number of pseudo-deleted RIDs / Total number of RIDs) < 20
F8: 100 * (Number of pseudo-empty leaf pages / Total number of leaf pages) < 20

SCHEMA.NAME INDCARD  LEAF ELEAF LVLS  NDEL KEYS ... LEAF_PAGE_OVERHEAD NLEAF_PAGE_OVERHEAD  F4  F5  F6  F7  F8 REORG
------------------------------------------------...---------------------------------------------------------------
Table: XXX.ADT003W 184 1  0  1   0  184     3       3               1444             1444 100   -   -   0   0 ***
...
  • F5 ou F7 alors reorg index uniquement.
  • F7 uniquement alors REORG CLEANUP ONLY
  • F8 uniquement alors REORG cleanup PAGE

Dans la colonne REORG plus il y a d'"*", plus le besoin de reorg est grand.

  • Voici un script automatique qui génère les commandes DB2 en fonction du besoin de REORG pour les Tables/Indexes
#!/bin/ksh
case "$1" in
-online)  TALLOW="INPLACE ALLOW WRITE ACCESS"
          IALLOW="ALLOW WRITE ACCESS";;
-offline) TALLOW="ALLOW READ ACCESS LONGLOBDATA"
          IALLOW="ALLOW WRITE ACCESS";;
*)        echo "Usage is : $0 -online|-offline"
          exit 1
          ;;
esac
tmpdir="/tmp/reorg_$$";mkdir -p $tmpdir;cd $tmpdir;rm -f *.out
db2 +o connect to nomBdd
db2 reorgchk current statistics on table all | awk '
    /^Table:/{tab=$NF;idx="";outfile=sprintf("%s.out",tab);next}
    /^Index:/{idx=$NF;next}
    $NF ~/\*/ && length($NF)==3 {printf("%s|0|%s\n",tab,$NF)        >outfile}
    $NF ~/\*/ && length($NF)==5 {printf("%s|1|%s|%s\n",tab,$NF,idx) >outfile}
'
db2 +o terminate
ls *.out | while read x
do
   sort $x | awk -F '|' -v TOPT="$TALLOW" -v IOPT="$IALLOW" '
   function getMax(val1,val2){ if (val1 > val2){return val1}else{return val2} }
   BEGIN { reorgtab=0;reorgidx=0 }
   $2==0 { reorgtab=1;tab=$1;next }
   $2==1 { tab=$1
           if(reorgtab!=1){
             F5=substr($3,2,1)
             F6=substr($3,3,1)
             F7=substr($3,4,1)
             F8=substr($3,5,1)
             if ( F5 == "*" || F6 == "*" ){reorgidx=3;next}
             if ( F7 == "*" )             {reorgidx=getMax(reorgidx,2);next}
             if ( F8 == "*" )             {reorgidx=getMax(reorgidx,1);next}
           }
         }
   END   { if(reorgtab==1){
             if(tab!="WAS.PIWCAN" && tab!="WAS.PIWPJ" && tab!="WAS.PIWQST" && tab!="WAS.PIWLEA_XML_SAVE"){
                gsub(/LONGLOBDATA/,"",TOPT)
             }
             printf("REORG TABLE %s %s\n",tab,TOPT)}
           else {
             if(reorgidx==1){printf("REORG INDEXES ALL FOR TABLE %s %s CLEANUP ONLY PAGES\n",tab,IOPT)}
             if(reorgidx==2){printf("REORG INDEXES ALL FOR TABLE %s %s CLEANUP ONLY ALL\n",tab,IOPT)}
             if(reorgidx==3){printf("REORG INDEXES ALL FOR TABLE %s %s\n",tab,IOPT)}
           }
         }
'
  rm -f $x
done
cd ..; rmdir $tmpdir

Commande de reorg

  • Reorg des indexes :
#> db2 reorg indexes all for table xxxx allow write access cleanup only pages
  • Reorg des tables :
#> db2 reorg table all for table xxxxx

Vérifier l'état des REORG

#> db2 list history reorg since 20101103 for database nomBase
  • Ou via la commande db2top et choisir la vue sur les "Tables"
#>db2top -d nomBdd

Vous retrouver une colonne nommé "Reorg% Progress", affichant le poucentage de reorg réalisé pour chaque table.

  • ou avec db2pd
#> db2pd -db nomBdd -reorg
  • Avec vue sur les indexes :
#> db2pd -db nomBdd -reorg index