Retrieve SiteCollection usage information and disk space
Quando si ha la necessità di misurare il size su disco ed il contenuto del ContentDB di un determinato SPSite i metodi che possiamo utilizzare sono parecchi, alcuni più efficienti degli altri e/o eventualmente bypassare l’utilizzo del OM messo a disposizione da MOSS.
In questo caso specifico abbiamo la necessità di monitorare il size del ContentDB di un determinato SPSite onde evitare il raggiungimento dei famigerati 100GB raccomandati dal capacity planning di riferimento.
Possiamo scegliere tra tre diversi metodi, oguno con una propria particolarità in base a diversi scenari di utilizzo.
Stored Procedure
Possiamo ad esempio misurare lo spazio fisico che il ContentDB occupa nel filesystem utilizzando la sp di sistema sp_spaceused. Questa misurazione è puntuale e può comprendere sia il LogDB che l’mdf vero e proprio e consiste nell’esecuzione della sp di sistema tramite il passaggio del nome DB che vogliamo monitorare. Non si fa uso dell’OM di MOSS, maggiormente performante ma occorre eseguire la sp nella stessa istanza SQL in cui è gestito il ContentDB di riferimento. Vi giro un esempio che prende in input il nome del database (@SourceDB) ed il sorting delle righe della tabella di output (@SortBy).
1: CREATE PROCEDURE [dba_SpaceUsed]
2:
3: @SourceDB varchar ( 128 ) = null,
4: @SortBy char(1) = 'S'
5:
6: AS
7:
8: SET NOCOUNT ON
9: DECLARE @sql nvarchar (4000)
10: IF @SourceDB IS NULL BEGIN
11: SET @SourceDB = DB_NAME ()
12: END
13:
14: CREATE TABLE #Tables ( [schema] sysname
15: , TabName sysname
16: )
17: SELECT @sql = 'INSERT #tables ([schema], [TabName])
18: SELECT TABLE_SCHEMA, TABLE_NAME
19: FROM ['+ @SourceDB +'].INFORMATION_SCHEMA.TABLES
20: WHERE TABLE_TYPE = ''BASE TABLE'''
21: EXEC (@sql)
22: CREATE TABLE #TabSpaceTxt (
23: TabName sysname
24: , [Rows] varchar (11)
25: , Reserved varchar (18)
26: , Data varchar (18)
27: , Index_Size varchar ( 18 )
28: , Unused varchar ( 18 )
29: )
30: CREATE TABLE #TabSpace ( [Schema] sysname
31: , TabName sysname
32: , [Rows] bigint
33: , ReservedMB numeric(18,3)
34: , DataMB numeric(18,3)
35: , Index_SizeMB numeric(18,3)
36: , UnusedMB numeric(18,3)
37: )
38: DECLARE @Tab sysname, @Sch sysname
39: DECLARE TableCursor CURSOR FOR
40: SELECT [SCHEMA], TabNAME
41: FROM #tables
42: OPEN TableCursor;
43: FETCH TableCursor into @Sch, @Tab;
44: WHILE @@FETCH_STATUS = 0 BEGIN
45: SELECT @sql = 'exec [' + @SourceDB
46: + ']..sp_executesql N''insert #TabSpaceTxt exec sp_spaceused '
47: + '''''[' + @Sch + '].[' + @Tab + ']' + '''''''';
48: Delete from #TabSpaceTxt;
49: EXEC (@sql);
50: INSERT INTO #TabSpace
51: SELECT @Sch
52: , [TabName]
53: , convert(bigint, rows)
54: , convert(numeric(18,3), convert(numeric(18,3),
55: left(reserved, len(reserved)-3)) / 1024.0)
56: ReservedMB
57: , convert(numeric(18,3), convert(numeric(18,3),
58: left(data, len(data)-3)) / 1024.0) DataMB
59: , convert(numeric(18,3), convert(numeric(18,3),
60: left(index_size, len(index_size)-3)) / 1024.0)
61: Index_SizeMB
62: , convert(numeric(18,3), convert(numeric(18,3),
63: left(unused, len([Unused])-3)) / 1024.0)
64: [UnusedMB]
65: FROM #TabSpaceTxt;
66: FETCH TableCursor into @Sch, @Tab;
67: END;
68: CLOSE TableCursor;
69: DEALLOCATE TableCursor;
70: IF @SortBy = 'N'
71: SELECT * FROM #TabSpace
72: ORDER BY [Schema] asc, [TabName] asc
73: ELSE IF @SortBy = 'T'
74: SELECT * FROM #TabSpace
75: ORDER BY [TabName] asc, [Schema] asc
76: ELSE
77: SELECT * FROM #TabSpace
78: ORDER BY ReservedMB desc
79: ;
80: DROP TABLE #Tables
81: DROP TABLE #TabSpaceTxt
82: DROP TABLE #TabSpace
Il risultato dell’esecuzione di questa sp è la visualizzazione di dati di occupazione su disco in base all’elenco completo di tabelle che sono contenute nel DB. I valori sono espressi in MB e basta fare la somma delle righe per avere il size totale di occupazione su disco del ContentDB di riferimento.
SPSite (ContentDatabase)
Se invece abbiamo bisogno di un’astrazione più ad alto livello possiamo interfacciarci direttamente con l’OM di MOSS e recuperare la proprietà DiskSizeRequired dell’oggetto ContentDataBase afferente alla classe SPSite.
1: private ulong CheckSiteDiskSpaceOccupied(string url)
2: {
3:
4: using (SPSite site = new SPSite(url))
5: {
6: return site.ContentDatabase.DiskSizeRequired;
7: }
8:
9: }
Il valore ritornato è un ULong (unsigned) e riporta il valore in bytes necessario ad effettuare un restore (full backup) del ContentDB di riferimento. Questo valore comprende anche la quantità di spazio necessaria alla ricostruzione dei log e di eventuali indici: può essere quindi maggiore del primo esempio.
SPSite (UsageInfo)
In quest’ultimo esempio invece ritorniamo il valore totale in bytes che viene consumato da tutti gli oggetti (metadata, SPList, ecc …) di un determinato SPSite.
1: private long CheckSiteContentUsage(string url)
2: {
3:
4: using (SPSite site = new SPSite(url))
5: {
6:
7: SPSite.UsageInfo info = site.Usage;
8: return info.Storage;
9:
10: }
11:
12: }
In questo caso l’oggetto UsageInfo ritorna un indicatore non aggiornato in tempo reale, in quanto appunto non basa la sua persistenza su informazioni che vengono recuperate da filesystem ma sul lavoro di timerjob che controllano periodicamente l’utilizzo degli oggetti del SPSite di riferimento.
In base alle vostre necessità selezionate il modo migliore, se siete nella stessa instanza potete utilizzare il primo metodo, altrimenti se occorrono dati puntuali utilizzate l’OM e magari ponderate bene l’utilizzo della struttura UsageInfo per elaborare le informazioni di utilizzo sui singoli oggetti del SPSite di riferimento.


