Erkennen von Änderungen an einer Datenbank (DDL und DML)

13

Auf dem SQL-Server meines Clients befinden sich viele Datenbanken. Diese Datenbanken befinden sich in der Entwicklung, sodass Entwickler Daten entwerfen, umgestalten, ändern und so weiter können. Es gibt einige Datenbanken, die sich selten ändern. Mein Kunde muss sie alle sicher aufbewahren (sichern) und einige Zeit mit der Verwaltung der Umgebung verbringen. (Im Unternehmen gibt es keine Position als DB-Administrator.) Nach einer langen Diskussion hat sich der Client aufgrund der einfachen Wiederherstellung für eine tägliche vollständige Sicherungsstrategie entschieden.

Also hier ist die Zusammenfassung der Situation:

  • Die Anzahl der Datenbanken kann täglich variieren.
  • Geänderte Datenbanken (dh Daten und / oder Struktur wurden geändert) müssen gesichert werden.
  • Datenbanken, die nicht geändert wurden, werden NICHT gesichert.
  • Die Lösung darf keine Auswirkungen auf die Datenbankstruktur haben (keine Einschränkung erforderlich)
  • Diese "Backup-Engine" soll automatisch funktionieren.

Das Hauptproblem: Wie erkennt man, dass eine Datenbank geändert wurde? Der erste Teil des Problems (DDL-Änderungen) kann mithilfe von DDL-Triggern behoben werden . Die Datenänderungen (DML-Änderungen) sind jedoch ein Problem. Es ist unmöglich, DML-Trigger auf alle Tabellen aller Datenbanken anzuwenden, um Änderungen zu verfolgen (Leistung, Verwaltung erweiterter Objekte ...). Die Backup-Engine muss alle Änderungen nachverfolgen, um jede Datenbank als bereit für das Backup zu markieren.

  • Change Data Capture ist eine Lösung, scheint jedoch zu umfangreich zu sein (erfordert auch SQL Server Enterprise Edition).

  • Eine andere Möglichkeit besteht darin, Änderungen an der Datenbankdatei zu verfolgen (Größe oder Zeitpunkt der letzten Änderung), dies funktioniert jedoch nicht ordnungsgemäß: Eine Datenbank kann ihre Größe ändern, wenn der gesamte reservierte freie Speicherplatz überschritten wird und sp_spaceused keine Lösung darstellt.

  • Die Ablaufverfolgung ist eine Lösung, verursacht jedoch Leistungsprobleme und erfordert zusätzliches Management.

Gibt es Lösungen zur Berechnung der tatsächlichen Größe der Datenbanknutzung, ohne Auswirkungen auf andere Datenbankverwaltungsobjekte (z. B. Statistiken) zu haben? Zugegeben, eine Änderung an den Daten einer Tabelle, die die Größe der Tabelle nicht ändert, wird nicht ausgelöst (glaube ich), ist aber besser als nichts. Wirklich suche ich nach einer direkten oder indirekten Lösung für SQL Server 2008.

Vielen Dank für Kommentare, Lösungen und Gedanken.

HINZUGEFÜGT:

Hier ist die Lösung (danke an 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
quelle
Hast du das als Teil eines Jobs implementiert oder ??? Ich würde gerne eine Methode für die tägliche Ausgabe (etwa um 2 Uhr morgens) aller Änderungen der letzten 24 Stunden in ein Verzeichnis haben, damit ich ein bisschen Changelog für mich haben kann.
Jcolebrand
@ Jcolebrand ja, ich habe. In meinem Fall muss ich jede Datenbankaktivität überprüfen und dann ein Backup (vollständig oder differenziell) erstellen. Ich überprüfe die LSN (den Primärschlüssel des Protokolldatensatzes), die die Funktion fn_dblog zurückgibt. Das ist alles. Ich glaube nicht, dass es in deinem Fall funktionieren wird. Ich habe nicht alle Funktionen von Daten untersucht, die von fn_dblog zurückgegeben werden können, aber ich denke, es werden nicht alle Informationen zurückgegeben, die damit zu tun haben. Wie Sie sehen, sind viele andere Systemtabellen damit verbunden. Wenn es einfach wäre, hätten wir eine Menge normaler, billiger Werkzeuge :)
garik

Antworten:

7

Eine Idee wäre, jeden Tag einen Snapshot zu erstellen und die Größe der Snapshot-Datei auf der Festplatte mithilfe eines Dateimonitors zu überwachen. Der Schnappschuss vergrößert sich nur, wenn dort Daten hinzugefügt werden. Daher ist es eine gute Idee, ein Tool zur Überwachung der tatsächlichen Größe (gemeldete Größe) zu finden.

Nun .. ich habe das nicht benutzt, kann dir also keine technischen Einsichten geben :-).

Eine andere Idee wäre, das Transaktionsprotokoll jeder Datenbank (wenn Sie den vollständigen Wiederherstellungsmodus verwenden) mit einer Funktion zu überprüfen, die ich in den Foren gesehen habe (db_fnlog .. oder so), die Vorgänge aus dem Protokoll liest , und prüfen Sie, ob Löschvorgänge / Einfügungen / Aktualisierungen vorhanden sind.

Das sind keine einfachen Dinge, aber ich hoffe, Sie werden sie nützlich finden.

PS: habe den Artikel mit der Log Read Funktion gefunden (es ist übrigens fndblog :-): Lies das Transaktionslog von Jens K. Suessmeyer .

Marian
quelle
1
Ich habe nicht über die Größe von DB-Dateien gesprochen, sondern über die lokale Snapshot-Datei, die erstellt wird mit: create database xxxdb as snapshot of yyydb. Details zu Snapshots finden Sie hier: msdn.microsoft.com/en-us/library/ms175158.aspx .
Marian
1
  • Für DDL-Änderungen lesen Sie bitte die Standard-Trace .
  • Für DML-Änderungen, da Sie CDC als etwas schwerfällig empfinden, können Sie einen eigenen kompakten serverseitigen Trace ausführen, der nur die relevanten Ereignisse verfolgt
Nomade
quelle
1

Bei DDL-Änderungen lösen Sie DDL-Trigger aus, bei DML-Änderungen können Sie drei verschiedene Optionen verwenden

1) Änderungsnachverfolgung 2) CDC (Datenerfassung ändern) 3) Audit-Funktion

Für die Änderungsverfolgung sehen Sie den folgenden Link: http://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-sql-server-2008/

Diese Änderungsnachverfolgung wird nur verwendet, wenn sich die Tabelle geändert hat oder nicht. Es ist jedoch sehr schwierig zu ermitteln, welche Daten geändert wurden. Wenn Sie ermitteln möchten, welche Daten geändert wurden, können Sie die Datenerfassung starten.

Für Aduit in sqlserver .. können Sie den folgenden Link überprüfen: http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx

Anil Inampudi
quelle
1
+1, aber CDC ausgeliefert mit Enterprise Edition
Garik
1

Für DML-Änderungen können Sie eine der folgenden nativen SQL Server-Überwachungsfunktionen verwenden:

  • SQL Server-Änderungsnachverfolgung
  • SQL Server Change Data Capture
  • SQL Server-Überwachung

Jedes hat seine Vor- und Nachteile, aber das Auditing ist das neueste, das von Microsoft eingeführt wurde. Daher ist es eine gute Idee, Ihre aktuellen und zukünftigen Lösungen damit zu kombinieren.

Beachten Sie, dass nur die Überwachungsfunktion Informationen zu Wer / Wann / Wie enthält

Ivan Stankovic
quelle
0

Sie können alle ddl-Änderungen mithilfe der Tracedatei erkennen. Unten ist ein Skript, um Änderungen zu erhalten.

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

Mithilfe dieses Skripts können Sie Änderungen an der Tabelle und der gespeicherten Prozedur erkennen:

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
quelle