Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
ACCUEIL SYBASE F.A.Q SYBASE FORUM SYBASE TUTORIELS SYBASE SOURCES SYBASE


Le journal de transaction et les seuils d'alerte sous ASE

7 janvier 2006
MAJ: 10 février 2006

Par Fabien Celaia (Fadace)

Sommaire

  • Préface
  • Principe de fonctionnement
  • Impact sur les sauvegardes
  • La vidange manuelle
  • La vidange automatique
  • Préface

    La plupart des SGBDR dignes de ce nom se doivent de maintenir leurs données consistantes en quelque moment que ce soit. Il faut donc un processus permettant

    • la récupération des données et le retour en un état transactionnel consistant en cas de crash au milieu d'activité
    • le retour en arrière d'une transaction au cas ou une erreur apparaîtrait et la récupération des anciennes valeurs
    • la sauvegarde consistante de la base de données pendant la période d'activité
    • la réplication des modifications effectuées dans des environnements distribués
    C'est donc le journal de transactions qui sera le garant de toutes ces différentes fonctionnalités.

    Sous Sybase ASE, le journal de transaction est en fait stocké dans une table propre à chaque base de données : la table système syslogs.

    Elle n'est pas utilisable en clair et est remplie séquentiellement.

    C'est cette table, et plus particulièrement la gestion de la place qu'elle utilise sur disque qui pose un certain nombre de problèmes aux DBAs en herbe.

    Principe de fonctionnement

    Prenons une transaction bancaire consistant à débiter et créditer 2 comptes.

    La transaction doit être atomique : soit les 2 écritures passent, soit aucune ne doit passer, soit...

    • Supprimer CHF 1000.-- du compte A
    • Ajouter CHF 1000.-- au nouveau compte B
    • Si tout c'est bien passé, valider, sinon invalider

    Ce qui s'écrit, en T-SQL

    BEGIN TRAN T2
    UPDATE CompteA SET Valeur=Valeur-1000 WHERE Noclient=999
    if @@error <> 0 
       ROLLBACK
    insert into CompteB (NoClient, Valeur) values (999,1000) 
    if @@error <> 0 
       ROLLBACK
    COMMIT

    Que se passe-t-il au niveau du journal de transaction ?

    Impact sur les sauvegardes

    Il faut ici déterminer quel type de sauvegardes vous effectuez.

    Sauvegarde de base de données complète uniquement

    Dans le cas où vous n'effectuez que des sauvegardes de base de données, vous devez tenir comptes des points suivantes

    • vous acceptez implicitement la perte de données qui pourrait se produire depuis votre dernière sauvegarde
    • vous vous interdisez la possibilité de revenir en arrière de quelques transactions en cas de DELETE/UPDATE malvenus

    Cela étant posé, cette façon de faire offre les intérêts suivants:

    • simplification de la gestion des jouraux de transactions
    • simplification de la gestion des sauvegardes

    Dans ce cas, il vous suffit de mettre l'option "trunc log on checkpoint" à votre base de données. Ce faisant, la partie inactive du journald e transaction sera nettoyée à chaque fois qu'un checkpoint (à savoir une écriture des blocs de la mémoire aux disques) s'effectuera.

    USE master
    GO
    sp_dboption Votrebase, 'trunc log', true
    GO

    Dans le même ordre d'idée, vous pouvez déterminer ce qui se passera si une transaction venait à remplir le journal. Vous pouvez choisir de tout arrêter tant que de la place ne se fait pas... dans ce cas, toute modification de cette base sera gelée. C'est l'option par défaut.

    Sinon vous pouvez opter de tuer la transaction saturant le log automatiquement:

    USE master
    GO
    sp_dboption Votrebase, 'abort tran on log full', true
    GO

    Sauvegarde de la base de données et des journaux de transaction

    Vidange manuelle

    Pour vidanger manuellement un journal de transaction plein, on doit exécuter la commande suivante:

    DUMP TRAN MaBase WITH TRUNCATE_ONLY

    Cette commande va tronquer toutes les transactions fermées apparaissant dans le journal, jusquà la première transaction ouverte.

    L'ASE doit cependant écrire dans ledit journal ce qu'il est en train de faire... ce qui pose un sérieux problème si le journal et totalement saturé. Dans ce cas, il y a possibilité de lui demander de tronquer le log sans spécifier quoi que ce soit dans le journal via

    DUMP TRAN MaBase WITH NOLOG

    c'est une méthode assez brutale, à n'utiliser qu'en ultime recours car si un problème matériel venait à apparaître à ce moment, la récupération automatique de la base pourrait être problématique : l'ASE essayerait de remonter un journal de transaction qu'il ne serait pas à même de trouver ! En effet, l'ASE cherchera à remonter une transaction dont l'ID se trouve dans master..syslogshold... et cette transaction ne sera plus présente dans Votrebase..syslogs !

    Il y a encore un cas de figure problématique : c'est celui de la transaction qu'un développeur aurait oublier de fermer.

    Dans ce cas, le journal de transaction se retrouve saturé par une seule transaction ouverte, donc impossible à vidanger.

    La solution consiste alors à tuer toutes les transactions ouvertes de la base problématique : ce faisant, la session problématique sera tuée et sa transaction rollbackée... et donc supprimable.

    La requête suivante vous génère les ordres SQL à exécuter pour tuer vos sessions. Il faut donc rejouer l'output de cette requête.

    SELECT 'KILL '+convert(char(5), spid) 
    from master..sysprocesses 
    where dbid=db_id('MaBase')

    ... puis réessayer le DUMP TRAN.

    Un autre cas de bord viendrait du fait que voter base aurait été une fois une base répliquée, utilisée par Sybase Replication Server ou SQL Remote. Dans ce cas, un deuxième point de troncature, nommé LTM (Log Transaction Mark) est présent et suit, avec une certaine latence, le point de troncature... et dans ce cas précis, le dump tran ne peut sectionner une transaction n'ayant pas passé dans la moulinette de la réplication.

    Il est assez aisé de se rendre compte qu'un LTM existe en testant la commande suivante : un LTM retourne une adresse supérieure à 0.

    use VotreBase
    GO
    dbcc gettrunc
    GO 

    Dans ce cas, il y a un moyen de supprimer ce point de troncature, tout en étant conscient de l'impact que cela pourrait avoir dans le cas ou votre base serait réellement une base source de réplication !

    USE VotreBase
    GO
    dbcc settrunc('ltm', 'ignore')
    GO

    ... et dans le cas ou ce problème se passerait en phase de récupération (et donc que la base ne pourrait être ouverte)

    use VotreBase
    GO
    dbcc dbrepair (VotreBase, ltmignore)
    GO

    Vidange automatique

    Il y a possibilité de créer une procédure stockée sp_thresholdaction.

    Soit il vous est possible de la créer dans la base sybsystemprocs, et dans ce cas elle sera active pour toutes vos bases

    Soit il vous est possible de la créer dans une base spécifique, et dans ce cas elle sera active cette base uniquement, en suppléant au besoin une sp_thresholdaction créée dans sybsystemprocs.

    Voici un exemple de procédure de seuil. Notez que vos pouvez modifier à votre guise le corps de la procédure, mais ni son nom, ni ses paramètres d'entrée:

    create procedure sp_thresholdaction 
            @dbname varchar(30),
            @segmentname varchar(30),
            @space_left int,
            @status int
    as
            dump transaction @dbname with truncate_only

    Il va sans dire que cette exemple est le plus basique qu'il soit. Nous pouvons l'enrichir à notre guise:

    CREATE PROC sp_thresholdaction (
      @dbname varchar(30),
      @segmentname varchar(30),
      @space_left int,
      @status int )  
    AS
    BEGIN
    declare @msg  varchar(80),
            @date_actuelle  datetime,
            @nom_fichier  varchar(100),
            @date_fichier  varchar(20),
            @rep_sauve_log  varchar(40)
    
    select @rep_sauve_log = C:\backup\log\'
    
    select @date_actuelle = getdate()
    
    select @date_fichier =
       convert(varchar(4),datepart(YYYY,@date_actuelle)) +
       convert(varchar(2),datepart(MM,@date_actuelle)) +
       convert(varchar(2),datepart(DD,@date_actuelle)) +'_'+
       convert(varchar(2),datepart(HH,@date_actuelle)) +
       convert(varchar(2),datepart(MI,@date_actuelle))
    
    select @nom_fichier = @rep_sauve_log + @dbname + @date_fichier + '.trn',
           @msg = 'ATTENTION: Seuil de la dernière chance atteint sur la base ' + @dbname + ', segment ' + @segmentname 
    
    print @msg
    
    if @segmentname = 'logsegment'
         dump tran @dbname to @nom_fichier
    
    return
    END

    Relevons que cette procédure est donc lancée automatiquement par l'ASE.

    Il est par contre possible d'ajouter des seuils à n'importe quel niveau et sur n'importe quel segment en l'activant via sp_addthreshold.

    Voici donc un exemple pour ajouter un seuil sur un segment d'index de la base MonTest.

    sp_addthreshold @dbname='MonTest', @segname='index_seg', @freespace=10, @proc_name='sp_thresholdaction'
    

    Copyright © Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.

    Responsable bénévole de la rubrique Sybase : Fabien Celaia - Contacter par EMail :
    Vos questions techniques : forum d'entraide Sybase - Publiez vos articles, tutoriels et cours
    et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
    Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.