Choć usługi w chmurze są obecnie popularne, nadal istnieje spora część lokalnych wdrożeń SQL Server, które nadal wymagają obsługi naszych usług. Jednym z obszarów konfiguracji lokalnych, na który musimy zwracać uwagę, jest przechowywanie, dokładnie tam, gdzie dane są zapisywane.
Zaprezentuję Wam procedurę składowaną, aby zwizualizować kluczowe informacje o przestrzeni dyskowej w instancji SQL Server.
Rozważania wstępne
- Upewnij się, że konto wykonujące tę procedurę składowaną ma wystarczające uprawnienia.
- Obiekty bazy danych (tabela bazy danych i procedura składowana) zostaną utworzone wewnątrz bazy danych wybranej w czasie wykonywania skryptu, więc wybieraj ostrożnie.
- Skrypt jest tak skonstruowany, że można go wykonać wiele razy bez wyrzucenia błędu. W przypadku procedury składowanej użyłem instrukcji CREATE OR ALTER PROCEDURE, dostępnej od SQL Server 2016 SP1.
- Możesz zmienić nazwę utworzonych obiektów bazy danych.
- Gdy zdecydujesz się utrwalić dane zwrócone przez procedurę składowaną, tabela docelowa zostanie najpierw obcięta, więc tylko najnowszy zestaw wyników zostanie zapisany.
- Pamiętaj, że to rozwiązanie nie ma sensu w przypadku wdrożeń w chmurze, w których dostawca chmury zarządza rzeczami za Ciebie i nie masz dostępu do systemu plików.
Jak korzystać z procedury zapisanej?
- Skopiuj i wklej kod TSQL (dostępny w tym artykule).
- SP oczekuje 2 parametrów:
- @persistData:„Y”, jeśli administrator danych chce zapisać dane wyjściowe w tabeli docelowej, i „N”, jeśli administrator danych chce tylko zobaczyć dane wyjściowe bezpośrednio.
- @driveDetail:Chociaż opcjonalny, jeśli podasz literę dysku, parametr @persistData nie będzie miał żadnego wpływu.
Prezentowane pola i ich znaczenie
- dysk: litera dysku zawierająca pliki danych dla bieżącej instancji.
- całkowita_przestrzeń: rozmiar dysku w GB.
- wolna_przestrzeń: ilość GB pozostałych na dysku.
- used_space: ilość GB zajmowanych przez wszystkie bazy danych w instancji.
- data_collection_timestamp: widoczne tylko wtedy, gdy „Y” jest przekazywane do parametru @persistData i jest używane, aby wiedzieć, kiedy SP został wykonany, a informacje zostały pomyślnie zapisane w tabeli DBA_Storage.
Testy wykonania
Pokażę kilka wykonań procedury składowanej, abyś mógł zorientować się, czego się po niej spodziewać:
EXEC GetStorageData @persistData = 'N'
Ponieważ uruchomiłem to w instancji testowej, w której mam wszystko wypchane na dysku C:\ (wiem, najgorsza praktyka w historii), zwrócono tylko jeden wiersz. Teraz pozwól, że pokażę zrzut ekranu użycia mojego dysku C:\, zgodnie z raportem systemu Windows, tylko po to, aby zobaczyć, czy SP nie blefuje:
W większości wygląda dobrze. Jeśli jednak przyjrzysz się bliżej, zauważysz, że „Wykorzystane miejsce” na grafice to 25 GB, a SP mówi „0,170 GB”, to dziwne, prawda? Cóż, powodem jest to, że znaczenie w SP jest nieco inne:tutaj podaje ilość GB zajmowaną tylko przez pliki bazy danych, więc miej to na uwadze.
Teraz to wyjście wydaje się nieco suche, prawda? Chodzi mi o to, że nie wiemy, co dokładnie zajmuje zgłoszone wykorzystane miejsce. W tym miejscu w grę wchodzi drugi parametr, więc sprawdźmy to:
EXEC GetStorageData @persistData = 'N', @driveDetail = 'C'
Wykonanie go w ten sposób da ci listę konkretnych baz danych, które mają co najmniej 1 plik bazy danych na dysku przekazany jako parametr. Jeśli zsumujesz kolumnę „całkowita przestrzeń”, uzyskasz dokładnie taką samą wartość, jak poprzednie podsumowanie wyników.
Spróbuję jeszcze jednej rzeczy, aby zobaczyć, co zwraca SP. Zamierzam utworzyć nową bazę danych, ale pliki bazy danych umieszczę na innym dysku, który mam. Nazywam bazę danych „test” i umieszczę ją na dysku S:\.
Więc teraz SP również wyprowadza dane sterujące w zestawie wyników. Ale znowu, zobaczmy, co się stanie, jeśli wrzucimy parametr @driveDetail z „S” jako wartością:
Bingo raportuje utworzoną przeze mnie „testową” bazę danych o wybranym przeze mnie rozmiarze (1 GB na plik danych i 8 MB na plik dziennika transakcji).
Zapytania poboczne
Teraz, aby zapewnić DBA większą wartość, przygotowałem kilka zapytań, które mogą pomóc w uzyskaniu przydatnych informacji z danych utrwalonych w tabeli.
*Zapytanie, aby znaleźć bazy danych z co najmniej 1 plikiem danych hostowanym na dysku C:\.
SELECT * FROM DBA_Storage WHERE drive = 'C:\';
* Zapytanie do wizualizacji listy dysków posortowanych według free_space, od najniższego do najwyższego. Dzięki temu możesz jak najszybciej dowiedzieć się, które dyski wymagają Twojej uwagi.
SELECT * FROM DBA_Storage ORDER BY free_space;
* Zapytanie do wizualizacji listy dysków posortowanych według used_space, od najwyższego do najniższego. Dzięki temu możesz wiedzieć, które z nich mają więcej danych niż inne.
SELECT * FROM DBA_Storage ORDER BY used_space DESC;
Oto pełny kod procedury przechowywanej:
*Na samym początku skryptu zobaczysz domyślną wartość, którą przyjmuje procedura składowana, jeśli nie przekazano żadnej wartości dla każdego parametru.
CREATE OR ALTER PROCEDURE [dbo].[GetStorageData]
@persistData CHAR(1) = 'Y',
@driveDetail CHAR(1) = NULL
AS
BEGIN
SET NOCOUNT ON
DECLARE @command NVARCHAR(MAX)
DECLARE @Tmp_StorageInformation TABLE(
[drive] [CHAR](3) NOT NULL,
[total_space] [DECIMAL](10,3) NOT NULL,
[free_space] [DECIMAL](10,3) NOT NULL,
[used_space] [DECIMAL](10,3) NOT NULL
)
IF NOT EXISTS (SELECT * FROM dbo.sysobjects where id = object_id(N'DBA_Storage') and OBJECTPROPERTY(id, N'IsTable') = 1)
BEGIN
CREATE TABLE DBA_Storage(
[drive] [CHAR](3) NOT NULL,
[total_space] [DECIMAL](10,3) NOT NULL,
[free_space] [DECIMAL](10,3) NOT NULL,
[used_space] [DECIMAL](10,3) NOT NULL,
[data_collection_timestamp] [DATETIME] NOT NULL
)
END
IF(@driveDetail IS NOT NULL)
BEGIN
SELECT DB_NAME(mf.database_id) AS 'database',CONVERT(DECIMAL(10,3),SUM(size*8)/1024.0/1024.0) AS 'total space'
FROM sys.master_files mf
WHERE SUBSTRING(mf.physical_name,0,4) = CONCAT(@driveDetail,':\')
GROUP BY mf.database_id
RETURN
END
INSERT INTO @Tmp_StorageInformation
SELECT
drives.drive,
drives.total_space,
drives.free_space,
(SELECT CONVERT(DECIMAL(10,3),SUM(size*8)/1024.0/1024) FROM sys.master_files WHERE SUBSTRING(physical_name,0,4) = drives.drive) AS 'used_space'
FROM(
SELECT DISTINCT vs.volume_mount_point AS 'drive',CONVERT(DECIMAL(10,3),(vs.available_bytes/1048576)/1024.0) AS 'free_space',CONVERT(DECIMAL(10,3),(vs.total_bytes/1048576)/1024.0) AS 'total_space'
FROM sys.master_files mf
CROSS APPLY sys.dm_os_volume_stats(mf.database_id,mf.file_id) vs
) AS drives
IF @persistData = 'N'
SELECT * FROM @Tmp_StorageInformation
ELSE
BEGIN
TRUNCATE TABLE DBA_Storage
INSERT INTO DBA_Storage
SELECT *,GETDATE() FROM @Tmp_StorageInformation ORDER BY [drive]
END
END
Wniosek
- Możesz wdrożyć ten SP w każdej instancji SQL Server pod twoim wsparciem i zaimplementować mechanizm ostrzegania w całym stosie obsługiwanych instancji.
- Jeśli zaimplementujesz zadanie agenta, które stosunkowo często odpytuje te informacje, możesz być na bieżąco, jeśli chodzi o podejmowanie kroków, aby zadbać o pamięć masową po osiągnięciu określonych progów w obsługiwanych środowiskach. .
- Pamiętaj, aby sprawdzić więcej narzędzi, które są publikowane tutaj w CodingSight.