Configurazione di SQL Server per FILESTREAM

Articolo tecnico su SQL Server
Autore: Paul S. Randal (SQLskills.com)
Revisori tecnici: Alexandru Chirica, Arkadi Brjazovski, Prem Mehra, Joanna Omel,
Mike Ruthruff, Robin Dhamankar
Data di pubblicazione: ottobre 2008
Contesto di applicazione: SQL Server 2008
Riepilogo: in questo white paper viene descritta la funzionalità FILESTREAM di SQL Server
2008, che consente di archiviare i dati BLOB e di accedervi in modo efficiente utilizzando una
combinazione di SQL Server 2008 e del file system NTFS. Vengono illustrate le possibili opzioni
per l'archiviazione BLOB, la configurazione di Windows e SQL Server per l'utilizzo dei dati
FILESTREAM, alcune considerazioni per combinare FILESTREAM con altre funzionalità,
nonché alcune informazioni dettagliate su aspetti dell'implementazione, quali il partizionamento
e le prestazioni.
Questo white paper è destinato ad architetti, professionisti IT e amministratori di database
incaricati della valutazione o dell'implementazione di FILESTREAM. Si presuppone che i lettori
abbiano familiarità con Windows e SQL Server e dispongano di una conoscenza di base dei
concetti relativi ai database, ad esempio le transazioni.
Introduzione
La società moderna è caratterizzata da un'elevatissima velocità di generazione dei dati, con la
conseguente necessità di individuare modi efficienti e controllati di archiviazione e accesso. La scelta
tra le varie tecnologie disponibili per soddisfare tale necessità dipende spesso dalla natura dei dati da
archiviare, che possono essere strutturati, semistrutturati o non strutturati:

I dati strutturati sono dati che possono essere facilmente archiviati in uno schema relazionale,
ad esempio i dati di vendita di una società. Tali dati possono essere archiviati in un database
con una tabella di informazioni sui prodotti venduti dalla società, un'altra di informazioni sui
clienti e un'altra con i dettagli delle vendite dei prodotti ai clienti. È possibile accedere ai dati
e modificarli utilizzando un linguaggio di query avanzato quale Transact-SQL.


I dati semistrutturati sono dati conformi a uno schema approssimativo ma non adatti a essere
archiviati in un set di tabelle di database, ad esempio i dati in cui ogni punto dati potrebbe avere
attributi radicalmente diversi. I dati semistrutturati vengono spesso archiviati utilizzando il tipo
di dati xml nel software di database di Microsoft® SQL Server® e ne viene eseguito l'accesso
utilizzando un linguaggio di query basato su elementi, quale XQuery.
I dati non strutturati possono non adattarsi ad alcuno schema (ad esempio dati crittografati)
o possono essere costituiti da grandi quantità di dati binari (di molti MB o anche GB)
apparentemente privi di schema, ma in realtà con uno schema insito di tipo molto semplice,
ad esempio file di immagine, video in streaming o clip audio. I dati binari sono in questo caso dati
che possono avere qualsiasi valore, non solo quelli esplicitamente digitati. Questi valori di dati
sono comunemente noti come oggetti binari di grandi dimensioni o, più semplicemente, BLOB.
In questo white paper viene descritta la funzionalità FILESTREAM di SQL Server 2008, che consente di
archiviare i dati BLOB e di accedervi in modo efficiente utilizzando una combinazione di SQL Server 2008
e del file system NTFS. Vengono illustrate la funzionalità FILESTREAM, le possibili opzioni per
l'archiviazione BLOB, la configurazione del sistema operativo Windows® e di SQL Server per l'utilizzo dei
dati FILESTREAM, alcune considerazioni per combinare FILESTREAM con altre funzionalità, nonché
informazioni dettagliate su aspetti dell'implementazione, quali partizionamento e prestazioni.
Opzioni per l'archiviazione BLOB
Mentre i dati strutturati e semistrutturati possono essere facilmente archiviati in un database relazionale,
la scelta della posizione di archiviazione dei dati non strutturati o BLOB è più complicata. Nel decidere
dove archiviare i dati BLOB è opportuno tenere presenti le esigenze indicate di seguito.




2
Prestazioni: il modo in cui i dati verranno utilizzati è fondamentale. Se è richiesto un accesso
tramite flusso, l'archiviazione dei dati in un database di SQL Server può risultare più lenta
rispetto all'archiviazione in una posizione esterna come il file system NTFS. Quando si utilizza
l'archiviazione nel file system, i dati vengono letti dal file e passati all'applicazione client
(direttamente o tramite ulteriore buffering). Quando vengono archiviati in un database di SQL
Server, i dati BLOB devono prima essere letti nella memoria di SQL Server (il pool di buffer)
e quindi passati tramite una connessione client all'applicazione client. Questo significa non solo
che i dati vengono sottoposti a un ulteriore passaggio di elaborazione, ma anche che la memoria
di SQL Server viene inutilmente "inquinata" dai dati BLOB, con la possibilità di causare ulteriori
problemi di prestazioni alle operazioni di SQL Server.
Sicurezza: i dati sensibili il cui accesso deve essere strettamente controllato possono essere
archiviati in un database, dove la sicurezza può essere gestita tramite i consueti controlli di
accesso di SQL Server. Se gli stessi dati vengono archiviati nel file system, è necessario
implementare metodi di sicurezza diversi, ad esempio gli elenchi di controllo di accesso (ACL).
Dimensioni dei dati: in base alla ricerca citata più avanti in questo white paper, per i BLOB
inferiori a 256 kilobyte (KB) (come le icone widget) è preferibile l'archiviazione in un database,
mentre per i BLOB superiori a 1 megabyte (MB) è preferibile l'archiviazione all'esterno del
database. Per i BLOB di dimensioni comprese tra 256 KB e 1 MB, la soluzione di archiviazione
più efficiente dipende dal rapporto lettura/scrittura dei dati e dalla frequenza di "sovrascrittura".
Se si archiviano i dati BLOB esclusivamente nel database, ad esempio utilizzando il tipo di dati
varbinary (max), è necessario rispettare il limite di 2 gigabyte (GB) per BLOB.
Accesso client: il protocollo utilizzato dal client per accedere ai dati di SQL Server, ad esempio
ODBC, potrebbe non essere adatto ad applicazioni quali lo streaming di file video di grandi
dimensioni. In questo caso potrebbe essere necessario archiviare i dati nel file system.




Semantica transazionale: se ai dati BLOB sono associati dati strutturati che verranno archiviati
nel database, le modifiche ai dati BLOB dovranno essere conformi alla semantica transazionale
in modo che i due set di dati rimangano sincronizzati. Ad esempio, se viene eseguito il rollback
di una transazione di creazione di dati BLOB e di una riga in una tabella di database, il rollback
deve essere eseguito sia per la creazione dei dati BLOB che per la creazione della riga di tabella.
Questo meccanismo può diventare molto complesso se i dati BLOB sono archiviati nel file system
senza collegamento al database.
Frammentazione dei dati: operazioni frequenti di aggiornamento e sovrascrittura provocano lo
spostamento dei BLOB nell'ambito dei file di database di SQL Server o del file system, a seconda
di dove siano archiviati. In questo caso, se i BLOB sono di grandi dimensioni possono diventare
frammentati, ovvero non archiviati in una parte contigua del disco. Il problema della
frammentazione può essere gestito più facilmente tramite il file system che tramite SQL Server.
Facilità di gestione: una soluzione che include più tecnologie non integrate è più complessa
e costosa di una soluzione integrata in termini di gestione.
Costo: il costo della soluzione di archiviazione dipende dalla tecnologia utilizzata.
Le considerazioni precedenti relative alle dimensioni e alla frammentazione sono basate sul noto articolo
di Microsoft Research in cui si discute se sia meglio archiviare gli oggetti di grandi dimensioni (BLOB)
in un database o in un file system (autori: Gray, Van Ingen e Sears). Il documento contiene ulteriori
informazioni sui possibili compromessi e può essere scaricato al seguente indirizzo:
http://research.microsoft.com/research/pubs/view.aspx?msr_tr_id=MSR-TR-2006-45
Sono disponibili diverse soluzioni per l'archiviazione BLOB, ognuna delle quali presenta vantaggi e
svantaggi rispetto alle esigenze appena descritte. Nella tabella seguente vengono confrontate tre opzioni
comuni per archiviare dati BLOB, inclusa la funzionalità FILESTREAM, in SQL Server 2008.
Aspetto confrontato
Dimensioni massime
BLOB
Prestazioni di flusso
di BLOB di grandi
dimensioni
Sicurezza
File server/file
system
Dimensioni volume
NTFS
Eccellenti
ACL manuali
Soluzione di archiviazione
SQL Server (tramite
FILESTREAM
varbinary(max))
Da 2 GB a 1 byte
Dimensioni volume
NTFS
Scarse
Eccellenti
Integrata
Integrata + ACL
automatici
Basso
Integrata
Coerenza a livello
di dati
Più semplici
Costo per GB
Basso
Alto
Facilità di gestione
Scarsa
Integrata
Integrazione con dati Difficile
Coerenza a livello
strutturati
di dati
Sviluppo
Più complessi
Più semplici
e distribuzione
di applicazioni
Recupero dalla
Eccellente
Scarso
Eccellente
frammentazione
dei dati
Prestazioni di
Eccellenti
Moderate
Scarse
aggiornamenti
piccoli e frequenti
Tabella 1. Confronto delle tecnologie di archiviazione BLOB prima di SQL Server 2008
3
FILESTREAM è l'unica soluzione che offre coerenza transazionale per dati strutturati e non strutturati,
nonché gestione integrata, sicurezza, costi contenuti e prestazioni di flusso eccellenti. L'efficacia della
soluzione si basa sulla separazione dell'archiviazione, nei file di database per i dati strutturati e nel file
system per i dati BLOB non strutturati, e sulla capacità di mantenere la coerenza transazionale tra i due
archivi. Ulteriori informazioni sull'architettura di FILESTREAM vengono fornite nella sezione "Panoramica
di FILESTREAM" seguente.
Panoramica di FILESTREAM
FILESTREAM è una nuova funzionalità di SQL Server 2008 che consente di archiviare i dati strutturati
nel database e i dati non strutturati associati (cioè i dati BLOB) direttamente nel file system NTFS.
Per accedere ai dati BLOB è quindi possibile utilizzare le API di flusso Win32® a prestazioni elevate,
anziché SQL Server, molto meno adatto a questo scopo in termini di prestazioni.
FILESTREAM assicura sempre la coerenza transazionale tra i dati strutturati e non strutturati,
consentendo anche il recupero temporizzato di dati FILESTREAM tramite i backup dei log. La coerenza
viene mantenuta automaticamente da SQL Server e non richiede alcuna logica personalizzata
nell'applicazione. In FILESTREAM la coerenza viene assicurata tramite l'equivalente di un log delle
transazioni del database, con pressoché gli stessi requisiti di gestione (descritti in maggior dettaglio
nella sezione "Configurazione dell'operazione di Garbage Collection di FILESTREAM" più avanti in
questo white paper). La combinazione del log delle transazioni del database e del log delle transazioni
FILESTREAM permette il corretto recupero dei dati FILESTREAM e dei dati strutturati dal punto di vista
transazionale.
Piuttosto che un tipo di dati completamente nuovo, FILESTREAM è un attributo di archiviazione del tipo
di dati varbinary (max) esistente, di cui mantiene la maggior parte del comportamento. La differenza
consiste nella modalità di archiviazione dei dati BLOB, che avviene nel file system anziché nei file di
dati di SQL Server. Poiché FILESTREAM è implementato come colonna varbinary (max) e integrato
direttamente nel motore di database, la maggior parte degli strumenti e delle funzioni di gestione di
SQL Server funziona senza modifiche per i dati FILESTREAM.
Si noti che il comportamento del tipo di dati varbinary (max) normale rimane totalmente invariato in
SQL Server 2008, incluso il limite delle dimensioni di 2 GB. Con l'aggiunta dell'attributo FILESTREAM,
una colonna varbinary (max) diventa di dimensioni praticamente illimitate, anche se in realtà viene posto
un limite dalle dimensioni del volume NTFS sottostante.
I dati FILESTREAM vengono archiviati nel file system in un set di directory NTFS chiamate contenitori di
dati, che corrispondono a filegroup speciali nel database. L'accesso transazionale ai dati FILESTREAM
è controllato da SQL Server e da un driver di filtro del file system installato quando FILESTREAM viene
abilitato a livello di Windows. L'utilizzo di un driver di filtro del file system consente inoltre l'accesso
remoto ai dati FILESTREAM tramite un percorso UNC. In SQL Server viene gestito un collegamento tra
le righe delle tabelle e i file FILESTREAM associati. Ciò significa che l'eliminazione o la ridenominazione
di file FILESTREAM direttamente tramite il file system provoca il danneggiamento del database.
L'utilizzo di FILESTREAM richiede alcune modifiche allo schema delle tabelle di dati (principalmente il
requisito dell'univocità dell'ID di ogni riga) e prevede inoltre alcune restrizioni quando viene combinato
con altre funzionalità (ad esempio l'impossibilità di crittografare i dati FILESTREAM). Ulteriori dettagli su
questo aspetto vengono forniti nella sezione "Configurazione di SQL Server per FILESTREAM" più avanti
in questo white paper.
4
I dati FILESTREAM sono accessibili e modificabili in due modalità: con il modello di programmazione
standard Transact-SQL o tramite le API di flusso Win32. Entrambi i meccanismi assicurano il supporto
completo per le transazioni e per la maggior parte delle operazioni DML, inclusi inserimento,
aggiornamento, eliminazione e selezione. I dati FILESTREAM sono supportati anche nelle operazioni di
manutenzione quali backup, ripristino e verifica della coerenza. L'eccezione principale consiste nel fatto
che non sono supportati aggiornamenti parziali ai dati FILESTREAM. Qualsiasi aggiornamento a un
valore dei dati FILESTREAM viene convertito nella creazione di una nuova copia del file di dati
FILESTREAM. Il file precedente viene rimosso in modo asincrono, come descritto nella sezione
"Configurazione dell'operazione di Garbage Collection di FILESTREAM" più avanti in questo white paper.
Due modelli di programmazione per l'accesso ai dati BLOB
È possibile accedere ai dati archiviati in una colonna FILESTREAM utilizzando le transazioni TransactSQL o le API Win32. In questa sezione vengono fornite alcune informazioni generali sui modelli di
programmazione e su come utilizzarli.
Accesso tramite Transact-SQL
Utilizzando Transact-SQL è possibile effettuare operazioni di inserimento, aggiornamento ed eliminazione
di dati FILESTREAM come indicato di seguito.



I campi FILESTREAM possono essere prepopolati tramite un'operazione di inserimento
(con un valore vuoto o un valore non Null di piccole dimensioni). Tuttavia, le interfacce Win32
costituiscono un modo più efficiente di trasmettere una grande quantità di dati.
Quando i dati FILESTREAM vengono aggiornati, i dati BLOB sottostanti nel file system vengono
modificati. Quando un campo FILESTREAM viene impostato su NULL, i dati BLOB associati al
campo vengono eliminati. Non è possibile utilizzare aggiornamenti a blocchi di Transact-SQL
implementati come UPDATE.Write() per eseguire aggiornamenti parziali ai dati FILESTREAM.
Quando si elimina una riga che contiene dati FILESTREAM oppure si elimina o si tronca una
tabella con tali dati, vengono eliminati anche i dati BLOB sottostanti nel file system. L'effettiva
rimozione fisica dei file FILESTREAM avviene con un processo asincrono eseguito in
background, come illustrato nella sezione "Configurazione dell'operazione di Garbage Collection
di FILESTREAM" più avanti in questo white paper.
Per ulteriori informazioni ed esempi sull'utilizzo di Transact-SQL per accedere ai dati FILESTREAM,
vedere l'argomento "Accedere a dati FILESTREAM con Transact-SQL" nella documentazione online di
SQL Server 2008 (http://msdn.microsoft.com/it-it/library/cc645962.aspx).
Accesso tramite flusso Win32
Per consentire al file system transazionale di accedere ai dati FILESTREAM è disponibile la nuova
funzione intrinseca GET_FILESTREAM_TRANSACTION_CONTEXT() che fornisce il token che
rappresenta la transazione corrente a cui è associata la sessione. È necessario che la transazione sia
stata avviata e non ne sia stato ancora eseguito il commit o il rollback. Ottenendo un token, l'applicazione
associa le operazioni di flusso nel file system di FILESTREAM con una transazione avviata. La funzione
restituisce NULL se non esistono transazioni esplicitamente avviate. È necessario ottenere un token
prima di poter accedere ai file FILESTREAM.
5
In FILESTREAM il motore di database consente di controllare lo spazio dei nomi del file system fisico
dei BLOB. Una nuova funzione intrinseca, PathName, fornisce il percorso UNC logico del BLOB che
corrisponde a ogni campo FILESTREAM nella tabella. L'applicazione utilizza questo percorso logico per
ottenere l'handle Win32 e operare sui dati BLOB mediante normali interfacce del file system Win32.
La funzione restituisce NULL se il valore della colonna FILESTREAM è NULL. Questo meccanismo
evidenzia il fatto che è necessario che un file FILESTREAM sia stato creato in precedenza perché sia
possibile accedervi a livello Win32. Questa operazione viene eseguita come descritto in precedenza.
Il supporto per il flusso Win32 opera nel contesto di una transazione di SQL Server. Dopo l'ottenimento di
un token di transazione e un nome di percorso, è possibile utilizzare l'API OpenSqlFilestream Win32 per
ottenere un handle di file Win32. In alternativa, è possibile utilizzare l'API SqlFileStream gestita. Il relativo
handle può quindi essere utilizzato dalle interfacce di flusso Win32, ad esempio ReadFile() e WriteFile(),
per accedere al file e aggiornarlo mediante il file system. Di nuovo, si noti che i file FILESTREAM non
possono essere direttamente eliminati né rinominati tramite il file system. In caso contrario la coerenza
a livello di collegamento tra il database e il file system andrà persa, cioè il database risulterà
essenzialmente danneggiato.
L'accesso al file system di FILESTREAM consente di modellare un'istruzione Transact-SQL utilizzando
le operazioni di apertura e chiusura dei file. L'istruzione si avvia quando un handle di file viene aperto
e termina quando l'handle viene chiuso. Ad esempio, se un handle di scrittura viene chiuso, qualsiasi
possibile trigger AFTER registrato nella tabella si attiva come se fosse stata completata un'istruzione
UPDATE.
Per ulteriori informazioni ed esempi sull'utilizzo delle API Win32 per accedere ai dati FILESTREAM,
vedere l'argomento "Gestione di dati FILESTREAM mediante Win32" nella documentazione online di
SQL Server 2008 (http://msdn.microsoft.com/it-it/library/cc645940.aspx).
Semantica transazionale
Tutti gli handle di file devono essere chiusi prima del commit o del rollback della transazione. Se un
handle viene lasciato aperto quando viene eseguito il commit di una transazione, il commit avrà esito
negativo e ulteriori operazioni di lettura e scrittura sull'handle provocheranno prevedibilmente un errore.
A quel punto dovrà essere eseguito il rollback della transazione. Allo stesso modo, se il database
o l'istanza del motore di database si arresta, tutti gli handle aperti vengono invalidati.
Ogni volta che un file FILESTREAM viene aperto per un'operazione di scrittura, viene creato un nuovo file
di lunghezza zero e al suo interno viene scritto l'intero valore dei dati FILESTREAM aggiornato. Il file
precedente viene rimosso in modo asincrono, come descritto nella sezione "Configurazione
dell'operazione di Garbage Collection di FILESTREAM" più avanti in questo white paper.
Con FILESTREAM, tramite il motore di database viene assicurata la durabilità della transazione al
commit per i dati BLOB di FILESTREAM modificati accedendo tramite flusso al file system. Questa
operazione viene eseguita utilizzando il log FILESTREAM indicato in precedenza e uno scaricamento
esplicito dei contenuti dei file FILESTREAM su disco.
6
Semantica dell'isolamento
La semantica dell'isolamento è gestita dai livelli di isolamento delle transazioni del motore di database.
Quando si accede ai dati FILESTREAM tramite le API Win32, viene supportato solo il livello di
isolamento READ-COMMITTED. L'accesso tramite Transact-SQL supporta anche i livelli di isolamento
REPEATABLE-READ e SERIALIZABLE. Inoltre, utilizzando l'accesso tramite Transact-SQL è possibile
effettuare letture dirty attraverso il livello di isolamento READ-UNCOMMITTED o l'hint per la query
NOLOCK, ma con tale accesso non verranno visualizzati gli aggiornamenti in transito dei dati
FILESTREAM.
Le operazioni di apertura dell'accesso al file system non attendono alcun blocco, ma danno immediato
esito negativo se non possono accedere ai dati a causa dell'isolamento della transazione. Le chiamate
API di flusso hanno esito negativo con ERROR_SHARING_VIOLATION se l'operazione di apertura non
può continuare a causa della violazione dell'isolamento.
Aggiornamenti parziali
Per consentire l'esecuzione di aggiornamenti parziali, l'applicazione può eseguire un controllo FS del
dispositivo (FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT) per recuperare il contenuto obsoleto
nel file a cui fa riferimento l'handle aperto. Questa operazione può essere eseguita anche utilizzando l'API
SqlFileStream gestita con il flag ReadWrite. In questo modo verrà attivata una copia del contenuto
obsoleto sul lato server, come descritto in precedenza. Per ottenere prestazioni migliori dell'applicazione
ed evitare timeout quando si utilizzano file molto grandi, si consiglia di utilizzare operazioni di I/O asincrone.
Se viene eseguito FSCTL dopo la scrittura sull'handle, l'ultima operazione di scrittura verrà resa
persistente e le scritture precedenti eseguite sull'handle andranno perdute.
Per ulteriori informazioni sugli aggiornamenti parziali, vedere l'argomento "Esecuzione di aggiornamenti
parziali di dati FILESTREAM" nella documentazione online di SQL Server 2008
(http://technet.microsoft.com/it-it/library/cc627407.aspx).
Write-through da client remoti
L'accesso remoto al file system per i dati FILESTREAM è abilitato tramite il protocollo SMB (Server
Message Block). Se il client è remoto, la memorizzazione nella cache delle operazioni di scrittura
dipende dalle opzioni specificate e dall'API utilizzata. Ad esempio, l'impostazione predefinita per le API in
codice nativo è di eseguire il write-through, mentre l'impostazione predefinita per le API gestite prevede
l'utilizzo del buffering. Questa differenza riflette i commenti e i suggerimenti dei clienti sulle varie API e le
modalità di utilizzo nelle versioni CTP provvisorie di SQL Server 2008.
Si consiglia il consolidamento (tramite buffering) delle piccole operazioni di scrittura delle applicazioni in
esecuzione sui client remoti, in modo da effettuare un numero minore di operazioni con dati di dimensioni
superiori. Inoltre, se viene utilizzato il buffering, è consigliabile eseguire uno scaricamento esplicito dal
client prima del commit della transazione.
La creazione di viste con mapping alla memoria (I/O con mapping alla memoria) utilizzando handle
FILESTREAM non è supportata. Se per i dati FILESTREAM viene utilizzato il mapping della memoria,
il motore di database non può assicurare la coerenza e la durabilità dei dati né l'integrità del database.
7
Quando utilizzare FILESTREAM
Anche se presenta molte caratteristiche utili, la tecnologia FILESTREAM non costituisce necessariamente
la scelta ottimale in tutte le situazioni. Come indicato in precedenza, le dimensioni dei dati BLOB
e i modelli di accesso sono i fattori più significativi quando si sceglie se archiviare i dati BLOB
interamente nel database o utilizzando FILESTREAM.
La dimensione influisce sugli aspetti seguenti:


Efficienza con cui è possibile accedere ai dati BLOB utilizzando l'uno o l'altro meccanismo di
archiviazione. Come indicato in precedenza, l'accesso tramite flusso ai dati BLOB di grandi
dimensioni è più efficiente con FILESTREAM, ma gli aggiornamenti parziali sono (potenzialmente
molto) più lenti.
Efficienza di backup della combinazione di dati strutturati e dati BLOB utilizzando l'uno o l'altro
meccanismo di archiviazione. Un backup in cui vengono combinati i file di database di SQL
Server e un numero elevato di file FILESTREAM risulta più lento del backup di soli file di
database di SQL Server per una dimensione totale equivalente. Ciò accade a causa
dell'overhead supplementare del backup di ogni file NTFS (uno per ogni valore di dati
FILESTREAM). L'overhead diventa più significativo quando i file FILESTREAM sono di
dimensioni inferiori, in quanto l'overhead di tempo diventa una percentuale maggiore del tempo
totale di backup per MB di dati.
Nel grafico di esempio seguente viene illustrata la velocità effettiva relativa delle letture locali di
dati BLOB di varie dimensioni utilizzando varbinary (max), FILESTREAM tramite Transact-SQL
e FILESTREAM tramite il file system NTFS. Si può osservare (sulla linea blu) che l'accesso tramite
Win32 ai dati FILESTREAM diventa diverse volte più veloce dell'accesso tramite Transact-SQL ai dati
varbinary (max) man mano che le dimensioni dei dati aumentano. Si noti che le misurazioni della
velocità effettiva sono espresse in megabit al secondo (Mbps).
Figura 1. Prestazioni di lettura di BLOB di diverse dimensioni
8
Le cifre relative a NTFS includono il tempo necessario per avviare una transazione, recuperare il
nome del percorso e il contesto di transazione da SQL Server e aprire un handle Win32 per i dati
FILESTREAM. Ogni test è stato eseguito utilizzando lo stesso computer con quattro core di processore
e un pool di buffer a caldo di SQL Server.
Come fattore ulteriore, va considerato se il client o il livello intermedio possono essere scritti (o modificati)
in modo da utilizzare le API di flusso Win32 oltre al normale accesso a SQL Server. In caso contrario,
FILESTREAM non è appropriato, in quanto le prestazioni migliori vengono ottenute tramite le API di
flusso Win32.
Configurazione di Windows per FILESTREAM
Come per qualsiasi altra distribuzione, prima di distribuire un'applicazione in cui viene utilizzato
FILESTREAM è importante preparare il server Windows che ospiterà il database di SQL Server
e i contenitori di dati FILESTREAM associati. In questa sezione viene descritto come configurare
l'hardware di archiviazione e il file system NTFS in preparazione all'utilizzo di FILESTREAM.
Viene quindi illustrato come abilitare FILESTREAM a livello di Windows.
Selezione e configurazione dell'hardware
Una delle cause più comuni delle scarse prestazioni di un carico di lavoro è una configurazione hardware
inadeguata. Talvolta la causa è la memoria insufficiente, che provoca il sovraccarico del pool di buffer di
SQL Server, talvolta si tratta semplicemente della mancanza nell'hardware di archiviazione delle capacità
di velocità effettiva di I/O necessarie al carico di lavoro. Per le applicazioni in cui viene utilizzato
FILESTREAM per il flusso a prestazioni elevate di dati BLOB tramite le API Win32, la scelta e la
configurazione dell'hardware di archiviazione sono di importanza critica.
Nelle sezioni seguenti vengono descritte alcune procedure consigliate per la scelta e il layout di
archiviazione. Per una discussione più approfondita su questo argomento, vedere il white
paper sulla progettazione dell'archiviazione di un database fisico nella libreria TechNet
(http://www.microsoft.com/technet/prodtechnol/sql/2005/physdbstor.mspx). Dopo avere progettato il
layout ottimale, è consigliabile eseguire il test di carico per convalidare le capacità di prestazioni del
sottosistema di I/O. Questo aspetto viene trattato in dettaglio nell'articolo sulle procedure consigliate
per SQL Server in cui viene illustrata la configurazione del sottosistema di I/O prima della distribuzione
(http://www.microsoft.com/technet/prodtechnol/sql/bestpractice/pdpliobp.mspx) nella libreria TechNet.
Layout dell'archiviazione fisica
Quando si stabilisce l'ubicazione di un contenitore di dati FILESTREAM, è opportuno tenere in
considerazione il relativo carico di lavoro previsto, nonché i carichi di lavoro nei contenitori di dati
o nei file di SQL Server nella medesima ubicazione. Ogni contenitore di dati FILESTREAM potrebbe
dover disporre di un proprio volume, poiché più contenitori di dati con carichi di lavoro pesanti in un
singolo volume potrebbero provocare effetti di contesa di risorse.
Il punto da ricordare è che la valutazione dei carichi di lavoro non va trascurata, perché la collocazione
di tutte le risorse di archiviazione su un unico volume può generare problemi di prestazioni. Il livello di
separazione richiesta dipende dagli specifici scenari dei clienti.
È inoltre possibile creare uno schema di tabella in SQL Server che consente un bilanciamento
approssimativo del carico di dati FILESTREAM tra più volumi. Questa operazione viene descritta nella
sezione "Bilanciamento del carico di dati FILESTREAM".
9
Scelta del livello RAID
I vantaggi offerti dalla tecnologia RAID sono noti e molto è stato scritto sulla scelta di un livello RAID
adeguato ai requisiti dell'applicazione, pertanto in questo white paper non si ripeteranno queste
informazioni. Nel già citato white paper sulla progettazione dell'archiviazione di un database fisico
è inclusa un'eccellente sezione sui livelli RAID e sui relativi criteri di scelta. Qui di seguito viene riportata
una semplice panoramica dei fattori da considerare.
I livelli RAID presentano molti aspetti di differenziazione, in particolare in termini di prestazioni di
lettura/scrittura, resilienza all'errore e costo. Ad esempio, il livello RAID 5 ha un costo relativamente
basso, è in grado di gestire gli errori di una sola unità nella matrice RAID e può essere inadatto per
i carichi di lavoro con intensa attività di scrittura. D'altra parte, il sistema RAID 10 offre eccellenti
prestazioni di lettura e scrittura ed è in grado di gestire gli errori di più unità (in base al livello di mirroring
utilizzato), ma è più costoso, considerando che almeno il 50% delle unità nella matrice RAID
è ridondante. Questi sono i tre fattori principali da considerare nella scelta di un livello RAID. È possibile
scegliere un livello RAID diverso per il volume in cui viene archiviato ciascun database utente e anche un
livello RAID diverso tra il volume in cui sono archiviati i file di dati e il volume in cui sono archiviati i file di
log di un singolo database.
In presenza di un carico di lavoro che richiede il flusso a prestazioni elevate di dati FILESTREAM,
si potrebbe istintivamente scegliere di associare il volume del contenitore di dati FILESTREAM al livello
RAID che fornisce le prestazioni di lettura superiori. Tuttavia, questa scelta potrebbe non assicurare un
elevato grado di resilienza agli errori. D'altra parte, la scelta potrebbe cadere sul livello RAID utilizzato
per gli altri volumi in cui vengono archiviati i dati del database, ma in questo caso potrebbero mancare
i requisiti di prestazioni richiesti dal carico di lavoro.
Il punto che si desidera evidenziare in questo white paper è che la scelta del livello RAID per i volumi dei
contenitori di dati FILESTREAM dovrebbe essere operata dopo aver attentamente valutato tutti i fattori
interessati con i relativi vantaggi e svantaggi e non in base a uno solo di essi.
Scelta dell'interfaccia di unità
Nei database comuni che includono dati BLOB, le dimensioni totali dei dati BLOB possono essere di
molto superiori alle dimensioni totali dei dati strutturati. Quando si implementa una soluzione che prevede
l'archiviazione dei dati FILESTREAM in volumi distinti, è possibile valutare di utilizzare un sistema di
archiviazione più economico per il volume, ad esempio IDE o SATA (da qui in avanti semplicemente
"SATA"), anziché un sistema archiviazione SCSI più costoso. Prima di compiere questa scelta
è importante comprendere vantaggi e svantaggi di ciascun sistema e i possibili compromessi.
In questa sezione viene fornita una panoramica delle diverse caratteristiche dei sistemi SCSI da un
parte e IDE/SATA dall'altra per favorire una scelta informata in base alle prestazioni e all'affidabilità
offerte, nonché ai costi da sostenere.
Capacità e prestazioni
Le unità SATA tendono ad avere maggiore capacità rispetto alle unità SCSI, ma minore velocità di
rotazione (RPM). Anche se sono disponibili unità SATA a 10.000 RPM, la maggior parte di esse offre
5.400 o 7.200 RPM. Le unità SCSI a prestazioni elevate offrono 10.000 e anche 15.000 RPM. Il valore
RPM può essere un'utile metrica di confronto, ma le due cifre realmente significative per un confronto
sono la latenza, cioè il tempo di attesa prima che la testina del disco si trovi nella posizione corretta sulla
superficie del disco, e la velocità media di trasferimento, cioè la quantità di dati che può essere trasferita
dalla/alla superficie del disco al secondo. È inoltre importante che le unità siano in grado di elaborare
modelli complessi di I/O in modo efficiente. Quando si scelgono le unità, verificare che le unità SATA
includano il supporto NCQ (Native Command Queue) e le unità SCSI includano il supporto CTQ
(Command Tag Queue). Tale supporto consente l'elaborazione di più operazioni interleaved di I/O su
disco e assicura così migliori prestazioni.
10
Per riepilogare, le unità SCSI si caratterizzano in genere per migliori valori di latenza e velocità di
trasferimento e quindi offrono migliori prestazioni di flusso, ma potenzialmente hanno un costo più elevato.
Affidabilità
Per garantire affidabilità e funzionalità di recupero attraverso il meccanismo di log write-ahead, in SQL
Server devono essere assicurati ordine di scrittura e durabilità. Per ulteriori informazioni su tali requisiti di
I/O, vedere il white paper sui concetti di base relativi all'I/O in SQL Server nella libreria TechNet
(http://www.microsoft.com/technet/prodtechnol/sql/2005/iobasics.mspx).
Per l'affidabilità, la tecnologia SCSI è migliore della SATA perché, a differenza di quest'ultima, supporta in
modo uniforme la scrittura forzata dei dati sul disco. Ciò avviene attraverso il supporto del processo writethrough, con il quale i dati da scrivere non vengono affatto memorizzati nella cache, oppure attraverso il
supporto dello scaricamento forzato dei contenuti della cache sul disco. In mancanza dell'uno o dell'altro
meccanismo potrebbero verificarsi difficoltà di recupero dopo un problema hardware, software o di
alimentazione. Tutti i tipi di interfaccia possono supportare il collegamento a caldo per consentire le
operazioni di ripristino e nel contempo mantenere la disponibilità.
La funzionalità FILESTREAM si basa su due aspetti che assicurano ordine di scrittura e durabilità:


durabilità dei dati in fase di commit della transazione;
registrazione write-ahead per la creazione e l'eliminazione di file FILESTREAM.
La durabilità dei dati viene ottenuta dal driver del file system di FILESTREAM che esegue uno
scaricamento esplicito dei file che sono stati modificati prima del commit di una transazione (i dettagli
del meccanismo esulano dall'ambito di questo white paper). Ciò assicura che, in caso di interruzione
dell'alimentazione, i dischi senza cache alimentata a batteria non contengano dati FILESTREAM di cui
è stato eseguito il commit, ma non lo scaricamento, che potrebbero andare persi. Se le unità SATA non
supportano un'operazione di scaricamento forzato, la recuperabilità può essere pregiudicata e i dati
possono andare persi.
La registrazione write-ahead si basa sulla coerenza dei metadati NTFS, a sua volta basata sull'affidabilità
delle unità sottostanti. Per le unità SCSI il problema non esiste, ma se le unità SATA non supportano lo
scaricamento forzato può verificarsi la perdita di alcune delle modifiche ai metadati in caso di interruzione
dell'alimentazione. Questa situazione può dare adito a una serie di scenari:



11
È impossibile recuperare il file system NTFS e il volume non può essere montato, ovvero il
contenitore di dati FILESTREAM è essenzialmente offline.
Il file system NTFS viene recuperato ma le modifiche ai metadati NTFS vengono perse
e SQL Server non è in grado di eseguire il rollback di una transazione senza commit con cui
viene eseguito un inserimento di dati FILESTREAM, ovvero si verifica una dispersione di dati
FILESTREAM.
Il file system NTFS viene recuperato ma le modifiche ai metadati NTFS vengono perse
e SQL Server non è in grado di eseguire il rollback di una transazione senza commit con
cui viene eseguita un'eliminazione di dati FILESTREAM, ovvero si verifica una perdita di dati
FILESTREAM.
Si noti che in tutti e tre gli scenari la situazione equivale effettivamente al caso in cui i dati BLOB vengono
archiviati esternamente al database in un volume NTFS con unità SATA sottostanti che non supportano
la forzatura dei dati sul disco. L'utilizzo di FILESTREAM in un volume con unità SATA sottostanti in
questo caso è effettivamente preferibile all'archiviazione dei dati BLOB in file NTFS RAW sullo stesso
volume, poiché la coerenza a livello di collegamenti di FILESTREAM fornisce un meccanismo per rilevare
la presenza di questi problemi (tramite l'esecuzione di DBCC CHECKDB sul database).
In sintesi, i dati FILESTREAM possono essere archiviati in modo affidabile in volumi con risorse di
archiviazione SATA sottostanti, purché le unità SATA supportino la forzatura dei dati sul disco tramite lo
scaricamento della cache.
Configurazione di NTFS
Anche il sottosistema di I/O più accuratamente progettato in esecuzione su hardware a prestazioni
elevate potrebbe non funzionare nel modo previsto se il file system (in questo caso NTFS) non
è configurato correttamente. In questa sezione vengono descritte alcune opzioni di configurazione
che possono influire su un carico di lavoro che include dati FILESTREAM.
Per una panoramica più completa di NTFS, vedere l'articolo di riferimento tecnico a NTFS
(http://technet.microsoft.com/it-it/library/cc758691.aspx) e l'articolo sull'utilizzo dei file system
(http://technet.microsoft.com/it-it/library/bb457112.aspx) nella libreria TechNet.
Ottimizzazione delle prestazioni di NTFS
La configurazione predefinita di NTFS non prevede la gestione di un carico di lavoro a prestazioni
elevate con decine di migliaia di file in una singola directory del file system, ovvero lo scenario di
FILESTREAM. È necessario configurare due opzioni NTFS per facilitare le prestazioni di FILESTREAM.
È particolarmente importante impostare queste opzioni in modo corretto prima dell'organizzazione di
qualsiasi attività di benchmarking di prestazioni. In caso contrario, i risultati non saranno rappresentativi
delle reali prestazioni di FILESTREAM.
La prima opzione di configurazione da disabilitare riguarda il processo di generazione di nomi in formato
8.3 quando vengono creati nuovi file o rinominati file esistenti. Questo processo genera un nome
secondario per ogni file al solo fine della compatibilità con le precedenti applicazioni a 16 bit. L'algoritmo
genera un nuovo nome in formato 8.3, ma per assicurarne l'univocità deve analizzare tutti i nomi file
in formato 8.3 esistenti nella directory. Poiché il numero di file nella directory tende ad aumentare
(generalmente oltre i 300.000), questo processo richiede un tempo sempre maggiore. Il tempo
necessario per creare un file aumenta a sua volta, a discapito delle prestazioni, pertanto la disabilitazione
di questo processo può consentire un significativo miglioramento delle prestazioni. Per disabilitare il
processo, digitare il comando seguente al prompt dei comandi e quindi riavviare il computer:
fsutil behavior set disable8dot3 1
Nota: con questa opzione la generazione di nomi in formato 8.3 viene disabilitata in tutti i volumi NTFS
sul server. Se i volumi vengono utilizzati da applicazioni a 16 bit, possono verificarsi problemi dopo la
modifica di questo comportamento.
12
La seconda opzione da disabilitare riguarda l'aggiornamento dell'ultima data/ora di accesso a un file.
Se il carico di lavoro accede brevemente a più file, viene spesa una quantità di tempo sproporzionata
solo per aggiornare l'ultima data/ora di accesso a ogni file. Anche la disabilitazione di questa opzione può
consentire un notevole miglioramento delle prestazioni. Per disabilitare il processo, digitare il comando
seguente al prompt dei comandi e quindi riavviare il computer:
fsutil behavior set disablelastaccess 1
Dimensione del cluster
A tutti i file system di Windows è associato il concetto di "cluster", ovvero l'unità di allocazione dello
spazio su disco. Poiché un cluster è la più piccola quantità allocabile di spazio su disco, in presenza
di file molto piccoli alcuni cluster potrebbero rimanere inutilizzati (essenzialmente sprecati). Pertanto la
dimensione del cluster è in genere sufficientemente piccola da evitare che i file di piccole dimensioni
sprechino spazio su disco.
Per i file di grandi dimensioni possono essere allocati molti cluster, mentre per i file che aumentano
di dimensioni nel tempo possono essere man mano assegnati più cluster. Se le dimensioni di un file
aumentano notevolmente, ma in piccoli blocchi, è probabile che i cluster allocati non siano contigui sul
disco, cioè siano "frammenti". Ciò significa che, più piccoli sono i cluster, più un file che aumenta di
dimensioni risulterà frammentato.
La dimensione del cluster deve pertanto essere un compromesso tra lo spreco di spazio e la riduzione
della frammentazione. Per ulteriori informazioni sulle diverse dimensioni dei cluster nei file system di
Windows, vedere l'articolo della Knowledge Base "Dimensioni di cluster predefinite per NTFS, FAT ed
exFAT" (http://support.microsoft.com/kb/140365).
Per utilizzare FILESTREAM, la dimensione consigliata delle singole unità di dati BLOB è di almeno 1 MB.
In questo caso, è consigliabile che la dimensione del cluster NTFS per il volume del contenitore di dati
FILESTREAM sia impostata su 64 KB per ridurre la frammentazione. Questa operazione deve essere
eseguita manualmente poiché l'impostazione predefinita per i volumi NTFS fino a 2 terabyte (TB) è di
4 KB. A tale scopo è possibile utilizzare l'opzione /A nel comando di formattazione. Al prompt dei
comandi, ad esempio, digitare:
format F: /FS:NTFS /V:MyFILESTREAMContainer /A:64K
Questa impostazione deve essere combinata con ampie dimensioni di buffer, come descritto nella
sezione "Considerazioni sull'ottimizzazione e sul benchmarking delle prestazioni" più avanti in questo
white paper.
Gestione della frammentazione
Come descritto in precedenza, molti file che in un volume aumentano di dimensioni diventano
frammentati. Ciò significa che la raccolta dei cluster allocati a un file non è contigua. Quando il file viene
letto in sequenza, le testine del disco sottostante devono leggere tutti i cluster in sequenza, pertanto
è probabile che debbano leggere diverse parti del disco. Anche se i file non aumentano di dimensioni
dopo essere stati creati, se vengono creati su un volume in cui lo spazio disponibile non si trova in un
unico blocco contiguo, è possibile che vengano frammentati immediatamente, in assenza di un numero
sufficiente di cluster contigui per ospitarli.
13
La frammentazione riduce le prestazioni di lettura sequenziale rispetto a condizioni di frammentazione
assente o scarsa. Il problema è molto simile a quello della frammentazione degli indici in un database che
rallenta le prestazioni di analisi dell'intervallo di query.
È pertanto necessario che la frammentazione venga rimossa periodicamente tramite l'utilizzo di uno
strumento di deframmentazione, in modo da mantenere un buon livello di prestazioni di lettura
sequenziale. Inoltre, se il volume da utilizzare per ospitare il contenitore di dati FILESTREAM è già stato
utilizzato in precedenza o contiene ancora altri dati, è opportuno controllare ed eventualmente correggere
il livello di frammentazione.
Compressione
I dati archiviati in NTFS possono essere compressi per risparmiare spazio su disco. Ciò comporta tuttavia
un maggiore utilizzo della CPU per comprimere e decomprimere i dati quando vengono rispettivamente
scritti o letti. Inoltre, la compressione non è utile se i dati non sono essenzialmente comprimibili.
Ad esempio, i dati casuali, i dati crittografati o i dati che sono già stati compressi non vengono compressi
in modo efficiente, ma vengono comunque elaborati tramite l'algoritmo di compressione di NTFS,
provocando un overhead della CPU.
Per questi motivi, la scelta della compressione va fatta solo quando i dati possono essere compressi in
modo significativo e l'utilizzo aggiuntivo di CPU non provoca una riduzione delle prestazioni del carico di
lavoro. Si noti anche che la compressione può essere abilitata solo se la dimensione del cluster NTFS
è al massimo di 4.096 byte.
La compressione può essere abilitata quando il volume del contenitore di dati FILESTREAM viene
formattato, utilizzando l'opzione /C del comando di formattazione. Ad esempio:
format F: /FS:NTFS /V:MyFILESTREAMContainer /A:4096 /C
È possibile abilitare per la compressione anche un volume esistente, utilizzando i passaggi seguenti:
1. In Risorse del computer o in Esplora risorse fare clic con il pulsante destro del mouse sul volume
da comprimere o decomprimere.
2. Fare clic su Proprietà per visualizzare la finestra di dialogo Proprietà.
3. Nella scheda Generale selezionare o deselezionare la casella di controllo Comprimi unità per
risparmiare spazio su disco, quindi fare clic su OK.
4. Nella finestra di dialogo Conferma cambiamenti attributi scegliere se applicare la
compressione all'intero volume o solo alla cartella radice.
14
Questa procedura è illustrata nella figura seguente.
Figura 2. Compressione di un volume esistente tramite Esplora risorse
Gestione dello spazio
Sebbene più contenitori di dati FILESTREAM possano essere collocati in un singolo volume NTFS,
per vari motivi è preferibile impostare un mapping di tipo 1:1 tra contenitori di dati e volumi NTFS. Oltre
al rischio di potenziali contese di risorse dipendenti dal carico di lavoro, non è possibile gestire l'utilizzo
dello spazio del contenitore di dati FILESTREAM dall'interno di SQL Server, pertanto, se necessario,
vanno utilizzate le quote disco NTFS. Le quote disco vengono rilevate per utente e per volume, quindi
la presenza di più contenitori di dati FILESTREAM in un singolo volume rende difficile stabilire quale
contenitore stia utilizzando più spazio su disco. Si noti che tutti i file FILESTREAM vengono creati con
l'account del servizio SQL Server. Se questa impostazione viene modificata, si inizierà a imputare lo
spazio su disco al nuovo account del servizio.
È disponibile un solo driver di filtro del file system FILESTREAM per ogni volume NTFS con un
contenitore di dati FILESTREAM e uno per ogni versione di SQL Server con un contenitore di dati
FILESTREAM nel volume. Ogni driver di filtro è responsabile della gestione di tutti i contenitori di dati
FILESTREAM per il volume specificato, per tutte le istanze in cui viene utilizzata una determinata
versione di SQL Server.
15
Ad esempio, un volume che ospita tre contenitori di dati FILESTREAM, uno per ognuna delle tre istanze
di SQL Server 2008, disporrà di un solo driver di filtro del file system FILESTREAM di SQL Server 2008.
Sicurezza
È necessario soddisfare due requisiti di sicurezza per utilizzare la funzionalità FILESTREAM.
Innanzitutto, SQL Server deve essere configurato per la sicurezza integrata. In secondo luogo,
se si intende utilizzare l'accesso remoto, la porta SMB (445) deve essere abilitata nei sistemi firewall,
analogamente a quanto richiesto per il normale accesso condiviso remoto. Per ulteriori informazioni,
vedere l'articolo della Knowledge Base relativo alla panoramica sui servizi e ai requisiti delle porte di
rete per Windows Server (http://support.microsoft.com/kb/832017).
Considerazioni sul software antivirus
Il software antivirus è ormai presente in ogni ambiente moderno. In FILESTREAM non è prevista la
possibilità di impedire al software antivirus di analizzare i file nel contenitore di dati FILESTREAM,
dal momento che questo comporterebbe problemi di sicurezza. Normalmente, i criteri impostati nei
programmi antivirus determinano l'azione da intraprendere sui file ritenuti certamente o probabilmente
contaminati: eliminare il file o limitarne l'accesso (mettendolo nella cosiddetta "quarantena"). In entrambi
i casi, l'accesso ai dati BLOB nel file interessato viene impedito e in SQL Server il file risulterà eliminato.
È consigliabile che il software antivirus venga impostato in modo tale da mettere i file in quarantena
e non eliminarli. In SQL Server è possibile utilizzare DBCC CHECKDB per individuare quali file risultano
mancanti e l'amministratore di Windows può correlare i nomi dei file al log del software antivirus ed
eseguire azioni correttive.
Abilitazione di FILESTREAM in Windows
FILESTREAM è una funzionalità ibrida la cui abilitazione richiede l'intervento sia dell'amministratore di
Windows che dell'amministratore di SQL Server. Il duplice intervento è necessario per mantenere la
separazione delle responsabilità tra i due amministratori, soprattutto se l'amministratore di SQL Server
non è anche l'amministratore di Windows. L'abilitazione di FILESTREAM a livello di Windows comporta
l'installazione di un driver di filtro del file system, operazione per la quale sono necessari privilegi di cui
dispone solo un amministratore di Windows.
A livello di Windows, la funzionalità FILESTREAM viene abilitata durante l'installazione di SQL Server
2008 o tramite l'esecuzione di Gestione configurazione SQL Server. Di seguito sono elencati i passaggi
da eseguire:
1.
2.
3.
4.
5.
6.
16
Nel menu Start scegliere Tutti i programmi, Microsoft SQL Server 2008, Strumenti di
configurazione, quindi fare clic su Gestione configurazione SQL Server.
Nell'elenco dei servizi fare clic con il pulsante destro del mouse su Servizi di SQL Server,
quindi scegliere Apri.
Nello snap-in Gestione configurazione SQL Server individuare l'istanza di SQL Server in
cui si desidera abilitare FILESTREAM.
Fare clic con il pulsante destro del mouse sull'istanza, quindi scegliere Proprietà.
Nella finestra di dialogo Proprietà di SQL Server fare clic sulla scheda FILESTREAM.
Selezionare la casella di controllo Abilita FILESTREAM per l'accesso Transact-SQL.
7.
8.
9.
Se si desidera leggere e scrivere dati FILESTREAM da Windows, fare clic su Abilita
FILESTREAM per l'accesso tramite il flusso di I/O dei file. Nella casella Nome
condivisione di Windows immettere il nome della condivisione di Windows.
Se i client remoti devono accedere ai dati FILESTREAM archiviati in tale condivisione,
selezionare Consenti ai client remoti l'accesso tramite flusso ai dati FILESTREAM.
Fare clic su Applica.
Nella figura seguente viene illustrata la scheda FILESTREAM descritta nella procedura.
Figura 3. Configurazione di FILESTREAM tramite Gestione configurazione SQL Server
Questa procedura deve essere eseguita per ogni istanza di SQL Server nella quale verrà utilizzata la
funzionalità FILESTREAM, prima che tale funzionalità possa essere utilizzata da SQL Server. Si noti che
in questa fase non è richiesta la specificazione di contenitori di dati FILESTREAM, che viene invece
effettuata al momento della creazione di un filegroup FILESTREAM in un database dopo l'abilitazione di
FILESTREAM in SQL Server.
17
Si noti che è possibile disabilitare l'accesso FILESTREAM a livello di Windows anche quando la
funzionalità è abilitata in SQL Server. In questo caso, dopo che l'istanza di SQL Server viene riavviata,
tutti i dati FILESTREAM risulteranno non disponibili. Verrà visualizzato il seguente avviso.
Figura 4. Avviso visualizzato a seguito della disabilitazione di FILESTREAM tramite Gestione
configurazione SQL Server
Configurazione di SQL Server per FILESTREAM
Ogni istanza di SQL Server in cui viene utilizzata la funzionalità FILESTREAM deve essere configurata
separatamente, sia a livello di Windows che a livello di SQL Server. Dopo l'abilitazione di FILESTREAM,
è necessario configurare un database per l'archiviazione dei dati FILESTREAM e solo successivamente
è possibile definire tabelle che includano colonne FILESTREAM. In questa sezione viene descritto
come configurare FILESTREAM a livello di SQL Server e come creare database e tabelle abilitati per
FILESTREAM. Viene inoltre illustrata l'interazione di FILESTREAM con altre funzionalità di SQL Server
2008.
Considerazioni sulla sicurezza
FILESTREAM richiede l'utilizzo della sicurezza integrata, cioè l'autenticazione di Windows. Quando
un'applicazione che utilizza Win32 tenta di accedere ai dati FILESTREAM, l'utente di Windows viene
convalidato tramite SQL Server. Se l'utente dispone dell'accesso tramite Transact-SQL ai dati
FILESTREAM, l'accesso verrà concesso anche a livello Win32, purché il token di transazione venga
ottenuto nel contesto di sicurezza dell'utente di Windows che esegue l'apertura del file.
Il requisito dell'autenticazione di Windows deriva dalla natura delle API di I/O dei file di Windows.
L'unico modo per passare l'identità del client dall'applicazione client a SQL Server durante un'operazione
di I/O dei file consiste nell'utilizzare il token di Windows associato al thread del client.
Quando il contenitore di dati FILESTREAM viene creato, viene automaticamente protetto in modo che
solo l'account del servizio SQL Server e i membri del gruppo builtin/Administrators possano accedere
all'albero di directory del contenitore di dati. È necessario prestare attenzione a non modificare mai il
contenuto del contenitore di dati se non tramite i metodi transazionali supportati, poiché l'utilizzo di altri
metodi provocherebbe danni al contenitore.
Abilitazione di FILESTREAM in SQL Server
Il secondo passaggio dell'abilitazione di FILESTREAM viene eseguito nell'istanza di SQL Server 2008.
Questo passaggio non deve essere eseguito fino a quando FILESTREAM non è stato abilitato a livello di
Windows e il volume NTFS in cui verranno archiviati i dati FILESTREAM non è stato preparato in modo
adeguato (come descritto nella sezione "Configurazione di Windows per FILESTREAM").
18
L'accesso a FILESTREAM viene controllato in SQL Server tramite sp_configure per impostare l'opzione
di configurazione filestream_access_level su uno di tre possibili valori, indicati di seguito.



0 - disabilita il supporto di FILESTREAM per l'istanza corrente
1 - abilita FILESTREAM solo per l'accesso tramite Transact-SQL
2 - abilita FILESTREAM per l'accesso tramite Transact-SQL e tramite flusso Win32
Nell'esempio seguente viene illustrata l'abilitazione di FILESTREAM per l'accesso tramite Transact-SQL
e tramite flusso Win32.
EXEC sp_configure filestream_access_level, 2;
GO
RECONFIGURE;
GO
L'istruzione RECONFIGURE è necessaria per rendere effettivo il valore appena configurato. Si noti che
se FILESTREAM non è stato abilitato a livello di Windows, non verrà abilitato a livello di SQL Server
quando il codice precedente viene eseguito. Il valore configurato corrente può essere trovato utilizzando il
codice seguente:
EXEC sp_configure filestream_access_level;
GO
Se FILESTREAM non è configurato a livello di Windows, il valore "config_value" nell'output di sp_configure
sarà diverso (cioè 0) dal valore "run_value" dopo l'esecuzione dell'istruzione RECONFIGURE.
Creazione di un database abilitato per FILESTREAM
Una volta abilitato FILESTREAM sia a livello di Windows che a livello di SQL Server, è possibile definire
un contenitore di dati FILESTREAM. A tale scopo, è necessario definire un filegroup FILESTREAM in un
database. Tra i filegroup FILESTREAM e i contenitori di dati FILESTREAM esiste un mapping di tipo 1:1.
È possibile definire un filegroup FILESTREAM al momento della creazione di un database oppure crearlo
separatamente utilizzando un'istruzione ALTER DATABASE. Nell'esempio seguente viene creato un
filegroup FILESTREAM in un database esistente.
ALTER DATABASE Production ADD
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM;
GO
19
La clausola CONTAINS FILESTREAM è necessaria per distinguere il nuovo filegroup dai normali
filegroup del database. Se la funzionalità FILESTREAM è disabilitata, l'istruzione avrà esito negativo con
l'errore seguente:
Messaggio 5591, livello 16, stato 3, riga 1
La funzionalità FILESTREAM è disabilitata.
Se FILESTREAM è abilitato a livello di Windows e a livello di SQL Server, il filegroup verrà creato.
A questo punto, il contenitore di dati FILESTREAM viene definito aggiungendo un singolo file al filegroup.
Il nome del percorso specificato è quello della directory che verrà creata come radice del contenitore
di dati. L'intero nome del percorso, escluso il nome della directory finale, deve essere già esistente.
Nell'esempio successivo viene definito il contenitore di dati per il filegroup FileStreamGroup1 creato in
precedenza.
ALTER DATABASE Production ADD FILE (
NAME = FSGroup1File,
FILENAME = 'F:\Production\FSDATA')
TO FILEGROUP FileStreamGroup1;
GO
A questo punto verrà creata la directory FSDATA, che sarà vuota tranne che per due elementi:


Il file filestream.hdr, che contiene i metadati FILESTREAM per il contenitore di dati.
La directory $FSLOG, che è l'equivalente FILESTREAM del log delle transazioni di un database.
Si noti che un database può includere più filegroup FILESTREAM. Ciò può risultare utile per separare
l'archiviazione BLOB di più tabelle nel database.
Creazione di una tabella per archiviare i dati FILESTREAM
Quando il database dispone di un filegroup FILESTREAM, è possibile creare tabelle contenenti colonne
FILESTREAM. Come indicato in precedenza, una colonna FILESTREAM è una colonna varbinary (max)
che dispone dell'attributo FILESTREAM. Il codice seguente crea una tabella con una sola colonna
FILESTREAM.
USE Production;
GO
20
CREATE TABLE DocumentStore (
DocumentID INT IDENTITY PRIMARY KEY,
Document VARBINARY (MAX) FILESTREAM NULL,
DocGUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL
UNIQUE DEFAULT NEWID ())
FILESTREAM_ON FileStreamGroup1;
GO
Una tabella può includere più colonne FILESTREAM, ma i dati di tutte le colonne FILESTREAM in una
tabella devono essere archiviati nello stesso filegroup FILESTREAM. Se la clausola FILESTREAM_ON
non viene specificata, verrà utilizzato il filegroup FILESTREAM impostato come predefinito. Questa
potrebbe non essere la migliore configurazione e provocare problemi di prestazioni.
Una volta creata la tabella, il contenitore di dati FILESTREAM conterrà un'altra directory, corrispondente
alla tabella, con una sottodirectory che corrisponde alla colonna FILESTREAM nella tabella.
La sottodirectory conterrà i file di dati una volta che i dati vengono immessi nella tabella. La struttura
di directory dipenderà dal numero di colonne FILESTREAM nella tabella e dal fatto che la tabella sia
o meno partizionata.
Si noti che, per includere una o più colonne FILESTREAM, una tabella deve disporre anche di una
colonna del tipo di dati uniqueidentifier con l'attributo ROWGUIDCOL. Questa colonna non deve
consentire valori Null e deve avere un vincolo a colonna singola UNIQUE o PRIMARY KEY. Il valore
GUID della colonna deve essere specificato tramite un'applicazione al momento dell'inserimento dei
dati o tramite un vincolo DEFAULT che utilizza la funzione NEWID() (o NEWSEQUENTIALID() se
è configurata la replica di tipo merge, come indicato nella sezione "Combinazioni di funzionalità e relative
restrizioni" più avanti).
Per ulteriori informazioni sui dettagli e sulle restrizioni relativi allo schema e alle opzioni di tabella richiesti,
vedere l'argomento "CREATE TABLE (Transact-SQL)" nella documentazione online di SQL Server 2008
(http://msdn.microsoft.com/it-it/library/ms174979.aspx).
Configurazione dell'operazione di Garbage Collection di FILESTREAM
I file di dati FILESTREAM nel contenitore di dati FILESTREAM non possono essere aggiornati
parzialmente. Ciò significa che qualsiasi modifica ai dati BLOB nella colonna FILESTREAM comporta la
creazione di un intero nuovo file di dati FILESTREAM. Il file precedente deve essere mantenuto a scopo
di recupero finché non è più necessario. I file che rappresentano dati FILESTREAM eliminati o gli
inserimenti di dati FILESTREAM di cui è stato eseguito il rollback vengono mantenuti in modo analogo.
I file non più necessari vengono rimossi tramite un processo di Garbage Collection. Questo processo
è automatico, a differenza di quanto accade in Windows SharePoint® Services, dove le operazioni di
Garbage Collection devono essere implementate manualmente nell'archivio BLOB esterno.
21
Per tutte le operazioni sui file FILESTREAM viene eseguito il mapping a un numero di sequenza del file
di log (LSN) nel log delle transazioni del database. Se il log delle transazioni è stato troncato dopo l'LSN
dell'operazione FILESTREAM, il file non è più necessario e può essere sottoposto all'operazione di
Garbage Collection. Pertanto, qualsiasi circostanza che possa impedire il troncamento del log delle
transazioni può impedire anche l'eliminazione fisica di un file FILESTREAM. Alcuni esempi:



I backup del log non sono stati eseguiti, nel modello di recupero FULL o BULK_LOGGED.
È presente una transazione attiva con esecuzione prolungata.
Il processo di lettura log repliche non è stato eseguito.
L'operazione di Garbage Collection di FILESTREAM è un'attività in background che viene attivata dal
processo di checkpoint del database. Un checkpoint viene eseguito automaticamente quando è stato
generato un log delle transazioni di lunghezza sufficiente. Per ulteriori informazioni, vedere l'argomento
"Relazione tra i checkpoint e la parte attiva del log" nella documentazione online di SQL Server 2008
(http://msdn.microsoft.com/it-it/library/ms189573.aspx). Dato che le operazioni sui file FILESTREAM
vengono registrate a livello minimo nel log delle transazioni del database, può trascorrere del tempo
prima che il numero dei record generati nel log delle transazioni attivi un processo di checkpoint e
venga eseguita l'operazione di Garbage Collection. Se questo diventa un problema, è possibile forzare
l'operazione di Garbage Collection utilizzando l'istruzione CHECKPOINT.
Considerazioni sul partizionamento
Se la tabella contenente i dati FILESTREAM è partizionata, la clausola FILESTREAM_ON deve
specificare uno schema di partizionamento che includa i filegroup FILESTREAM e si basi sulla
funzione di partizionamento della tabella. Tale operazione è necessaria perché il normale schema
di partizionamento include filegroup normali che non possono essere utilizzati per archiviare dati
FILESTREAM. La definizione di tabella (in un'istruzione CREATE TABLE o CREATE CLUSTERED
INDEX … WITH DROP_EXISTING) specifica quindi entrambi gli schemi di partizionamento.
Con lo schema di partizionamento di FILESTREAM è possibile specificare che per tutte le partizioni
sia eseguito il mapping a un singolo filegroup, ma questa impostazione non è consigliabile poiché può
provocare problemi di prestazioni.
Questa sintassi è illustrata nell'esempio seguente, appositamente formulato:
CREATE PARTITION FUNCTION DocPartFunction (INT)
AS RANGE RIGHT FOR VALUES (100000, 200000);
GO
CREATE PARTITION SCHEME DocPartScheme AS
PARTITION DocPartFunction TO (Data_FG1, Data_FG2, Data_FG3);
GO
22
CREATE PARTITION SCHEME DocFSPartScheme AS
PARTITION DocPartFunction TO (FS_FG1, FS_FG2, FS_FG3);
GO
CREATE TABLE DocumentStore (
DocumentID INT IDENTITY PRIMARY KEY,
Document VARBINARY (MAX) FILESTREAM NULL,
DocGUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL
UNIQUE DEFAULT NEWID () ON Data_FG1)
ON DocPartScheme (DocumentID)
FILESTREAM_ON DocFSPartScheme;
GO
Si noti che per utilizzare la colonna DocumentID come colonna di partizionamento, è necessario che
l'indice non cluster sottostante che applica il vincolo UNIQUE nel DocGUID sia esplicitamente posizionato
su un filegroup, in modo che la colonna DocumentID possa fungere da colonna di partizionamento. Ciò
significa che il cambio di partizione è possibile solo se i vincoli UNIQUE vengono disabilitati prima di eseguire
tale cambio, in quanto si tratta di indici non allineati, per poi essere nuovamente abilitati in seguito.
Proseguendo con l'esempio precedente, il codice seguente crea una tabella e quindi tenta un cambio di
partizione.
CREATE TABLE NonPartitionedDocumentStore (
DocumentID INT IDENTITY PRIMARY KEY,
Document VARBINARY (MAX) FILESTREAM NULL,
DocGUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL
UNIQUE DEFAULT NEWID ());
GO
ALTER TABLE DocumentStore SWITCH PARTITION 2 TO NonPartitionedDocumentStore;
GO
23
Il cambio di partizione non riesce con il messaggio seguente:
Messaggio 7733, livello 16, stato 4, riga 1
Istruzione'ALTER TABLE SWITCH' non riuscita. L'elemento tabella
'FileStreamTestDB.dbo.DocumentStore' è partizionato mentre l'elemento
'UQ_Document_8CC1617F60ED59' non è partizionato.
Se si disabilita l'indice univoco nella tabella di origine e si riprova, si ottiene il codice seguente:
ALTER INDEX [UQ__Document__8CC331617F60ED59] ON DocumentStore DISABLE;
GO
ALTER TABLE FileStreamTest3 SWITCH PARTITION 2 TO NonPartitionedFileStreamTest3;
GO
Anche questa operazione non riesce, con il messaggio seguente:
Messaggio 4947, livello 16, stato 1, riga 1
Istruzione ALTER TABLE SWITCH non riuscita. Nella tabella di origine
'FileStreamTestDB.dbo.DocumentStore' non esiste un indice identico all'indice
'UQ_NonParti_8CC3316103317E3D' nella tabella di destinazione
'FileStreamTestDB.dbo.NonPartitionedDocumentStore'.
Gli indici univoci devono essere disabilitati sia nelle tabelle partizionate che non partizionate prima che il
cambio possa continuare.
ALTER INDEX [UQ__NonParti__8CC3316103317E3D] ON NonPartitionedDocumentStore DISABLE;
GO
ALTER TABLE DocumentStore SWITCH PARTITION 2 TO NonPartitionedDocumentStore;
GO
ALTER INDEX [UQ__NonParti__8CC3316103317E3D] ON
NonPartitionedDocumentStore REBUILD WITH (ONLINE = ON);
24
ALTER INDEX [UQ__Document__8CC331617F60ED59] ON
NonPartitionedDocumentStore REBUILD WITH (ONLINE = ON);
GO
Ulteriori informazioni sul partizionamento dei dati FILESTREAM verranno incluse in un imminente white
paper sul partizionamento in SQL Server 2008.
Bilanciamento del carico dei dati FILESTREAM
Il partizionamento può essere utilizzato anche per creare uno schema di tabella che consenta un
bilanciamento approssimativo del carico dei dati FILESTREAM tra più volumi. Ciò può essere
consigliabile per vari motivi, ad esempio per restrizioni hardware o per consentire l'archiviazione in volumi
diversi delle aree sensibili di una tabella.
Il codice seguente mostra una funzione e uno schema di partizionamento basati sulla colonna
uniqueidentifier che distribuisce i dati FILESTREAM in modo efficiente tra 16 volumi, effettuando nel
contempo lo striping dei dati strutturati in due filegroup.
USE master;
GO
-- Creare il database
CREATE DATABASE Production ON PRIMARY
(NAME = 'Production', FILENAME = 'E:\Production\Production.mdf'),
FILEGROUP DataFilegroup1
(NAME = 'Data_FG1', FILENAME = 'F:\Production\Data_FG1.ndf'),
FILEGROUP DataFilegroup2
(NAME = 'Data_FG2', FILENAME = 'G:\Production\Data_FG2.ndf'),
FILEGROUP FSFilegroup0 CONTAINS FILESTREAM
(NAME = 'FS_FG0', FILENAME = 'H:\Production\FS_FG0'),
FILEGROUP FSFilegroup1 CONTAINS FILESTREAM
(NAME = 'FS_FG1', FILENAME = 'I:\Production\FS_FG1'),
FILEGROUP FSFilegroup2 CONTAINS FILESTREAM
(NAME = 'FS_FG2', FILENAME = 'J:\Production\FS_FG2'),
25
FILEGROUP FSFilegroup3 CONTAINS FILESTREAM
(NAME = 'FS_FG3', FILENAME = 'K:\Production\FS_FG3'),
FILEGROUP FSFilegroup4 CONTAINS FILESTREAM
(NAME = 'FS_FG4', FILENAME = 'L:\Production\FS_FG4'),
FILEGROUP FSFilegroup5 CONTAINS FILESTREAM
(NAME = 'FS_FG5', FILENAME = 'M:\Production\FS_FG5'),
FILEGROUP FSFilegroup6 CONTAINS FILESTREAM
(NAME = 'FS_FG6', FILENAME = 'N:\Production\FS_FG6'),
FILEGROUP FSFilegroup7 CONTAINS FILESTREAM
(NAME = 'FS_FG7', FILENAME = 'O:\Production\FS_FG7'),
FILEGROUP FSFilegroup8 CONTAINS FILESTREAM
(NAME = 'FS_FG8', FILENAME = 'P:\Production\FS_FG8'),
FILEGROUP FSFilegroup9 CONTAINS FILESTREAM
(NAME = 'FS_FG9', FILENAME = 'Q:\Production\FS_FG9'),
FILEGROUP FSFilegroupA CONTAINS FILESTREAM
(NAME = 'FS_FGA', FILENAME = 'R:\Production\FS_FGA'),
FILEGROUP FSFilegroupB CONTAINS FILESTREAM
(NAME = 'FS_FGB', FILENAME = 'S:\Production\FS_FGB'),
FILEGROUP FSFilegroupC CONTAINS FILESTREAM
(NAME = 'FS_FGC', FILENAME = 'T:\Production\FS_FGC'),
FILEGROUP FSFilegroupD CONTAINS FILESTREAM
(NAME = 'FS_FGD', FILENAME = 'U:\Production\FS_FGD'),
FILEGROUP FSFilegroupE CONTAINS FILESTREAM
(NAME = 'FS_FGE', FILENAME = 'V:\Production\FS_FGE'),
FILEGROUP FSFilegroupF CONTAINS FILESTREAM
(NAME = 'FS_FGF', FILENAME = 'W:\Production\FS_FGF');
GO
26
USE Production;
GO
-- Creare una funzione di partizione basata sugli ultimi 6 byte del GUID
CREATE PARTITION FUNCTION LoadBalance_PF (UNIQUEIDENTIFIER)
AS RANGE LEFT FOR VALUES (
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-100000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-200000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-300000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-400000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-500000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-600000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-700000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-800000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-900000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-a00000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-b00000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-c00000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-d00000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-e00000000000'),
CONVERT (uniqueidentifier, '00000000-0000-0000-0000-f00000000000'));
GO
-- Creare uno schema di partizionamento di FILESTREAM che consenta il mapping a 16
filegroup FILESTREAM
CREATE PARTITION SCHEME LoadBalance_FS_PS
AS PARTITION LoadBalance_PF TO (
FSFileGroup0, FSFileGroup1, FSFileGroup2, FSFileGroup3,
27
FSFileGroup4, FSFileGroup5, FSFileGroup6, FSFileGroup7,
FSFileGroup8, FSFileGroup9, FSFileGroupA, FSFileGroupB,
FSFileGroupC, FSFileGroupD, FSFileGroupE, FSFileGroupF);
GO
-- Creare uno schema di partizionamento dei dati per il round robin tra due filegroup
CREATE PARTITION SCHEME LoadBalance_Data_PS
AS PARTITION LoadBalance_PF TO (
DataFileGroup1, DataFileGroup2, DataFileGroup1, DataFileGroup2,
DataFileGroup1, DataFileGroup2, DataFileGroup1, DataFileGroup2,
DataFileGroup1, DataFileGroup2, DataFileGroup1, DataFileGroup2,
DataFileGroup1, DataFileGroup2, DataFileGroup1, DataFileGroup2);
GO
-- Creare la tabella partizionata
CREATE TABLE DocumentStore (
DocumentID INT IDENTITY,
Document VARBINARY (MAX) FILESTREAM NULL,
DocGUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL
DEFAULT NEWID (),
CONSTRAINT DocStorePK PRIMARY KEY CLUSTERED (DocGUID),
CONSTRAINT DocStoreU UNIQUE (DocGUID))
ON LoadBalance_Data_PS (DocGUID)
FILESTREAM_ON LoadBalance_FS_PS;
GO
28
Il bilanciamento del carico può essere facilmente testato tramite il codice seguente:
SET NOCOUNT ON;
GO
-- Inserire 10000 righe per testare il bilanciamento del carico
DECLARE @count INT = 0;
WHILE (@count < 10000)
BEGIN
INSERT INTO DocumentStore DEFAULT VALUES;
SET @count = @count + 1;
END;
GO
-- Controllare la distribuzione
SELECT COUNT ($PARTITION.LoadBalance_PF (DocGUID))
FROM DocumentStore
GROUP BY $PARTITION.LoadBalance_PF (DocGUID);
GO
I risultati dell'esecuzione di esempio di questo test sono le righe 631, 641, 661, 640, 649, 637, 618, 618,
576, 608, 595, 645, 640, 616, 602 e 623 in ogni filegroup FILESTREAM da FS_FG0 a FS_FGF.
Combinazioni di funzionalità e relative restrizioni
Poiché la funzionalità FILESTREAM consente di archiviare dati nel file system, esistono alcune restrizioni
e considerazioni da tenere presenti quando si combina FILESTREAM con altre funzionalità di SQL
Server. In questa sezione viene fornita una panoramica delle combinazioni di funzionalità a cui prestare
attenzione. Per ulteriori informazioni, vedere l'argomento "Compatibilità FILESTREAM con altre
funzionalità di SQL Server" nella documentazione online di SQL Server 2008
(http://msdn.microsoft.com/it-it/library/bb895334.aspx).
29
Replica
Sia la replica transazionale sia la replica di tipo merge supportano i dati FILESTREAM, ma è necessario
tenere presenti molte considerazioni, come quelle indicate di seguito.




Quando la topologia di replica include istanze in cui vengono utilizzate diverse versioni di SQL
Server, esistono limitazioni sulle dimensioni dei dati che è possibile inviare alle istanze legacy.
Le opzioni di filtro di replica determinano se l'attributo FILESTREAM viene replicato o meno
mediante la replica transazionale.
Le dimensioni massime del valore di dati varbinary (max) che possono essere replicate nella
replica transazionale senza replicare l'attributo FILESTREAM sono pari a 2 GB.
Quando si utilizza la replica di tipo merge, sia la replica sia FILESTREAM richiedono una colonna
uniqueidentifier. Nell'utilizzo della replica di tipo merge, assicurarsi che i GUID nello schema
della tabella siano sequenziali, ovvero utilizzare NEWSEQUENTIALID() invece di NEWID().
Mirroring del database
Il mirroring del database non include il supporto per FILESTREAM. Non è possibile creare un filegroup
FILESTREAM sul server principale né configurare il mirroring per un database in cui sono contenuti
filegroup FILESTREAM.
Crittografia
I dati FILESTREAM non possono essere crittografati utilizzando i metodi di crittografia di SQL Server.
Se Transparent Data Encryption è abilitato, i dati FILESTREAM non vengono crittografati.
Clustering di failover
FILESTREAM è completamente supportato dal clustering di failover. In tutti i nodi del cluster,
FILESTREAM deve essere abilitato a livello di Windows e i contenitori di dati FILESTREAM devono
essere collocati in risorse di archiviazione condivisa in modo che i dati siano disponibili in tutti i nodi.
Per ulteriori informazioni, vedere l'argomento "Configurazione di FILESTREAM in un cluster di failover"
nella documentazione online di SQL Server 2008 (http://msdn.microsoft.com/it-it/library/cc645886.aspx).
Full-text
L'indicizzazione full-text viene eseguita per una colonna FILESTREAM nello stesso modo in cui avviene
per una colonna varbinary (max). La tabella deve includere una colonna aggiuntiva contenente
l'estensione di file per i dati BLOB archiviati nella colonna FILESTREAM.
Snapshot del database
In SQL Server non è previsto il supporto di snapshot del database per i contenitori di dati FILESTREAM.
Se un file di dati FILESTREAM è incluso in una clausola CREATE DATABASE ON, l'istruzione non verrà
eseguita e verrà generato un errore.
Se un database contiene dati FILESTREAM, sarà comunque possibile creare uno snapshot del database
di filegroup normali. In questo caso, verrà restituito un messaggio di avviso e i filegroup FILESTREAM
verranno contrassegnati come offline nello snapshot del database. Le query verranno eseguite come
previsto sullo snapshot del database a meno che tentino di accedere ai dati FILESTREAM. In questo
caso verrà generato un errore.
30
Un database non può essere ripristinato come snapshot se contiene dati FILESTREAM, in quanto non
è possibile stabilire in che stato i dati FILESTREAM fossero nel momento rappresentato dallo snapshot
del database.
Viste, indici, statistiche, trigger e vincoli
Le colonne FILESTREAM non possono far parte di una chiave di indice o essere specificate come
colonna INCLUDE in un indice non cluster. È possibile definire una colonna calcolata che faccia
riferimento a una colonna FILESTREAM, ma la colonna calcolata non può essere indicizzata.
Non è possibile creare statistiche su colonne FILESTREAM.
Non è possibile creare vincoli PRIMARY KEY, FOREIGN KEY e UNIQUE su colonne FILESTREAM.
Le viste indicizzate non possono contenere colonne FILESTREAM, mentre le viste non indicizzate
possono contenerle.
Non è possibile definire trigger Instead-of su tabelle che contengono colonne FILESTREAM.
Livelli di isolamento
Quando si accede ai dati FILESTREAM tramite le API Win32, viene supportato solo il livello di
isolamento READ-COMMITTED. L'accesso tramite Transact-SQL supporta anche i livelli di isolamento
REPEATABLE-READ e SERIALIZABLE. Inoltre, utilizzando l'accesso tramite Transact-SQL è possibile
effettuare letture dirty attraverso il livello di isolamento READ-UNCOMMITTED o l'hint per la query
NOLOCK, ma con tale accesso non verranno visualizzati gli aggiornamenti in transito dei dati
FILESTREAM.
Backup e ripristino
FILESTREAM funziona con tutti i modelli di recupero e tutti i tipi di backup e ripristino (completo,
differenziale e di log). In una situazione di emergenza, se l'opzione CONTINUE_AFTER_ERROR viene
specificata con un'opzione BACKUP o RESTORE, i dati FILESTREAM potrebbero non venire recuperati
con perdita di dati zero (analogamente al recupero dei dati normali quando si specifica
CONTINUE_AFTER_ERROR).
Sicurezza
L'istanza di SQL Server deve essere configurata per l'utilizzo della sicurezza integrata se è richiesto
l'accesso Win32 ai dati FILESTREAM.
Log shipping
Il log shipping prevede il supporto di FILESTREAM. Sia sui server primari che secondari deve essere in
esecuzione SQL Server 2008 o una versione successiva e FILESTREAM deve essere abilitato a livello di
Windows.
SQL Server Express
SQL Server Express supporta FILESTREAM. Il limite delle dimensioni di 4 GB non include il contenitore
di dati FILESTREAM.
31
Tuttavia, se dati FILESTREAM vengono inviati alla o dall'istanza di SQL Server Express tramite Service
Broker, è necessario prestare attenzione, perché in Service Broker non è previsto il supporto dell'archiviazione
di dati in formato FILESTREAM nelle code di trasmissione o destinazione. Ciò significa che se l'una
o l'altra coda aumenta, potrebbe venire raggiunto il limite di 4 GB delle dimensioni del database.
Un'alternativa in questo caso è l'utilizzo di uno schema in cui la conversazione di Service Broker
funge da trasporto di notifiche che segnalano che è necessario inviare o ricevere dati FILESTREAM.
La trasmissione effettiva dei dati FILESTREAM viene quindi eseguita tramite accesso remoto attraverso
la condivisione FILESTREAM del contenitore di dati FILESTREAM dell'istanza di SQL Server Express.
Considerazioni sull'ottimizzazione e sul benchmarking delle prestazioni
Quando si ottimizza un carico di lavoro FILESTREAM è necessario tenere presenti alcune considerazioni
importanti:






Verificare che l'hardware sia configurato correttamente per FILESTREAM.
Verificare che la generazione di nomi in formato 8.3 sia disabilitata in NTFS.
Verificare che il rilevamento di data/ora dell'ultimo accesso sia disabilitato in NTFS.
Verificare che il contenitore di dati FILESTREAM non si trovi su un volume frammentato.
Verificare che la dimensione dei dati BLOB sia appropriata per l'archiviazione con FILESTREAM.
Verificare che i contenitori di dati FILESTREAM dispongano di propri volumi dedicati.
Un fattore importante da evidenziare riguarda le dimensioni del buffer utilizzato dal protocollo SMB, a sua
volta utilizzato per il buffering delle letture dei dati FILESTREAM. Nei test effettuati con il sistema operativo
Windows Server® 2003, dimensioni del buffer maggiori (multipli di circa 60 KB) tendono a migliorare la
velocità effettiva. Buffer di dimensioni maggiori possono essere più efficienti su altri sistemi operativi.
Vi sono poi ulteriori considerazioni per quanto riguarda il confronto di un carico di lavoro FILESTREAM
con altre opzioni di archiviazione (dopo l'ottimizzazione del carico di lavoro FILESTREAM):



Verificare che l'hardware di archiviazione e il livello RAID corrispondano.
Verificare che l'impostazione di compressione del volume corrisponda.
Tenere in considerazione se in FILESTREAM viene eseguito il write-through in base all'API
utilizzata e alle opzioni specificate.
Considerazioni sulla migrazione dei dati
Uno scenario comune dell'utilizzo di SQL Server 2008 è la migrazione dei dati BLOB esistenti nelle
risorse di archiviazione FILESTREAM. La descrizione dettagliata degli strumenti o del codice per
effettuare tali migrazioni esula dall'ambito di questo white paper, tuttavia di seguito viene indicato un
semplice flusso di lavoro da utilizzare:



32
Esaminare le considerazioni relative alle dimensioni dei dati per l'utilizzo di FILESTREAM per
assicurarsi che le dimensioni medie dei dati interessati siano tali da rendere appropriata
l'archiviazione FILESTREAM.
Esaminare le informazioni disponibili sulle combinazioni di funzionalità e le relative limitazioni per
assicurare che l'archiviazione FILESTREAM funzioni con tutti gli altri requisiti dell'applicazione.
Seguire le indicazioni contenute nella precedente sezione "Considerazioni sull'ottimizzazione
e sul benchmarking delle prestazioni".






Verificare che nell'istanza di SQL Server venga utilizzata la sicurezza integrata e che
FILESTREAM sia abilitato a livello di SQL Server e a livello di Windows.
Verificare che la posizione del contenitore di dati FILESTREAM di destinazione disponga di
spazio sufficiente per archiviare i dati BLOB di cui viene eseguita la migrazione.
Creare i filegroup FILESTREAM richiesti.
Duplicare gli schemi di tabella interessati, modificando in FILESTREAM le colonne BLOB
necessarie.
Eseguire la migrazione di tutti i dati non BLOB nel nuovo schema.
Eseguire la migrazione di tutti i dati BLOB nelle nuove colonne FILESTREAM.
Procedure consigliate per l'utilizzo di FILESTREAM
Questa sezione contiene una raccolta di procedure consigliate emerse in seguito all'utilizzo di
FILESTREAM durante le attività di test interne e pubbliche sulla versione provvisoria della funzionalità.
Come tutte le procedure consigliate, si tratta di generalizzazioni che potrebbero non essere adatte a ogni
situazione e scenario. Sono indicate di seguito, senza un ordine specifico:




Quando possibile, è opportuno evitare più accodamenti di piccole dimensioni a un file
FILESTREAM, perché ogni accodamento comporta la creazione di un intero nuovo file
FILESTREAM. Ciò potrebbe risultare molto costoso per file FILESTREAM di grandi dimensioni.
Se possibile, riunire più accodamenti in una colonna varbinary (max) e quindi accodarli alla
colonna FILESTREAM al raggiungimento di una soglia di dimensione.
Con un carico di lavoro di scrittura con numerosi thread multipli, valutare la possibilità di impostare
il parametro AllocationSize per le API SqlFilestream o OpenSqlFilestream. Dimensioni iniziali più
elevate di allocazione limiteranno il rischio di frammentazione a livello di file system, soprattutto
se si combinano con una grande dimensione del cluster NTFS, come descritto in precedenza.
Se i file FILESTREAM hanno grandi dimensioni, evitare aggiornamenti Transact-SQL che
comportano accodamenti o anteposizioni di dati a un file. Queste operazioni provocano in
genere lo spooling dei dati in tempdb e in un nuovo file fisico, con un conseguente impatto
sulle prestazioni.
Quando si legge un valore FILESTREAM, considerare gli aspetti indicati di seguito:
o Se è necessario leggere solo i primi byte, valutare l'utilizzo della funzione SUBSTRING.
o Se è necessario leggere l'intero file, valutare l'accesso tramite Win32.
o Se è necessario leggere parti casuali del file, valutare la possibilità di aprire l'handle del
file mediante SetFilePointer.
o Per la lettura di un intero file, specificare il flag FILE_SEQUENTIAL_ONLY.
o Utilizzare buffer con dimensioni multiple di 60 KB (come descritto in precedenza).
È possibile ottenere le dimensioni di un file FILESTREAM senza dover aprire un handle del file
aggiungendo una colonna calcolata persistente alla tabella in cui sono archiviate le dimensioni del file
FILESTREAM. La colonna calcolata viene aggiornata mentre il file è già aperto per le operazioni di scrittura.
Conclusione
In questo white paper è stata descritta la funzionalità FILESTREAM di SQL Server 2008,
che consente di archiviare i dati BLOB e di accedervi in modo efficiente utilizzando una
combinazione di SQL Server 2008 e del file system NTFS. Per concludere, è utile ripetere
i punti principali trattati nel white paper.
33
L'archiviazione FILESTREAM non è adatta in tutti i casi. In base a ricerche precedenti a al
comportamento della funzionalità FILESTREAM, i dati BLOB di dimensioni di almeno 1 MB
a cui non si accede tramite Transact-SQL sono i migliori candidati all'archiviazione come dati
FILESTREAM.
È necessario inoltre considerare anche il carico di lavoro dell'aggiornamento, poiché qualsiasi
aggiornamento parziale a un file FILESTREAM comporta la creazione di una copia completa del
file. Un carico di lavoro di aggiornamento particolarmente elevato potrebbe ridurre talmente le
prestazioni da non giustificare l'utilizzo di FILESTREAM.
Per assicurare la riuscita della distribuzione è opportuno valutare in dettaglio le combinazioni
delle funzionalità. Ad esempio, in SQL Server 2008 RTM il mirroring del database non può
essere utilizzato con i dati FILESTREAM e lo stesso vale per l'isolamento dello snapshot.
La maggior parte delle altre combinazioni di funzionalità è supportata, ma per qualche
funzionalità, come la replica, possono esistere delle restrizioni. In questo white paper non
viene fornita una tassonomia completa delle funzionalità e della loro interazione. È pertanto
consigliabile consultare le più recenti sezioni della documentazione online di SQL Server prima
di procedere alla distribuzione, soprattutto perché alcune restrizioni potrebbero non essere più
applicabili nelle versioni future.
Infine, se FILESTREAM viene distribuito senza configurare correttamente Windows e SQL
Server, potrebbe non essere possibile ottenere i livelli di prestazioni previsti. Per evitare
problemi di prestazioni è consigliabile adottare le procedure consigliate e le indicazioni sulla
configurazione descritte in precedenza.
Per ulteriori informazioni
http://www.microsoft.com/italy/server/sql: sito Web SQL Server
http://technet.microsoft.com/it-it/sqlserver/: TechCenter di SQL Server
http://msdn.microsoft.com/it-it/sqlserver/: risorse online per gli sviluppatori di SQL Server
Il documento è risultato utile? Esprimere una valutazione utilizzando una scala compresa tra
1 (scarso) e 5 (eccellente), indicandone i motivi. Ad esempio:


La valutazione è alta perché il documento contiene esempi validi, catture di schermate
nitide, spiegazioni chiare o altri motivi?
La valutazione è bassa perché il documento contiene esempi confusi, catture di
schermate sfocate, spiegazioni poco chiare?
I commenti aiuteranno Microsoft a migliorare la qualità dei white paper pubblicati.
Commenti e suggerimenti.
34