Колкото и популярни да са облачните услуги в днешно време, все още има голяма част от локални внедрявания на SQL Server, които все още изискват нашите услуги да ги поддържат. Една от областите на локалните настройки, за които трябва да следим, е съхранението, точно там, където се записват данните.
Ще ви представя съхранена процедура за визуализиране на ключова информация за пространството за съхранение във вашия екземпляр на SQL Server.
Първоначални съображения
- Уверете се, че акаунтът, изпълняващ тази съхранена процедура, има достатъчно привилегии.
- Обектите на базата данни (таблица на базата данни и съхранена процедура) ще бъдат създадени вътре в базата данни, избрани в момента, в който скриптът се изпълнява, така че избирайте внимателно.
- Скриптът е изработен по начин, който може да бъде изпълнен многократно, без да ви бъде хвърлена грешка. За съхранената процедура използвах израза CREATE OR ALTER PROCEDURE, наличен от SQL Server 2016 SP1.
- Чувствайте се свободни да промените името на създадените обекти на базата данни.
- Когато изберете да запазите данните, върнати от съхранената процедура, целевата таблица първо ще бъде съкратена, така че ще бъде съхранен само най-скорошният набор от резултати.
- Имайте предвид, че това решение няма смисъл при внедряване в облак, където доставчикът на облак управлява нещата вместо вас и вие нямате достъп до файловата система.
Как да използвам съхранена процедура?
- Копирайте и поставете TSQL кода (наличен в тази статия).
- SP очаква 2 параметъра:
- @persistData:„Y“, ако DBA желае да запази изхода в целева таблица, и „N“, ако DBA иска само да види изхода директно.
- @driveDetail:Макар и по избор, ако предадете буква на устройството, параметърът @persistData няма да има никакъв ефект.
Представени полета и тяхното значение
- шофиране: буквата на устройството, което съдържа файлове с данни за текущия екземпляр.
- общо_пространство: размерът на устройството в ГБ.
- свободно_пространство: количеството GB, останало в устройството.
- използвано_пространство: количеството GB, заети от всички бази данни в екземпляра.
- data_collection_timestamp: видимо само ако „Y“ е предадено на параметъра @persistData и се използва, за да се знае кога SP е бил изпълнен и информацията е била успешно запазена в таблицата DBA_Storage.
Тестове за изпълнение
Ще демонстрирам няколко изпълнения на Съхранената процедура, за да можете да получите представа какво да очаквате от нея:
EXEC GetStorageData @persistData = 'N'
Тъй като изпълних това в тестов екземпляр, където имам всичко напълнено в C:\ устройство (знам, най-лошата практика досега), беше върнат само един ред. Сега, нека ви покажа екранна снимка на използването на моето устройство C:\, както се съобщава от Windows, само за да видя дали SP не блъфира:
Изглежда добре, в по-голямата си част. Ако обаче погледнете по-отблизо, ще забележите, че „Използвано пространство“ в графиката пише 25GB, а SP казва „0.170GB“, това е странно, нали? Е, причината е, че значението в SP е малко по-различно:тук той отчита количеството GB, заети само от файловете на базата данни, така че имайте това предвид.
Сега този изход изглежда малко сух, нали? Искам да кажа, че не знаем какво точно заема отчетеното използвано пространство. Това е мястото, където другият параметър влиза в игра, така че нека да го проверим:
EXEC GetStorageData @persistData = 'N', @driveDetail = 'C'
Изпълнението му по този начин ще ви даде списък с конкретни бази данни, които имат поне 1 файл на база данни в устройството, предаден като параметър. Ако сумирате колоната „общо пространство“, тя ще ви даде точно същата стойност като предишния обобщен изход.
Нека опитам още нещо, за да видя какво връща SP. Ще създам нова база данни, но ще поставя файловете на базата данни в друго устройство, което имам. Извиквам базата данни „тест“ и ще я поставя в устройство S:\.
Така че сега SP също извежда това устройство в набора от резултати. Но отново, нека видим какво ще се случи, ако хвърлим параметъра @driveDetail с „S“ като стойност:
Бинго, той отчита „тестовата“ база данни, която създадох с избрания от мен размер (1GB за файла с данни и 8MB за регистрационния файл на транзакциите).
Странични заявки
Сега, за да предам повече стойност на DBA, подготвих няколко заявки, които могат да ви помогнат да получите полезна информация от данните, запазени в таблицата.
*Запитване за намиране на бази данни с поне 1 файл с данни, хостван в C:\ устройство.
SELECT * FROM DBA_Storage WHERE drive = 'C:\';
*Запитване за визуализиране на списъка с устройства, сортирани по свободно_пространство, от най-ниското до най-високото. С това можете да разберете кои устройства се нуждаят от вашето внимание възможно най-скоро.
SELECT * FROM DBA_Storage ORDER BY free_space;
*Запитване за визуализиране на списъка с устройства, сортирани по used_space, от най-високо към най-ниско. С това можете да разберете кои от тях имат повече данни от другите.
SELECT * FROM DBA_Storage ORDER BY used_space DESC;
Ето пълния код на Съхранената процедура:
*В самото начало на скрипта ще видите стойността по подразбиране, която запаметената процедура приема, ако не се подаде стойност за всеки параметър.
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
Заключение
- Можете да разположите този SP във всеки екземпляр на SQL Server под вашата поддръжка и да внедрите механизъм за предупреждение в целия си пакет от поддържани екземпляри.
- Ако внедрите задача на агент, която отправя заявки към тази информация относително често, можете да останете на върха на играта по отношение на предприемането на стъпките, за да се погрижите за съхранението, когато бъдат постигнати определени прагове, в рамките на поддържаната от вас среда(и) .
- Не забравяйте да разгледате още инструменти, публикувани тук в CodingSight.