Oracle 8i - Généralités sur les Online Redo Log

Introduction

Cet article présente les généralités sur les online redo log d'Oracle avec un cas pratique dans lequel des groupes de fichiers de redo log sont supprimés, ajoutés, modifiés et « switchés » manuellement.

Les vues V$LOG, V$LOGFILE et V$LOGHIST relatifs aux fichiers de redo log sont également présentées.

Généralités sur les online redo log

Les online redo log sont cruciaux pour les opérations de recovery d'une base de données Oracle. Les online redo log consistent en deux ou plusieurs fichiers pré-alloués qui stockent tous les changements effectués dans la base de données. Chaque instance d'une base de données Oracle possède un fichier de redo log en ligne pour protéger la base de données en cas de crash.

Les threads dédiés au redo

Chaque instance d'une base de données possède ses groupes de redo log. Ces fichiers de redo log, multiplexés ou non, sont gérés par un seul thread dans une instance Oracle dans le cas où Oracle Parallel Server n'est pas mis en œuvre : le thread LGWR (Log Writer).

Le contenu des fichiers de redo log

Les fichiers online de redo log sont remplis avec des enregistrements de redo (redo records). Un enregistrement de redo est appelé aussi une entrée de redo (redo entry) et est composé d'un groupe de vecteurs de changement, chaque vecteur correspondant à la description d'un changement dans un bloc unique dans la base de données.

Les entrées de redo enregistrent tous les changements effectués dans la base de données, y compris les segments de rollback. Ainsi les online redo log protègent également les données de rollback.

Log writer et redo bloc

Les enregistrements de redo sont mis dans un buffer en mode circulaire dans le buffer redo log de la SGA d'une instance Oracle et sont écrits dans un des fichiers de redo log par le process en arrière plan LGWR (Oracle background process Log Writer). Dès lors q'une transaction est validée (commit), le process LGWR écrit les enregistrements de redo de la transaction du buffer de redo log dans la SGA vers un fichier de redo log, et un SCN (system change number) est attribué pour identifier les enregistrements de redo avec chaque transaction validée.

Ce n'est que lorsque tous les enregistrements de redo associés à une transaction donnée sont écrits sur disque dans les fichiers de redo log que le process utilisateur est notifiée que la transaction est validée.

Les enregistrements de redo peuvent être également écrits dans un fichier de redo log avant que la transaction correspondante ne soit validée. Si le buffer de redo log est complet, ou bien qu'une autre transaction est validée, le process LGWR flush toutes les entrées de redo log du buffer de redo log vers un fichier de redo log, même si des enregistrements de redo ne sont pas validées. Si nécessaire, Oracle peut annuler ces changements.

Écriture dans les fichiers de redo log

Les fichiers de redo log se composent au minimum de deux fichiers de redo log en ligne (online redo log). Oracle impose un minimum de deux fichiers pour garantir qu'un fichier de redo log soit toujours disponible en écriture alors que l'autre est en cours d'archivage (si le mode archivelog est actif).

Le process LGWR écrit dans les fichiers de redo log en mode circulaire : lorsque le fichier de redo log courant est rempli, LGWR commence à écrire dans le fichier de redo log suivant. Lorsque le dernier fichier de redo log est rempli, LGWR revient au premier fichier de redo log et écrit dans ce dernier, recommençant ainsi un nouveau cycle.

Mouvement circulaire des redo logs

Les fichiers de redo log remplis sont disponibles au process LGWR pour réutilisation en fonction du mode ARCHIVELOG actif ou non :

  • Si l'archivage n'est pas activé (mode NOARCHIVELOG), un fichier de redo log rempli est disponible une fois que les changements enregistrés dans ce dernier ont été écrits dans les fichiers de données.
  • Si l'archivage est actif (mode ARCHIVELOG), un fichier de redo log rempli est disponible au process LGWR une fois que les changements enregistrés dans ce dernier ont été écrits dans les fichiers de données et une fois que le fichier de redo log a été archivé.

Fichiers de redo log actif (courant) et inactif

Oracle n'utilise qu'un fichier de redo log à la fois pour écrire les enregistrements de redo à partir du buffer de redo log. Le fichier de redo log que le process LGWR remplit est appelé le fichier de redo log courant.

Les fichiers de redo log nécessaires au recovery sont appelés les fichiers de redo log actifs. Ceux qui ne sont pas nécessaires au recovery sont appelés les fichiers de redo log inactifs.

Si l'archivage est activé, Oracle ne peut réutiliser ou écraser un fichier de redo log actif tant que son contenu n'a pas été archivé intégralement.

Log switches et Log sequence Numbers

Un switch de log est le point pendant lequel Oracle termine l'écriture dans un fichier de redo log et bascule vers un autre fichier de redo log. Un switch de log se produit toujours lorsque le fichier de redo log est saturé et que les écritures doivent se poursuivre vers le prochain fichier de redo log. Les switches de log peuvent être également effectué manuellement.

Oracle affecte automatiquement un numéro de séquence de log (log sequence number) à un fichier de redo log chaque fois qu'un switch de log se produit. Si Oracle archive les fichiers de redo log, les fichiers de redo log archivés retiennent ce numéro de séquence. Durant un crash, un recovery, Oracle réapplique correctement les fichiers de redo log selon le numéro de séquence de log.

Multiplexage des fichiers de redo log

Lorsque du multiplexage est appliqué sur des fichiers de redo log, le process LGWR écrit la même information dans plusieurs fichiers de redo log identiques, permettant ainsi d'éliminer un crash de lecture sur un fichier de redo log endommagé.

Multiplexage redo logs

La mise en œuvre du multiplexage des fichiers de redo log consiste à créér des groupes de fichiers de redo log. Chaque fichier de redo log dans un groupe est appelé un membre. Les membres dans un groupe de fichiers de redo log doivent avoir la même taille.

Selon l'exemple donné sur le schéma, le process LGWR écrit simultanément dans les membres A_LOG1 et B_LOG1 du groupe Group1 de fichiers de redo log et ensuite dans les membres A_LOG2 et B_LOG2 du groupe Group2 de fichiers de redo log après un switch de log.

Il est recommandé de placer les membres d'un groupe de fichiers de redo log sur des disques différents.

Paramètres MAXLOGFILES, LOG_FILES et MAXLOGMEMBERS

Il est impératif de considérer les paramètres qui peuvent limiter le nombre de fichier de redo log online avant d'altérer la configuration des fichiers de redo log pour une instance.

  • le paramètre MAXLOGFILES utilisé dans la commande CREATE DATABASE détermine le nombre de groupes de fichiers de redo log. Le seul moyen de modifier cette limite impose de recréer la base de données ou d'altérer ses fichiers de contrôles. Si le paramètre MAXLOGFILES n'est pas spécifié, Oracle applique une valeur par défaut dépendant du système d'exploitation.
  • Le paramètre d'initialisation LOG_FILES (dans le fichier d'initialisation de l'instance) peut temporairement diminuer le nombre maximum de groupes de fichiers de redo log sans toutefois excéder le paramètre MAXLOGFILES.
  • Le paramètre MAXLOGMEMBERS utilisé dans la commande CREATE DATABASE détermine le nombre maximum de membres dans un groupe de fichiers de redo log. Comme le paramètre MAXLOGFILES, le seul moyen d'augmenter cette valeur nécessite de recréer la base de données ou bien d'altérer les fichiers de contrôles. Si le paramètre MAXLOGMEMBERS n'est pas spécifié, Oracle applique une valeur par défaut dépendant du système d'exploitation.

La vue v$controlfile_record_section permet de connaître le paramètre MAXLOGFILES :

SQL > select records_total from v$controlfile_record_section where type='REDO LOG'
records_total
-------------
32

Dans le contexte du cas pratique : 32 groupes de fichiers de redo log au maximum peuvent être créés.

Cas pratique

Dans le cas pratique qui suit, on se propose de voir les commandes principales Oracle de manipulation des fichiers de redo log pour réaliser une réorganisation des fichiers de redo log.

La commande initiale de création de la base de données du cas pratique est rappelée ci-dessous :

CREATE DATABASE CGC
  LOGFILE '/sdata/oracle/v8/TSTT1ORA/redolog/redo01.log' SIZE 1024K,
          '/sdata/oracle/v8/TSTT1ORA/redolog/redo02.log' SIZE 1024K,
          '/sdata/oracle/v8/TSTT1ORA/redolog/redo03.log' SIZE 1024K
  MAXLOGFILES 32
  MAXLOGMEMBERS 2
  MAXLOGHISTORY 1
  DATAFILE '/sdata/oracle/v8/TSTT1ORA/data/system01.dbf' SIZE 264M  REUSE AUTOEXTEND OFF
  MAXDATAFILES 254
  MAXINSTANCES 1
  CHARACTER SET WE8ISO8859P1
  NATIONAL CHARACTER SET WE8ISO8859P1;

La commande CREATE DATABASE nous impose de ne pas créer plus de 32 groupes de fichiers de redo log. Chaque groupe ne pourra pas contenir plus de 2 membres, soit 2 fichiers de redo log.

Lors de la création de la base de données CGC, 3 groupes de fichiers de redo log ont été créés, 3 groupes qui ne contiennent qu'un seul fichier de redo log. A l'issue de la reconstruction, il y aura toujours 3 groupes de fichiers de redo log, mais chaque groupe contiendra 2 fichiers de redo log comme le montre le schéma qui suit :

Cas pratique redo logs

Dans le contexte du cas pratique, les membres d'un même groupe ne peuvent être placés sur des disques différents.

Vues V$LOG et V$LOGFILE pour la collecte des informations

Les vues V$LOG et V$LOGFILE fournissent des informations sur les groupes de fichiers de redolog. Ces vues s'appuient sur les informations contenues dans les fichiers de contrôle.

Vue V$LOG

La vue V$LOG donne des informations précises sur les fichiers de redo log :

select group#,
       thread#,
       sequence#,
       bytes,
       members,
       archived,
       status,
       first_change#,
       to_char(first_time, 'dd/mm/yy hh:mi:ss') as FIRST_TIME
from v$log
group# thread# sequence#    bytes members arc status    first_change# first_time
------ ------- ---------  ------- ------- --- --------- ------------- ----------
1        1          1066  1048576       1 NO  CURRENT         292718  14/01/2005 12:03
2        1          1064  1048576       1 NO  INACTIVE        272227  30/12/2004 02:28
3        1          1065  1048576       1 NO  INACTIVE        272626 

La vue V$LOG indique bien qu'il a trois groupes de fichiers de redo log, trois groupes ne possédant qu'un seul membre ou fichier de redo log (members=1). Chaque fichier de redo log a une taille de 1 Mo.

Le fichier de redo log actif est le fichier du groupe 1 pour lequel le statut est CURRENT (colonne status).

Le numéro de séquence de log est 1066 (sequence#) pour le premier groupe de fichiers de redo log, 1064 pour le second groupe et 1065 pour le troisième groupe, ce qui est parfaitement logique compte tenu du caractère circulaire dans les fichiers de redo log.

La colonne first_change# indique le premier SCN (system change number) dans le groupe de fichiers de redo log et l'heure à laquelle correspond ce SCN est donnée par la colonne first_time.

Vue V$LOGFILE

La vue V$LOGFILE donne quant à elle les statuts et localisations physiques des membres des groupes de fichiers de redo log :

select * from v$logfile
group# status member
------ ------ --------------------------------------------
1             /SDATA/ORACLE/V8/TSTT1ORA/REDOLOG/REDO01.LOG
2             /SDATA/ORACLE/V8/TSTT1ORA/REDOLOG/REDO02.LOG
3      STALE  /SDATA/ORACLE/V8/TSTT1ORA/REDOLOG/REDO03.LOG

Le statut est INVALID lorsqu'un fichier de redo log dans un groupe ne peut être accédé.

Le statut est STALE lorsqu'Oracle suspecte qu'un fichier de redo log est incomplet ou incorrect jusqu'à ce que le fichier de redo log en question soit membre du groupe actif.

Forcer manuellement un switch de log

La commande alter system permet de switcher de groupe de fichiers de redo log :

alter system switch logfile;

La vue V$LOG confirme effectivement le switch de log à l'issue de la commande : le groupe actif de fichier de redo log devient le groupe 2 avec un numéro de séquence de log incrémenté de 1.

select * from v$log;
group# thread# sequence# bytes   members arc status     first_change#  first_time
------ ------- --------- ------- ------- --- ---------  -------------  ----------
1        1          1066 1048576 1       NO  INACTIVE          292718  14/01/2005 12:03
2        1          1067 1048576 1       NO  CURRENT           292768  14/01/2005 01:09
3        1          1065 1048576 1       NO  INACTIVE          272626  30/12/2004 04:21

Le fichier d'alert de l'instance confirme le switch manuel réalisé :

Thread 1 advanced to log sequence 1067
Current log# 2 seq# 1067 mem# 0: /SDATA/ORACLE/V8/TSTT1ORA/REDOLOG/REDO02.LOG.

Suppression d'un groupe de fichiers de redo log

Dans le contexte du cas pratique, le groupe 1 va être supprimé.

Avant la suppression d'un groupe de fichiers de redo log, quelques notions doivent être connues :

  • il est impératif de s'assurer qu'il existera au moins deux groupes de fichiers de redo log disponibles à l'issue de la suppression.
  • un message d'erreur apparaît si l'on tente de supprimer un membre d'un groupe actif de fichiers de redo log. Un switch de log doit être réalisé au préalable.
  • il est autorisé de ne supprimer qu'un membre d'un groupe de fichiers de redo log, à condition que ce membre ne soit pas unique et le dernier du groupe (le message ORA-00361 est sinon affiché : impossible de supprimer le dernier membre).
  • le fichier physique n'est pas suppprimé sur le disque.

Pour supprimer un groupe de fichiers de redo log :

alter database drop logfile group <group_number>;

Pour supprimer un membre d'un groupe de fichiers de redo log :

alter database drop logfile member '<path_to_filename>';

Dans le cas pratique : le groupe 1 n'est pas actif et ne possède qu'un seul membre donc seule la syntaxe ci-dessous pourra être utilisée.

alter database drop logfile group 1

La vue V$LOG confirme la suppression du groupe 1.

group# thread# sequence# bytes   members arc status     first_change#  first_time
------ ------- --------- ------- ------- --- ---------  -------------  ----------
2        1        1067   1048576        1 NO CURRENT          292768   14/01/2005 01:09
3        1        1065   1048576        1 NO INACTIVE         272626 

Création d'un groupe de fichiers de redo log

Le groupe 1 de fichiers de redo log va être recréé avec un 1 seul membre (redo1_01.log). La syntaxe alter database est utilisée pour ajouter un groupe de fichiers de redo log : le nombre de membres dans un groupe de fichiers de redo log ne pouvant pas dépasser le paramètre MAXLOGMEMBERS.

alter database add logfile [group <group_number>]
   ('<path_to_filename1>' [, '<path_to_filename2>' [,... )
   size 'size M|K';

La commande alter database add logfile autorise l'utilisateur à spécifier un numéro au groupe.

Dans le cas pratique :

alter database add logfile group 1 ('/sdata/oracle/v8/TSTT1ORA/redolog/redo1_01.log') size 1M

Le membre redo1_02.log du group 1 créé va être ajouté avec la commande alter database add logfile member.

alter database add logfile member '<path_to_filename>' to group <group_number>;

Dans le cas pratique :

alter database add logfile member '/sdata/oracle/v8/TSTT1ORA/redolog/redo1_02.log'
to group 1

La vue V$LOG indique bien deux membres dans le groupe de fichiers de redo log n°1 et lorsqu'il s'agit d'un groupe de fichiers de redo log nouveau, le statut indiqué dans la vue V$LOG est UNUSED :

select group#,
       thread#,
       sequence#,
       bytes,
       members,
       archived,
       status,
       first_change#,
       to_char(first_time,'dd/mm/yy hh:mi:ss') as FIRST_TIME
from v$log;
group# thread# sequence# bytes   members arc status     first_change#  first_time
------ ------- --------- ------- ------- --- ---------  -------------  ----------
1        1        0        1048576      2 YES UNUSED               0        
2        1        1067     1048576      1 NO  INACTIVE        292768   14/01/2005 01:09
3        1        1068     1048576      1 NO  CURRENT         312770 

Le groupe 3 va être également recréé :

SQL > alter database drop logfile group 3;

SQL > alter database add logfile (
        '/sdata/oracle/v8/TSTT1ORA/redolog/redo3_01.log',
        '/sdata/oracle/v8/TSTT1ORA/redolog/redo3_02.log'
) size 1M;

Le groupe 2 va être recréé en ajoutant et supprimant des membres (des switchs de log sont réalisés):

SQL > alter database
         add logfile member '/sdata/oracle/v8/TSTT1ORA/redolog/redo2_01.log' to group 2;

SQL > alter database
         drop logfile member '/sdata/oracle/v8/TSTT1ORA/redolog/redo02.log';

SQL > alter database
         add logfile member '/sdata/oracle/v8/TSTT1ORA/redolog/redo2_02.log' to group 2;

La vue V$LOGHIST

La vue V$LOGHIST qui s'appuie sur les informations contenues dans les fichiers de contrôle donne un historique sur les switchs de redo log.

select thread#, sequence#,first_change#,to_char(first_time,'dd/mm/yyyy hh:mi:ss'), switch_change#
from v$loghist;
#        sequence# first_change# to_char(first_time, switch_change#
-------  --------- ------------- ------------------- --------------
1        1068        312770        14/01/2005 01:40        312821
1        1069        312821        14/01/2005 02:07        312822
1        1070        312822        14/01/2005 02:09        312823
1        1071        312823        14/01/2005 02:23        312824
1        1072        312824        14/01/2005 02:29        312825
1        1073        312825        14/01/2005 02:29        312826
1        1074        312826        14/01/2005 02:29        332828

Les numéros de séquence de log sont historisées dans la vue V$LOGHIST en donnant également le SCN (system change number) de départ pour une séquence (first_change#) et le SCN correspondant à un switch de log.

Par exemple, la séquence de log 1068 a démarré le 14/01/2005 à 01h50:01 : le premier SCN est le numéro 312770 (first_change#) et le dernier SCN est le numéro 312820 puisqu'un switch de log a été réalisé pour le SCN 312820 (switch_change#). La séquence de log 1068 contient dont 50 enregistrements de redo.

Le paramètre MAXLOGHISTORY lors de la création de la base de données gouverne le nombre maximal de rétention des informations des switchs de log dans les fichiers de contrôle. Pour modifier ce paramètre, ou bien un fichier de contrôle doit être recréé, ou bien la base de données doit être reconstruite.

La vue v$controlfile_record_section permet de connaître le paramètre MAXLOGHISTORY :

SQL > select records_total from v$controlfile_record_section where type='LOG HISTORY'
records_total
-------------
1815

Dans le contexte du cas pratique : 1815 switchs de log sont historisés dans V$LOGHIST.