Backup database (Parte II)

Recuperare il database

Di vitale importanza per un database è, ovviamente, lapossibilità di essere recuperato.

Recuperare un backup completo

Recuperare un backup "full" , è tantosemplice quanto crearlo:

RESTORE DATABASE Adventureworks FROM DISK = 'C:BackupAdventureWorks.bak';

Un po' più complesso invece il caso in cui sivoglia recuperare qualsiasi cosa di un file, come se fosse unbackup device; in questo caso dovremo specificare a qualefile, interno al device, accedere. Se non si conosce talefile, dovremo generarne una lista, così:

RESTORE HEADERONLY FROM DISK = 'C:BackupAdventureworks.bak';

A questo punto, volendo recuperare ad esempio il secondo filedel gruppo (quello del COPY_ONLY), ecco i comandi:

RESTORE DATABASE AdventureWorks FROM DISK = 'C:BackupAdventureworks.bak' WITH FILE = 2;

Sfortunatamente così si cade in un errore:

Msg 3159, Level 16, State 1, Line 1The tail of the log for the database "AdventureWorks" has not been backed up.Use BACKUP LOG WITH NORECOVERY to backup the log if it contains work you donot want to lose. Use the WITH REPLACE or WITH STOPAT clause of the RESTOREstatement to just overwrite the contents of the log.Msg 3013, Level 16, State 1, Line 1RESTORE DATABASE is terminating abnormally.

Cosa significa? Che il database in questione èimpostato in full recovery mode. Come evitare l'errore? Con questo script, da sostituire all' ultimoriportato sopra:

RESTORE DATABASE AdventureWorks FROM DISK = 'C:BackupsAdventureworks.bak' WITH FILE = 2, REPLACE;

Cosa accade se vogliamo recuperare i dati da un databasedifferente dall' originale? Ecco lo script:

RESTORE DATABASE AdventureWorks_2 FROM DISK =    'C:BackupsAdventureworks.bak' WITH FILE = 2;

In questo caso, potrebbero apparire alcuni errori. Possiamorealmente creare nuovi database da un backup,ma se tentiamodi farlo su un server sul quale è già presentequesto database, ci sarà bisogno di cambiare lalocazione del file, usandone il relativo logic name. Perconoscere i logical names dei files di un database, usarequesto script:

RESTORE FILELISTONLY FROM DISK =    'C:BackupsAdventureworks.bak' WITH FILE = 2;

Avremo così i logical names dei files, che potremousare per dar vita al successivo script:

RESTORE DATABASE AdventureWorks_2 FROM DISK = 'C:BackupsAdventureworks.bak' WITH FILE = 2,    MOVE 'AdventureWorks_Data' TO 'C:ackupsaw2_data.mdf',    MOVE 'AdventureWorks_Log' TO 'C:ackupsaw2_log.ldf';

Recuperare backup differenziali

Per recuperare un backup differenziale bisogna eseguire dueoperazioni: innanzitutto recuperare il database, facendoneuna copia gemella ed, a  questo punto, applicarvi ilbackup differenziale:

RESTORE DATABASE AdventureWorks FROM DISK = 'C:BackupsAdventureworks.bak' WITH FILE = 1,    NORECOVERY,    REPLACE;  RESTORE DATABASE AdventureWorks FROM DISK = 'C:BackupsAdventureWorks.bak' WITH FILE = 3;

Mai sentito parlare della keyword NORECOVERY? Niente paura,è molto semplice: durante il recupero possono avviarsialcune transactions, alcune completandosi, altre rimanendo ametà; alla fine del recupero dunque, alcunetransactions risulteranno completate, altre invece (quelle ametà) totalmente annullate. Grazie al NORECOVERYinvece le transazioni vengono sempre tenute aperte.

Recuperare un database da un certomomento

Recuperare i logs non è poi più difficile cherecuperare un backup differenziale, Immaginiamo di volerrecuperare i logs di un singolo file o device:

RESTORE HEADERONLY FROM DISK = 'C:BackupsAdventureworks_log.bak';

Altrimenti, eseguire il recupero del backup, facendoattenzione a togliere lo stato non-recovered. Seguiamoquesti script per recuperare una serie di log relativi ad unperiodo ben preciso:

RESTORE DATABASE AdventureWorks FROM DISK = 'C:BackupsAdventureworks.bak' WITH FILE = 1,    NORECOVERY,    REPLACE,    STOPAT = 'Oct 23, 2006 14:30:29.000'; RESTORE LOG AdventureWorks FROM DISK = 'C:BackupsAdventureworks_log.bak' WITH FILE = 1,    NORECOVERY,    STOPAT = 'Oct 23, 2006 14:30:29.000'; RESTORE LOG AdventureWorks FROM DISK = 'C:BackupsAdventureworks_log.bak' WITH FILE = 2,    NORECOVERY,    STOPAT = 'Oct 23, 2006 14:30:29.000'; RESTORE LOG AdventureWorks FROM DISK = 'C:BackupsAdventureworks_log.bak' WITH FILE = 3,    NORECOVERY,    STOPAT = 'Oct 23, 2006 14:30:29.000'; RESTORE LOG AdventureWorks FROM DISK = 'C:BackupsAdventureworks_log.bak' WITH FILE = 4,    STOPAT = 'Oct 23, 2006 14:30:29.000';

Nel caso in tutte le richieste sia rimasta impostata lakeyword NORECOVERY, dovremo fermare l' operazione erecuperare il backup del database, per poi riprendere ilprocesso con:

RESTORE DATABASE Adventureworks WITH RECOVERY;

Procedimenti Consigliati:

Il modo in cui viene creato un backup può nondipendere da una decisione tecnica, ma può esseredettata dal tipo di lavoro da eseguire. Piccole applicazionicon velocità di transazioni molto basse richiedonobackup completi; i database di medio-grande dimensione,invece, risultano spesso dipendenti dai tipi di dati gestiti,in seguito ai quali si stabilisce la tipologia di backuppiù appropriata.

Per un database medio, un backup giornaliero con diversibackup dei logs, sparsi nella giornata, èindubbiamente una buona soluzione.

Per un database di grandi dimensioni è invececonsigliabile evitare i full backups, mentre èpreferibile effettuare un backup per ciascun gruppo di filein esso contenuto.

Naturalmente, è importantissimo trovare e definire illuogo ove stanziare i backups. A sua volta, è beneprogrammare backup di questa zona, per evitare bruttesorprese, causate da malasorte o da attacchi ben strutturati.

Infine, è consigliabile, per ogni backup completato,eseguirne il restore: se conterrà qualche errore,verrà subito al pettine.