Eseguire un backup senza indici
Sul newsgroup privato degli MVP sto seguendo da qualche giorno il thread che Greg Linwood ha lanciato in merito ad un suo post, segnalato anche da Andrea, sulla possibilità di eseguire backup solo dei dati di un database. Lasciando fuori gli indici si potrebbe risparmiare mediamente un 50% di spazio (e tempo) di informazioni, tutto sommato, per certi versi ridondanti e comunque riproducibili
Da un punto di vista implementativo non è affatto semplice dare seguito alla richiesta e non mi addentro nei dettagli delle motivazioni che alcuni membri del team di sviluppo di SQL Server hanno dato, sempre nel newsgroup privato MVP, per motivare le ragioni per le quali, allo stato attuale, la richiesta è stata chiusa con un "won't fix".
Sicuramente in un'ottica di disaster recovery avrebbe poco senso ripristinare un database privo di indici perchè questi andrebbero sicuramente ricreati o ricostruiti prima di restituire l'operatività del database ed i tempi di ricostruzione vanificherebbero qualunque risparmio di tempo precedente. Certamente l'attività di ricostruzione degli indici può essere posticipata e le "funzionalità vitali" del database, ovvero mettere a disposizione i dati a chi ne faccia richiesta, sarebbero certamente salvaguardate già con il ripristino, minimale, dei soli dati. Tutte le query sarebbero risolte con un table scan, ma l'operatività sarebbe comunque garantita.
Inoltre in quegli scenari dove i tempi di downtime devono tendere a zero, la continuità non può essere affidata ad una seppur eccellente strategia di disaster recovery ma ci saranno soluzioni basate su cluster, log shipping, database mirroring, san in mirror, ecc (e sicuramente 2 o più di queste funzionalità integrate fra loro) in grado di assicurare la continuità del servizio nelle diverse circostanze relegando il restore alle attività più catastrofiche.
La soluzione che prevede il backup dei soli dati potrebbe essere percorribile in quegli ambienti dove non è vitale una rapida ripresa del servizio a seguito di un danno, ma ci si può permettere un fermo più ampio, necessario alle attività di creazione/ricostruzione degli indici. In questo caso avrei comunque il vantaggio di avere un backup di dimensioni contenute che mi farebbe risparmiare sullo spazio disco/nastro necessario per le diverse esigenze di archiviazione insite/offsite. Ragionando nell'ottica "il backup lo faccio quotidianamente, il restore spero di non farlo mai (se non in ambiente di test)" si tratta certamente di una soluzione non solo percorribile ma anche raccomandabile che consente di risparmiare tempo e risorse in occasione dei backup a fronte di un accettabile ritardo nei tempi di ripristino.
In ogni caso in SQL Server 2005 è possibile velocizzare il processo di ripristino dei dati ricorrendo al "piecemeal restore", ovvero un restore parziale in grado di restituire l'operatività del database anche se il processo di ripristino non si è completato. Questo obiettivo possiamo realizzarlo suddividendo il database su diversi filegroup e posizionando i dati su un filegroup e gli indici non clustered su un altro filegroup. Così facendo, in occasione di un ripristino, potremmo accedere al db già immediatamente dopo il ripristino del filegroup contenente i dati e prima che sia terminato il ripristino del filegroup contenente gli indici (il filegroup primary deve essere ripristinato prima di tutti).
Tuttavia questa soluzione richiede la reingegnerizzazione del database affinchè venga strutturato secondo determinate regole e benchè lo spostamento degli indici su un altro filegroup sia una attività che può essere fatta agevolmente (e online) mediante la ricostruzione degli indici stessi, la soluzione appare poco percorribile perchè possa essere utilizzata su vasta scala così come in tutti quegli ambienti, anche di medie dimensioni, dove non esiste una figura di DBA a tempo pieno in grado di pianificare e documentare la strategia di ripristino (last but not least il "partial restore" è presente solo nella versione Enterprise).
Tornando alle ragioni per le quali potrei voler eseguire un backup dei soli dati, tenderei ad escludere anche quelle attività che richiedono il ripristino di un database di produzione nell'ambiente di test perchè un ambiente di collaudo che non sia il più possibile simile a quello di produzione vanificherebbe buona parte della destinazione d'uso specifica di questi ambienti (sempre che non voglia farmi carico della duplice attività restore + reindex). Restano i casi legati ad un eventuale ripristino in ambiente di sviluppo oppure quando il database deve essere inviato ad un fornitore esterno o ad una sede periferica della società, ovvero quei casi in cui ridurre le dimensioni fisiche dei dati da inviare si traduce in un immediato e tangibile vantaggio.
Non sarebbe male, quindi, avere una clausola che ci permetta di eseguire un
BACKUP DATABASE MyDB TO DISK = myDevice WITH DATA_ONLY
Qui nasce, però, uno degli interrogativi da porsi: è l'integrità dei dati? Per poterla garantire devo aver bisogno, almeno, di tutte le primary key e di tutti gli unique constraint che, se non sono di tipo clustered, avrebbero a loro volta bisogno dei rispettivi indici clustered per non perdere il puntamento alle pagine dati. Oppure voglio rinunciare anche a questa garanzia che un DBMS dovrebbe darmi?
Forse tutto sommato utilizzerei veramente poco un backup privo di indici, anche in considerazione del fatto che, in SQL Server 2008, verrà introdotta la possibilità di comprimere dati e backup ottenendo i benefici voluti e da test che ho eseguito la compressione dei dati ed i backup compressi sono "cumulabili" fra loro ed un backup compresso di un database compresso può essere ulteriormente zippato (anche se di pochi punti percentuali) o posizionato su una cartella compressa a livello NTFS riducendolo da 14,6 GB iniziali ad 1,02 GB. Stiamo parlando di una riduzione del 93% che benchè sia maturata in circostanze favorevoli ad un elevato fattore di compressione dei dati, rappresenta un risultato di sicuro interesse...
Bye