Backup database (Parte II)

Recuperare il database

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

Recuperare un backup completo

Recuperare un backup "full" , è tanto semplice quanto crearlo:

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

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

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

A questo punto, volendo recuperare ad esempio il secondo file del 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 1
The 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 do
not want to lose. Use the WITH REPLACE or WITH STOPAT clause of the RESTORE
statement to just overwrite the contents of the log.
Msg 3013, Level 16, State 1, Line 1
RESTORE 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' ultimo riportato sopra:

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

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

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

In questo caso, potrebbero apparire alcuni errori. Possiamo realmente creare nuovi database da un backup,ma se tentiamo di farlo su un server sul quale è già presente questo database, ci sarà bisogno di cambiare la locazione del file, usandone il relativo logic name. Per conoscere i logical names dei files di un database, usare questo script:

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

Avremo così i logical names dei files, che potremo usare 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 due operazioni: innanzitutto recuperare il database, facendone una copia gemella ed, a  questo punto, applicarvi il backup 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 avviarsi alcune transactions, alcune completandosi, altre rimanendo a metà; alla fine del recupero dunque, alcune transactions risulteranno completate, altre invece (quelle a metà) totalmente annullate. Grazie al NORECOVERY invece le transazioni vengono sempre tenute aperte.

Recuperare un database da un certo momento

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

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

Altrimenti, eseguire il recupero del backup, facendo attenzione a togliere lo stato non-recovered. Seguiamo questi script per recuperare una serie di log relativi ad un periodo 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 la keyword NORECOVERY, dovremo fermare l' operazione e recuperare il backup del database, per poi riprendere il processo con:

RESTORE DATABASE Adventureworks 
WITH RECOVERY;

Procedimenti Consigliati:

Il modo in cui viene creato un backup può non dipendere da una decisione tecnica, ma può essere dettata dal tipo di lavoro da eseguire. Piccole applicazioni con velocità di transazioni molto basse richiedono backup 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 backup più appropriata.

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

Per un database di grandi dimensioni è invece consigliabile evitare i full backups, mentre è preferibile effettuare un backup per ciascun gruppo di file in esso contenuto.

Naturalmente, è importantissimo trovare e definire il luogo ove stanziare i backups. A sua volta, è bene programmare backup di questa zona, per evitare brutte sorprese, 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.



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Sara
Hai dubbi su questo articolo?