powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Размеры дисков сервера
14 сообщений из 14, страница 1 из 1
Размеры дисков сервера
    #39823524
AndrF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xp_fixeddrives не возвращает размеры дисков сервера, а иногда их все же требуется знать, причем включать поддержку скриптов/clr нельзя.

В итоге сегодня набросал процедуру приведенную ниже. Она вернет размеры всех дисков, на которых есть базы данных. Если на диске нет баз, но есть папка DATA или LOGS , то процедура создаст в них пустую базу данных, чтобы место все же определялось...

В общем, желающие могут пробовать.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
CREATE PROCEDURE GetDisks(@Drv char(1) = NULL)
AS
BEGIN
	SET NOCOUNT ON

	DECLARE @f tinyint = 0, @db sysname, @DefaultLogFolder sysname
	DECLARE @Sql nvarchar(MAX)
	
	DECLARE @Disks TABLE (Drv char(1), Total_MB int, Free_MB int, [Data] bit DEFAULT 0, Logs bit DEFAULT 0)
	DECLARE @Folders TABLE (Folder sysname)

	EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultLog', @DefaultLogFolder OUTPUT
	INSERT INTO @Disks (Drv, Free_MB) EXEC master..xp_fixeddrives
	IF NOT @Drv IS NULL
		DELETE FROM @Disks WHERE Drv <> @Drv

	UPDATE @Disks
		SET Total_MB = t.total_bytes / 1048576
		FROM @Disks d
			INNER JOIN(SELECT DISTINCT UPPER(LEFT(volume_mount_point,1)) AS Drv, total_bytes
						FROM sys.master_files f
							CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id)) t ON d.Drv = t.Drv

	DECLARE cur CURSOR FOR SELECT Drv FROM @Disks
	OPEN cur
	FETCH NEXT FROM cur INTO @Drv
	WHILE @@FETCH_STATUS = 0
	BEGIN
		SET @f = 0
		DELETE FROM @Folders

		INSERT INTO @Folders EXEC('EXEC master..xp_subdirs ''' + @Drv + ':\''')

		IF EXISTS(SELECT * FROM @Folders WHERE Folder='DATA')
			BEGIN
				SET @f = 1
				UPDATE @Disks SET [Data] = 1 WHERE Drv = @Drv
			END

		IF EXISTS(SELECT * FROM @Folders WHERE Folder='LOGS')
			BEGIN
				IF @f = 0 SET @f = 2
				UPDATE @Disks SET [Logs] = 1 WHERE Drv = @Drv
			END
		
		IF @f > 0 AND EXISTS(SELECT * FROM @Disks WHERE Drv = @Drv AND Total_MB IS NULL)
			BEGIN
				SET @db = 'z_disk_' + @Drv
				EXEC ('DROP DATABASE IF EXISTS ' + @db)

				SET @Sql ='
CREATE DATABASE ' + @db + '
	ON ( NAME = ' + @db + '_dat, FILENAME = ''' + @Drv + ':\' + CASE WHEN @f = 1 THEN 'DATA' ELSE 'LOGS' END + '\' + @db + '_dat.mdf'' )
	LOG ON ( NAME = ' + @db + '_log, FILENAME = ''' + @DefaultLogFolder + '\' + @db + '_log.ldf'' )'
				EXEC ( @Sql)

				UPDATE @Disks
					SET Total_MB = total_bytes / 1048576
					FROM @Disks d
						INNER JOIN  (SELECT UPPER(LEFT(volume_mount_point,1)) AS Drv, total_bytes
										FROM sys.database_files f
										CROSS APPLY sys.dm_os_volume_stats(DB_ID( @db ), f.file_id)) t ON d.Drv=t.Drv 
			END
		FETCH NEXT FROM cur INTO @Drv
	END
	CLOSE cur
	DEALLOCATE cur
	DELETE FROM @Disks WHERE [Data]=0 AND Logs=0 AND Drv <> 'C'
	SET NOCOUNT OFF

	SELECT * FROM @Disks
END
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823531
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrF,

как обрабатывается случай отсутствия у учетки прав на диск, на котором создается временная бд?
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823541
Фотография Критик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrF,

зачем?
администратор же есть, у которого имеются права,
и диски - это его проблема
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823545
AndrF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
komradкак обрабатывается случай отсутствия у учетки прав на диск, на котором создается временная бд?

Пока - никак.
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823551
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какая минимальная версия сервера должна быть ?
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823557
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrFkomradкак обрабатывается случай отсутствия у учетки прав на диск, на котором создается временная бд?

Пока - никак.
похоже что последняя временная база и не удаляется, так?
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823571
AndrF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
komradAndrFпропущено...
Пока - никак.
похоже что последняя временная база и не удаляется, так?

Собственно это не совсем временная. Для того чтобы dm_os_volume_stats возвращала данные о диске необходимо чтобы на нем была какая-то база или ее лог. Так что пустую базку можно оставить постоянно - ее нет смысла удалять, тогда в следующий раз и создавать не придется. А лучше дописать удаление в случае если на этом диске появились другие базы...

На счет прав - еще буду думать - надо чтобы все работало для группы не имеющей прав sysadmin-a. В общем, пока все в процессе - для того и кинул сюда чтобы не упустить чего - добрые люди подскажут. Догонят и еще раз подскажут... ;)
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823577
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
столько ещё вариантов заставить что-то делать неестественное sql серевер...
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823596
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrFНа счет прав - еще буду думать - надо чтобы все работало для группы не имеющей прав sysadmin-a.

try catch ?

AndrFВ общем, пока все в процессе - для того и кинул сюда чтобы не упустить чего - добрые люди подскажут. Догонят и еще раз подскажут... ;)
по-товарищески, поскольку не всё равно
было бы всё равно - никто бы и не взлянул ;)
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823609
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrF все работало для группы не имеющей прав sysadmin-a.
http://www.sommarskog.se/grantperm.html часть 5
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823614
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Узнать, сколько осталось места:

Код: sql
1.
exec xp_cmdshell 'dir c:\'



А другое DBA и не требуется.
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823632
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrFОна вернет размеры всех дисков, на которых есть базы данных. Если на диске нет баз, но есть папка DATA или LOGS , то процедура создаст в них пустую базу данных, чтобы место все же определялось...Идея мониторить параметры дисков, на которых расположены базы, понятна, собственно, для этого МС сделал sys.dm_os_volume_stats.
Для дополнительного контроля DBA того, что в принципе должно контролироваться железными админами - но двойной контроль критических параметров полезен.

Но зачем создавать временные базы и мониторить диски, на которых баз не было?

Соглашусь с предыдущими ораторами, ненужный функционал для DBA.
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39823813
Фотография Mind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrF,

Ну то есть mount points вы не используете? Оно вам ерунду выдаст да еще и не по всем дискам.
Wmi/PowerShell надо использовать для такого если очень хочется. А идея с созданием пустых баз конечно забавная.
...
Рейтинг: 0 / 0
Размеры дисков сервера
    #39824464
AndrF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgНо зачем создавать временные базы и мониторить диски, на которых баз не было?

Потому что они там могут быть созданы. А для этого нужно знать сколько там места, ну и сколько останется после... В том числе и в %.

alexeyvgСоглашусь с предыдущими ораторами, ненужный функционал для DBA.

Тут все же каждый решает сам, со своей колокольни. По мне - так очень удобно. Кроме того - вам же неизвестна конкретная задача, для которой оно требуется...

В, общем, все же пришел к тому чем вначале не хотел заниматься, а именно к CLR - на нем все оказалось до смешного просто:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void GetDataDisks(bool bAllDisks = true)
    {
        DriveInfo[] allDrives = System.IO.DriveInfo.GetDrives();

        SqlDataRecord record = new SqlDataRecord(
            new SqlMetaData("Drive", SqlDbType.NVarChar, 25),
            new SqlMetaData("VolumeLabel", SqlDbType.NVarChar, 50),
            new SqlMetaData("Size (MB)", SqlDbType.Float),
            new SqlMetaData("FreeSpace (MB)", SqlDbType.Float),
            new SqlMetaData("Percent Free Space", SqlDbType.Float),
            new SqlMetaData("Data", SqlDbType.Bit),
            new SqlMetaData("Logs", SqlDbType.Bit));

        SqlContext.Pipe.SendResultsStart(record);

        foreach (DriveInfo d in allDrives)
        {
            if (d.DriveType == DriveType.Fixed && d.IsReady == true)
            {
                bool bDataDisk = Directory.Exists(d.Name + "Data");
                bool bLogsDisk = Directory.Exists(d.Name + "Logs");

                if (bAllDisks == true || bDataDisk == true || bLogsDisk == true)
                {
                    record.SetValue(0, d.Name);
                    record.SetValue(1, d.VolumeLabel);
                    record.SetValue(2, (double)d.TotalSize / 1048576);
                    record.SetValue(3, (double)d.TotalFreeSpace / 1048576);
                    record.SetValue(4, (double)(d.TotalFreeSpace * 100) / d.TotalSize);
                    record.SetValue(5, bDataDisk);
                    record.SetValue(6, bLogsDisk);

                    SqlContext.Pipe.SendResultsRow(record);
                }
            }
        }

        SqlContext.Pipe.SendResultsEnd();
    }
}
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Размеры дисков сервера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]