web-dev-qa-db-fra.com

Comment détecter les modifications apportées à une base de données (DDL et DML)

Il y a beaucoup de bases de données sur le serveur SQL de mon client. Ces bases de données sont en cours de développement, afin que les développeurs puissent concevoir, refactoriser, effectuer des modifications de données, etc. Certaines bases de données changent rarement. Mon client doit les garder tous en sécurité (sauvegardés) et passer du temps à gérer l'environnement. (Il n'y a pas de poste d'administrateur de base de données dans l'entreprise.) Après une longue discussion, le client a décidé d'utiliser une stratégie de sauvegarde complète quotidienne, en raison de la facilité de restauration.

Voici donc le résumé de la situation:

  • Le nombre de bases de données peut varier chaque jour.
  • Les bases de données qui ont été modifiées (ce qui signifie que les données et/ou la structure ont été modifiées) doivent être sauvegardées.
  • Les bases de données qui n'ont pas été modifiées ne doivent PAS être sauvegardées.
  • La solution ne doit pas affecter la structure de la base de données (ce n'est pas une exigence restreinte)
  • Ce "moteur de sauvegarde" fonctionnera automatiquement.

Le problème principal: comment détecter qu'une base de données a été modifiée. La première partie du problème (changements DDL) peut être résolue en utilisant DDL déclenche . Mais les changements de données (changements DML) sont un problème. Il est impossible d'appliquer des déclencheurs DML à toutes les tables de toutes les bases de données pour suivre les changements (performances, gestion des objets étendus ...). Le moteur de sauvegarde doit suivre toutes les modifications pour marquer chaque base de données comme prête à la sauvegarde.

  • Change Data Capture est une solution mais elle semble trop lourde (elle nécessite également SQL Server Enterprise Edition).

  • Une autre façon consiste à suivre les modifications du fichier de base de données (taille ou dernière heure de modification), mais cela ne fonctionne pas correctement: une base de données peut changer sa taille lorsqu'elle dépasse tout l'espace libre réservé et sp_spaceused n'est pas une solution.

  • Le traçage est une solution mais il provoque problèmes de performances et nécessite une gestion supplémentaire.

Existe-t-il des solutions pour calculer la taille réelle d'utilisation de la base de données sans impact sur les autres objets de gestion de base de données (comme les statistiques ..)? Certes, une modification des données d'une table qui ne change pas la taille de la table ne se déclencherait pas (je pense), mais c'est mieux que rien. Vraiment je recherche une solution directe ou indirecte pour SQL Server 2008.

Merci pour tous commentaires, solutions et réflexions.

AJOUTÉ:

Voici la solution (merci à Marian ):

Select
    NextLSN = MAX(fn.[Current LSN])
    ,Databasename = DB_NAME()
 from fn_dblog(NULL,    NULL) fn
     LEFT JOIN sys.allocation_units au
         ON fn.AllocUnitId = au.allocation_unit_id
     LEFT  JOIN sys.partitions p
         ON p.partition_id = au.container_id
     LEFT  JOIN sys.objects so
         ON so.object_id = p.object_id  
    WHERE 
    (
        (Operation IN 
       ('LOP_INSERT_ROWS','LOP_MODIFY_ROW',
            'LOP_DELETE_ROWS','LOP_BEGIN_XACT','LOP_COMMIT_XACT') 
            AND so.is_ms_shipped = 0)
        OR 
        ([Lock Information] like '%ACQUIRE_LOCK_SCH_M OBJECT%')
    )
13
garik

Une idée serait de faire un instantané tous les jours et de surveiller la taille du fichier instantané sur le disque à l'aide d'un moniteur de fichiers. L'instantané n'augmente sa taille que lorsque des données y sont ajoutées, il serait donc judicieux de trouver un outil pour surveiller la taille réelle (taille signalée).

Maintenant .. Je ne l'ai pas utilisé, donc je ne peux pas vous donner des informations techniques :-).

Une autre idée serait de vérifier le journal des transactions de chaque base de données (si vous utilisez le mode de récupération complet sur elles, bien sûr) avec une fonction que j'ai vue sur les forums (db_fnlog .. ou quelque chose) qui lit les opérations du journal et voyez si vous avez des suppressions/insertions/mises à jour.

Ce ne sont pas des choses faciles à faire .. mais j'espère que vous les trouverez utiles.

PS: a trouvé l'article avec la fonction de lecture du journal (c'est fndblog, d'ailleurs :-): Lire le journal des transactions par Jens K. Suessmeyer .

7
Marian
  • Pour les modifications DDL, vous pouvez lire Trace par défaut .
  • Pour les modifications DML puisque vous trouvez que CDC est un peu lourd, vous pouvez exécuter votre propre trace côté serveur léger qui ne trace que les événements pertinents
1
Nomad

Pour les modifications DML, vous pouvez utiliser l'une des fonctionnalités d'audit natives SQL Server suivantes:

  • Suivi des modifications SQL Server
  • Capture de données modifiées SQL Server
  • Audit SQL Server

Chacun a ses avantages et ses inconvénients, mais l'audit est le dernier introduit par Microsoft, donc ce serait une bonne idée de construire vos solutions actuelles et futures en conséquence.

Notez que seule la fonction d'audit fournit des informations sur Qui/Quand/Comment

1
Ivan Stankovic

Pour les modifications DDL, vous déclenchez DDL, mais les modifications DML vous pouvez essayer d'utiliser 3 options différentes

1) Suivi des modifications 2) CDC (Capture des données modifiées) 3) Fonction d'audit

Pour le suivi des modifications .. vous pouvez voir le lien ci-dessous http://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-sql-server-2008/

ce suivi des modifications ne sera utilisé que si la table a changé ou non ... mais il est très difficile de trouver quelles données ont changé .. si vous voulez trouver quelles données ont changé, vous pouvez aller à Chnage data Capture.

Pour Aduit dans sqlserver ..vous pouvez vérifier le lien ci-dessous http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx

1
Anil Inampudi

Vous pouvez détecter toutes les modifications ddl à l'aide du fichier de trace. ci-dessous est un script pour obtenir des modifications.

SELECT 
    te.name AS eventtype
    ,t.loginname
    ,t.spid
    ,t.starttime
    ,t.objectname
    ,t.databasename
    ,t.hostname
    ,t.ntusername
    ,t.ntdomainname
    ,t.clientprocessid
    ,t.applicationname  
FROM sys.fn_trace_gettable
(
    CONVERT
    (VARCHAR(150)
    ,(
        SELECT TOP 1 
            value
        FROM sys.fn_trace_getinfo(NULL)  
        WHERE property = 2
    )),DEFAULT
) T 
INNER JOIN sys.trace_events as te 
    ON t.eventclass = te.trace_event_id 
WHERE eventclass=164

Vous pouvez détecter toute modification sur la table et la procédure stockée à l'aide de ce script:

SELECT 
    SO.Name
    ,SS.name 
    ,SO.type_desc 
    ,SO.create_date
    ,SO.modify_date 
 FROM sys.objects AS SO
INNER JOIN sys.schemas AS SS 
    ON SS.schema_id = SO.schema_id 
WHERE DATEDIFF(D,modify_date, GETDATE()) < 50
AND TYPE IN ('P','U')
0
Anvesh