A partire dalla CU2 di SQL Server 2012 SP1 è stata introdotta una funzionalità interessante per fare il backup di un database locale sullo storage di Windows Azure.
Sostanzialmente aggiunge la possibilità di specificare l’opzione TO URL ad un comando di backup database, assegnando come parametro uno storage account di Windows Azure.
Per accedere ho necessità di avere un Account di archiviazione e una chiave di accesso all’account. Fatto questo creerò un oggetto di tipo credential che verrà utilizzato per accedere allo storage nello statement di backup. Di seguito il codice di esempio per il backup e il restore del database:
Creazione Windows Azure Storage Account
La creazione di uno storage account per testare la soluzione può essere fatta direttamente dal portale Windows Azure. Una volta completato il wizard è necessario creare un container per salvare i file e copiare la chiave di accesso che SQL Server utilizzerà per i backup remoti
Backup e restore con TSQL
CREATECREDENTIALAzureRemoteBackup
WITHIDENTITY='francedstoragetodelete',
SECRET='myStorageKey';
BACKUPDATABASEAdventureWorksDW2012TO
URL='https://francedstoragetodelete.blob.core.windows.net/backups/adworks.bak'
WITHCREDENTIAL='AzureRemoteBackup',COMPRESSION,STATS= 5;
RESTOREDATABASEAdventureWorksDW2012FROM
URL='https://francedstoragetodelete.blob.core.windows.net/backups/adworks.bak'
WITHCREDENTIAL='AzureRemoteBackup',
STATS= 5,
BLOCKSIZE= 65536,
REPLACE
Backup e restore con SMO
Gli Assembly offerti da SMO consentono di effettuare i backup anche da codice. Nell’esempio di seguito ho creato una semplice Console Application in C# per effettuare backup e restore. Sono presenti due classi, Program che legge i parametri dal file App.Config e clsBackup che si occupa di creare un oggetto Credential (se non esiste) e di fare il backup con il metodo doBackup
e il restore con il metodo doRestore
Per comodità, oltre a copiare il codice qui di seguito, ho caricato il sorgente in un blob storage su Azure : https://datacontent.blob.core.windows.net/pub/SQLBackupToAzure.zip
Per aggiungere le references corrette al progetto Visual Studio è necessario puntare ai file SDK delle Cumulative Update aggiornati, che vengono copiati nella cartella C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies
-- Program
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //FDusing System.Configuration; namespace SQLBackupToWindowsAzure { class Program { privatestaticvoid printMenu() { Console.Clear(); Console.WriteLine("1 - backup \r\n2 - restore \r\n0 - exit"); } staticvoid Main(string[] args) { string ssServer = ConfigurationManager.AppSettings["ServerName"]; string ssStorageName = ConfigurationManager.AppSettings["StorageName"]; string ssStorageKey = ConfigurationManager.AppSettings["StorageKey"]; string ssDatabaseName = ConfigurationManager.AppSettings["DatabaseName"]; string ssCredential = ConfigurationManager.AppSettings["Credential"]; string ssContainer = ConfigurationManager.AppSettings["Container"]; string ssDatabaseBlobFile = ConfigurationManager.AppSettings["DatabaseBlobFile"]; clsBackup myclsBackup = new clsBackup(ssServer, ssDatabaseName, ssStorageName,
ssStorageKey, ssCredential, ssContainer, ssDatabaseBlobFile); short intOptions = -1; int intReturn = 0; printMenu(); string sMessage; while (intOptions != 0) { if (short.TryParse(Console.ReadLine(), out intOptions)) { switch (intOptions) { case 1: { Console.WriteLine("Performing Backup on Windows Azure, please wait"); intReturn = myclsBackup.doBackup(out sMessage); if (intReturn == 0) Console.WriteLine("Backup Completed: " + sMessage); else Console.WriteLine("Error"); Console.ReadLine(); printMenu(); break; } case 2: { Console.WriteLine("Restoring a database from Windows Azure, please wait"); intReturn = myclsBackup.doRestore(); if (intReturn == 0) Console.WriteLine("Restore Completed from " + ssDatabaseBlobFile +
" to " + ssDatabaseName); else Console.WriteLine("Error"); Console.ReadLine(); printMenu(); break; } } } else { printMenu(); } } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.SqlServer.Management.Smo; using System.Data.SqlClient; using Microsoft.SqlServer.Server; namespace SQLBackupToWindowsAzure { class clsBackup { #regionprivate vars privatestring strDatabase; privatestring strStorageName; privatestring strStorageKey; privatestring strServer; privatestring strCredential; privatestring strContainer; privatestring strDatabaseBlobFile; private Server myLocalServer; private Credential myCredential; #endregionprivatevoid myInitialize() { } #region constructors public clsBackup(string sServer, string sDatabase,string sStorageName, string sStorageKey,
string sCredential, string sContainer, string sDatabaseBlobFile) { strServer = sServer; strDatabase = sDatabase; strStorageName = sStorageName; strStorageKey = sStorageKey; strCredential = sCredential; strContainer = sContainer; strDatabaseBlobFile = sDatabaseBlobFile; try { myLocalServer = new Server(strServer); myCredential = new Credential(myLocalServer, strCredential); if (!(myLocalServer.Credentials.Contains(strCredential))) myCredential.Create(strStorageName, strStorageKey); } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregionpublicint doBackup(outstring sBackupFileName) { /* 0 = noError 1 = Error */int intReturn = 0; string desturl = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}_{3}.bak", strStorageName, strContainer, strDatabase, DateTime.Now.ToString()); sBackupFileName = desturl; try { Backup mybackup = new Backup(); mybackup.CredentialName = strCredential; mybackup.Database = strDatabase; mybackup.CompressionOption = BackupCompressionOptions.On; mybackup.Devices.AddDevice(desturl, DeviceType.Url); mybackup.SqlBackup(myLocalServer); } catch (Exception) { intReturn = 1; } return intReturn; } publicint doRestore() { /* 0 = noError 1 = Error */int intReturn = 0; try { Restore myrestore = new Restore(); myrestore.CredentialName = strCredential; myrestore.Database = strDatabase; myrestore.ReplaceDatabase = true; myrestore.BlockSize = 65536; myrestore.Devices.AddDevice(strDatabaseBlobFile, DeviceType.Url); myrestore.SqlRestore(myLocalServer); } catch (Exception) { intReturn = 1; } return intReturn; } } }
Considerazioni sulla versione attuale
- La funzionalità al momento non è disponibile dalla GUI di SQL Server Management Studio
- Ho il limite di 1 Terabyte per il file di backup
- Non posso andare in append sul file, quindi devo scegliere se sovrascrivere il file oppure crearne uno con un nuovo nome
Backup e restore con Powershell
Con SQL Server 2012 SP1 CU4 è possibile creare i backup su Windows Azure Storage anche usando le nuove opzioni del cmdlet Backup-SqlDatabase fornito da Powershell
$url ="https://francedstoragetodelete.blob.core.windows.net/
backups/Advworks_powershell.bak"
$credential ="mycredential"$server ="SQLSERVER:\SQL\[computer]\DEFAULT"CD $server Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $url
-SqlCredential $credential -CompressionOption On
Nei prossimi giorni (tempo permettendo ) cercherò di aggiornare il post con
maggiori informazioni su quest’ultima parte.
Francesco