[PL] SQL Server dla DBA – zapomniany widok sys.master_files
Pomyślałem ostatnio, że fajnie by było, jakbym częściej umieszczał nieco prostsze, acz użyteczne kawałki kodu T-SQL, głównie dedykowane administratorom baz danych. Na dobry początek wykorzystanie często zapominanego i niedocenianego widoku systemowego sys.master_files istniejącego w SQL Server 2005 i nowszych wersjach.
Widok ten jest znakomitym źródłem informacji na temat plików baz danych. Można się dzięki niemu szybko zorientować w takich tematach, jak:
- czy pliki bazy leżą na tym samym dysku logicznym,
- jaki jest rozmiar oraz parametry automatycznego powiększania każdego z plików,
- ile plików jakiego typu wchodzi w skład każdej z baz danych,
- jaki jest status każdego pliku (OFFLINE / ONLINE, READ_ONLY, etc.),
- jaki był ostatni log sequence number (LSN) backupu wykonanego na pliku.
Z mojej perspektywy najbardziej przydatna informacja to (oczywiście?) lokalizacja i rozmiar plików (kolumny physical_name oraz size). Rozmiar w kolumnie size liczony jest w 8-kilobajtowych stronach, więc po drodze trzeba wykonać kilka prostych obliczeń, by uzyskać rozmiar pliku na przykład wyrażony w megabajtach. Poniższe zapytanie jest przykładem, jak z widoku sys.master_files można odczytać łączny rozmiar plików każdego rodzaju (log, dane, etc.) dla każdej z baz danych.
SELECT DB_NAME(database_id) AS database_name, CONVERT( numeric(38,2), SUM( CASE type WHEN 0 THEN size * 8192.0 / (1024 * 1024) ELSE 0 END ) ) AS data_size_mb, CONVERT( numeric(38,2), SUM( CASE type WHEN 1 THEN size * 8192.0 / (1024 * 1024) ELSE 0 END ) ) AS log_size_mb, CONVERT( numeric(38,2), SUM( CASE type WHEN 2 THEN size * 8192.0 / (1024 * 1024) ELSE 0 END ) ) AS filestream_size_mb, CONVERT( numeric(38,2), SUM( CASE type WHEN 4 THEN size * 8192.0 / (1024 * 1024) ELSE 0 END ) ) AS fulltext_size_mb FROM sys.master_files GROUP BY database_id ORDER BY DB_NAME(database_id);
Powyższy skrypt umożliwia natychmiastową odpowiedź na pytania w stylu: “która baza jest największa?”, “która baza używa filestream?”, “gdzie log jest większy niż dane?”.
[EDYCJA 2011-01-26]: Czytelnik o nicku wacio słusznie zwrócił mi uwagę, że dla kontenerów FILESTREAM w widoku sys.master_files kolumna size zawsze przyjmuje wartość 0. Dzięki za czujność. Dla mnie to oczywisty bug, ale na szczęście oczywiste obejście tego problemu jest podane w BOL dla Denali: This field is populated as zero for FILESTREAM containers. Query the sys.database_files catalog view for the actual size of FILESTREAM containers. Mimo to, nadal uważam, że sys.master_files jest ciekawym i przydatnym widokiem :-)

Nazywam się Paweł Potasiński i pracuję w polskim oddziale Microsoft w dziale Small and Midmarket Solutions & Partners (SMS&P) jako Partner Technology Advisor.





2011/01/25 - 10:54
teraz do takich zabaw najlepiej wykożystywać performance counters, w zasadzie można wszystko ;)
przykład
select
db_id(instance_name) as DBID,
RTrim(instance_name) as DBName,
sum(case when lower(counter_name) = ‘backup/restore throughput/sec’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLBackupThroughput,
sum(case when lower(counter_name) = ‘bulk copy throughput/sec’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLBCPThroughput,
sum(case when lower(counter_name) = ‘data file(s) size (kb)’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLDataFilesSizeKB,
sum(case when lower(counter_name) = ‘dbcc logical scan bytes/sec’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLDBCCScans,
sum(case when lower(counter_name) = ‘log cache hit ratio’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogCachePhysicalReads,
sum(case when lower(counter_name) = ‘log cache hit ratio base’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogCacheLogicalReads,
sum(case when lower(counter_name) = ‘log file(s) size (kb)’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogFilesSizeKB,
sum(case when lower(counter_name) = ‘log flush wait time’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogFlushWaitTime,
sum(case when lower(counter_name) = ‘log flushes/sec’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogFlushes,
sum(case when lower(counter_name) = ‘log growths’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogGrowths,
sum(case when lower(counter_name) = ‘log shrinks’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogShrinks,
sum(case when lower(counter_name) = ‘log truncations’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLLogTruncations,
sum(case when lower(counter_name) = ‘percent log used’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLPercentLogUsed,
sum(case when lower(counter_name) = ‘transactions/sec’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLTransactions,
sum(case when lower(counter_name) = ‘active transactions’ then convert(numeric(19,0), cntr_value) else 0 end) as SQLTranCount,
case when count(counter_name) = 0 then 1 else 0 end as PerfStats
from sys.dm_os_performance_counters p with (readpast)
where object_name = case when convert(sysname,serverproperty(‘ServerName’)) like ‘%\%’ then ‘MSSQL$’ + @@servicename else ‘SQLServer’ end
+ ‘:Databases’
and instance_name in (select name from sys.databases with (readpast))
group by instance_name
END
2011/01/25 - 11:40
@roku: Też fajne. Countery perfmona daje się czytać i na starszych wersjach SQL Servera (master.dbo.sysperfinfo). A widok master_files pozwala mi zorientować się, ile plików ma każda baza, gdzie są zlokalizowane i jaka jes ich wielkość. Przydatne także wtedy, gdy “najeżdżam” obcy serwer audytem.
2011/01/25 - 11:53
@roku: Jeszcze jedno mi się przypomniało a propos sys.dm_os_performance_counters (zmagałem się z tym dawno temu przy okazji używania sysperfinfo). Niektóre liczniki trzeba sobie przeliczyć bazując na cntr_type (przykład – jak rozumieć Buffer cache hit ratio mające wartość 454 :-)).
2011/01/25 - 12:32
@roku: Bodaj wszystkie countery z nazwą kończącą się słowem “base” w sys.dm_os_performance_counters to podstawy do obliczeń procentowych. W podanym przez Ciebie skrypcie log cache hit ratio base jest interpretowany jako osobny licznik, podczas gdy powinno się go raczej brać do liczenia procentowego współczynnika log cache hit ratio (prosty iloraz: “log cache hit ratio / log cache hit ratio base” powinien dać prawidłowy wynik w ułamku, a dalej pomnożenie przez 100 daje wynik w procentach).
2011/01/25 - 13:09
ten kawałek to akurat z bebechów spotlighta questowego jest ;)
2011/01/25 - 14:08
@roku: Hihi, nikt nie jest doskonały ;-) Chociaż może gdzieś dalej w kodzie robią z tą wartością coś więcej.
2011/01/25 - 21:45
@Paweł: Niestety ten ficzer do formatowania kodu nie wpływa poprawnie na wykorzystanie tego kodu bo kopiuje się z numerkiem linii;) Przy Twoim formatowaniu kodu i ilości treści bieganie z backspacem po 150 linijkach to katorga :D
2011/01/25 - 22:04
A nie pojawiają się ikonki w prawym górnym rogu okna z kodem? :-) Powinna być też ikonka podglądu kodu jako tekstu i ikonka kopiowania do schowka.
2011/01/25 - 22:51
@Paweł: :))))))))) jakbyś nie napisał to w życiu bym na to nie wpadł;)
2011/01/26 - 08:36
@Krzysiek: Poszukam jakiegoś zamiennika albo zrezygnuję z kolorowania, skoro taki kozak, jak Ty, nie dał rady z tym pluginem ;-)
2011/01/26 - 08:54
hehehe nie przesadzaj, nie przesadzaj ;)))) Sam plugin jest fajny dużo lepiej czyta się kod tylko te ikonki mogłyby tam być przypięte na stałe jak ktoś akurat podczas przewijania nie trafi w kod to się nie zorientuje, że coś tam jest ;)
2011/01/26 - 09:20
@Krzysiek: Mówisz i masz :-)
2011/01/26 - 10:28
@Paweł: oooo teraz moim zdaniem intuicyjność +100 ;))))
2011/01/26 - 14:10
Zapytanie w przypadku bazy z filestream pokazuje wielkość filestream równe 0. Jak sprawdziłem bezpośrednio w sys.master_files rzczywiście jest tam 0, a powinno być kilka giga. Czy to narmalne?
2011/01/26 - 15:14
@wacio: Niestety, masz rację. Z FILESTREAM sys.master_files sobie nie radzi. Zresztą w BOL dla następnej wersji SQL Servera (Denali) stoi taki opis kolumny size:
This field is populated as zero for FILESTREAM containers. Query the sys.database_files catalog view for the actual size of FILESTREAM containers.
Pełny opis sys.master_files w BOL dla Denali: http://msdn.microsoft.com/en-us/library/ms186782(v=sql.110).aspx.