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

13

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 avoir d'impact sur la structure de la base de données (ce n'est pas une exigence restreinte)
  • Ce "moteur de sauvegarde" fonctionnera automatiquement.

Le principal problème: comment détecter qu'une base de données a été modifiée. La première partie du problème (modifications DDL) peut être résolue à l'aide de déclencheurs DDL . 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 à être sauvegardée.

  • 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 des fichiers de la base de données (taille ou heure de la dernière 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 entraîne des 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ÉE:

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%')
    )
garik
la source
Alors avez-vous implémenté cela dans le cadre d'un travail ou ??? Je serais ravi d'avoir une méthode de sortie quotidienne (disons à 2h du matin) de tous les changements des 24 heures précédentes dans un répertoire afin que je puisse avoir un peu de journal des modifications pour moi.
jcolebrand
@jcolebrand oui, je l'ai fait. Dans mon cas, je dois vérifier toute activité de base de données, puis effectuer une sauvegarde (complète ou différentielle). Je vérifie LSN (la clé primaire de l'enregistrement de journal), cette fonction renvoie fn_dblog. C'est tout. Je ne pense pas que cela fonctionnera dans votre cas. Je n'ai pas étudié toutes les fonctionnalités des données qui peuvent être renvoyées par fn_dblog, mais je pense qu'elles ne renvoient pas toutes les informations concernant. Comme vous pouvez le voir, de nombreuses autres tables système y sont associées. Si c'était facile, nous aurions beaucoup d'outils normaux et bon marché :)
garik

Réponses:

7

Une idée serait de créer un instantané chaque jour et de surveiller la taille du fichier d'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 :-): Lisez le journal des transactions de Jens K. Suessmeyer .

Marian
la source
1
Je ne parlais pas de la taille des fichiers db, mais du fichier local d'instantané, qui est créé avec: créer la base de données xxxdb comme instantané de yyydb. Voir les détails sur les instantanés ici: msdn.microsoft.com/en-us/library/ms175158.aspx .
Marian
1
  • Pour les modifications DDL, vous pouvez lire la 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
Nomade
la source
1

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

Anil Inampudi
la source
1
+1, mais CDC livré avec Enterprise Edition
garik
1

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 de modification 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

Ivan Stankovic
la source
0

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')
Anvesh
la source