it-swarm.it

Come rilevare eventuali modifiche a un database (DDL e DML)

Ci sono molti database sul server SQL del mio cliente. Questi database sono in fase di sviluppo, quindi gli sviluppatori possono progettare, refactoring, apportare modifiche ai dati e così via. Ci sono alcuni database che cambiano raramente. Il mio cliente deve tenerli tutti al sicuro (backup) e dedicare un po 'di tempo alla gestione dell'ambiente. (Non esiste una posizione di amministratore DB presso l'azienda). Dopo lunghe discussioni, il cliente ha deciso di utilizzare una strategia di backup completo giornaliero, a causa della facilità di ripristino.

Quindi, ecco il riassunto della situazione:

  • Il numero di database può variare ogni giorno.
  • È necessario eseguire il backup dei database che sono stati modificati (nel senso che i dati e/o la struttura sono stati modificati).
  • I database che non sono stati modificati NON devono essere sottoposti a backup.
  • La soluzione non deve influire sulla struttura del database (non è un requisito limitato)
  • Questo "motore di backup" deve funzionare automaticamente.

Il problema principale: come rilevare che un database è stato modificato. La prima parte del problema (modifiche DDL) può essere risolta usando Trigger DDL . Ma le modifiche ai dati (modifiche DML) sono un problema. È impossibile applicare i trigger DML a tutte le tabelle di tutti i database per tenere traccia delle modifiche (prestazioni, gestione degli oggetti estesi ...). Il motore di backup deve tenere traccia di tutte le modifiche per contrassegnare ciascun database come pronto per il backup.

  • Change Data Capture è una soluzione ma sembra troppo pesante (richiede anche SQL Server Enterprise Edition).

  • Un altro modo è tenere traccia delle modifiche ai file di database (dimensioni o ora dell'ultima modifica), ma non funziona correttamente: un database può cambiare le sue dimensioni quando supera tutto lo spazio libero riservato e sp_spaceused non è una soluzione.

  • La traccia è una soluzione ma causa problemi di prestazioni e richiede una gestione aggiuntiva.

Esistono soluzioni per calcolare l'effettiva dimensione di utilizzo del database senza impatto su altri oggetti di gestione del database (come le statistiche ..)? Concesso che una modifica ai dati di una tabella che non modifica le dimensioni della tabella non si innescherebbe (credo), ma è meglio di niente. Sto davvero cercando una soluzione diretta o indiretta per SQL Server 2008.

Grazie per eventuali commenti, soluzioni e pensieri.

ha aggiunto:

Ecco la soluzione (grazie a 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

Un'idea sarebbe quella di creare un'istantanea ogni giorno e monitorare la dimensione del file dell'istantanea sul disco usando un monitor file. Lo snapshot sta aumentando le sue dimensioni solo quando vengono aggiunti dati lì, quindi sarebbe una valida idea se si trovasse uno strumento per monitorare le dimensioni reali (dimensioni riportate).

Ora .. Non l'ho usato, quindi non posso darti approfondimenti tecnici :-).

Un'altra idea sarebbe quella di verificare il registro delle transazioni di ciascun db (se si sta utilizzando la modalità di recupero completo su di essi, ovviamente) con alcune funzioni che ho visto sui forum (db_fnlog .. o qualcosa del genere) che legge le operazioni dal registro e vedi se hai eliminazioni/inserti/aggiornamenti.

Non sono cose facili da fare .. ma spero che le troverai utili.

PS: trovato l'articolo con la funzione di lettura del registro (è fndblog, a proposito :-): Leggi il registro delle transazioni di Jens K. Suessmeyer .

7
Marian
  • Per le modifiche DDL è possibile leggere Traccia predefinita .
  • Per le modifiche DML poiché ritieni che CDC sia un po 'pesante, puoi eseguire la tua traccia lato server leggera che traccia solo gli eventi rilevanti
1
Nomad

Per le modifiche DML è possibile utilizzare una qualsiasi delle seguenti funzionalità di controllo nativo di SQL Server:

  • Monitoraggio delle modifiche di SQL Server
  • SQL Server Change Data Capture
  • Controllo di SQL Server

Ognuno ha i suoi vantaggi e svantaggi, ma il controllo è l'ultimo introdotto da Microsoft, quindi sarebbe una buona idea costruire le tue soluzioni attuali e future.

Si noti che solo la funzione di controllo fornisce informazioni su Chi/Quando/Come

1
Ivan Stankovic

Per le modifiche DDL, Trigger DDL, ma le modifiche DML puoi provare a utilizzare 3 diverse opzioni

1) Tracking delle modifiche 2) CDC (Change Data Capture) 3) Funzione di controllo

Per il rilevamento delle modifiche .. puoi vedere il link seguente http://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-sql-server-2008/

questo rilevamento delle modifiche verrà utilizzato solo se la tabella è cambiata o meno ... ma è molto difficile trovare quali dati sono cambiati .. se vuoi trovare quali dati sono cambiati, puoi utilizzare Chnage Data Capture.

Per Aduit in sqlserver .. è possibile controllare il seguente link http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx

1
Anil Inampudi

È possibile rilevare eventuali modifiche ddl utilizzando il file di traccia. di seguito è riportato lo script per ottenere le modifiche.

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

È possibile rilevare qualsiasi modifica sulla tabella e stored procedure utilizzando questo 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