Database
 sql >> Base de Dados >  >> RDS >> Database

Procedimento armazenado para obter informações de armazenamento do servidor no servidor


Por mais populares que sejam os serviços em nuvem hoje em dia, ainda há uma boa parte das implantações locais do SQL Server que ainda exigem que nossos serviços os suportem. Uma das áreas das configurações locais que devemos ficar de olho é o armazenamento, exatamente onde os dados são salvos.

Vou apresentar um procedimento armazenado para visualizar as principais informações do espaço de armazenamento em sua instância do SQL Server.

Considerações iniciais

  • Certifique-se de que a conta que executa este procedimento armazenado tenha privilégios suficientes.
  • Os objetos do banco de dados (tabela do banco de dados e procedimento armazenado) serão criados dentro do banco de dados selecionado no momento em que o script for executado, portanto, escolha com cuidado.
  • O script foi criado de forma que possa ser executado várias vezes sem que você receba um erro. Para o procedimento armazenado, usei a instrução CREATE OR ALTER PROCEDURE, disponível desde o SQL Server 2016 SP1.
  • Sinta-se à vontade para alterar o nome dos objetos de banco de dados criados.
  • Quando você opta por persistir os dados retornados pelo procedimento armazenado, a tabela de destino será primeiro truncada para que apenas o conjunto de resultados mais recente seja armazenado.
  • Lembre-se de que esta solução não faz sentido em implantações na nuvem em que o provedor de nuvem gerencia as coisas para você e você não tem acesso ao sistema de arquivos.

Como usar o procedimento armazenado?

  1. Copie e cole o código TSQL (disponível neste artigo).
  2. O SP espera 2 parâmetros:
    1. @persistData:'S' se o DBA desejar salvar a saída em uma tabela de destino e 'N' se o DBA quiser apenas ver a saída diretamente.
    2. @driveDetail:embora opcional, se você passar uma letra de unidade, o parâmetro @persistData não terá nenhum efeito.

Campos apresentados e seu significado

  • dirigir: a letra da unidade que contém os arquivos de dados da instância atual.
  • total_space: o tamanho da unidade, em GBs.
  • espaço_livre: a quantidade de GBs restantes na unidade.
  • espaço_usado: a quantidade de GBs ocupados por todos os bancos de dados na instância.
  • data_collection_timestamp: visível apenas se ‘Y’ for passado para o parâmetro @persistData, e é usado para saber quando o SP foi executado e as informações foram salvas com sucesso na tabela DBA_Storage.

Testes de execução


Vou demonstrar algumas execuções do Stored Procedure para que você tenha uma ideia do que esperar dele:

EXEC GetStorageData @persistData = 'N'

Como executei isso em uma instância de teste em que tenho tudo na unidade C:\ (eu sei, a pior prática de todos os tempos), apenas uma linha foi retornada. Agora, deixe-me mostrar uma captura de tela do uso da minha unidade C:\, conforme relatado pelo Windows, apenas para ver se o SP não está blefando:

Parece bom, na maior parte. No entanto, se você olhar mais de perto, notará que o “espaço usado” no gráfico diz 25 GB e o SP diz “0,170 GB”, isso é estranho, certo? Bem, a razão é que o significado no SP é um pouco diferente:aqui ele informa a quantidade de GBs ocupados apenas por arquivos de banco de dados, então tenha isso em mente.

Agora, essa saída parece um pouco seca, não é? Quero dizer, não sabemos exatamente o que está ocupando o espaço usado relatado. É aí que o outro parâmetro entra em jogo, então vamos dar uma olhada:

EXEC GetStorageData @persistData = 'N', @driveDetail = 'C'

Executá-lo assim fornecerá a lista de bancos de dados específicos que possuem pelo menos 1 arquivo de banco de dados na unidade passado como parâmetro. Se você somar a coluna “espaço total”, ela fornecerá exatamente o mesmo valor que a saída resumida anterior.

Deixe-me tentar mais uma coisa para ver o que o SP retorna. Vou criar um novo banco de dados, mas colocarei os arquivos do banco de dados em outra unidade que tenho disponível. Estou chamando o banco de dados de “teste” e vou colocá-lo na unidade S:\.

Portanto, agora o SP também gera essa unidade no conjunto de resultados. Mas, novamente, vamos ver o que acontece se lançarmos o parâmetro @driveDetail com 'S' como valor:

Bingo, ele informa o banco de dados ‘teste’ que criei com o tamanho que escolhi (1 GB para o arquivo de dados e 8 MB para o arquivo de log de transações).

Consultas secundárias


Agora, para entregar mais valor ao DBA, preparei algumas consultas que podem ajudá-lo a obter informações úteis a partir dos dados persistidos na tabela.

*Consulta para encontrar bancos de dados com pelo menos 1 arquivo de dados hospedado na unidade C:\.

SELECT * FROM DBA_Storage WHERE drive = 'C:\';

*Consulta para visualizar a lista de drives ordenados por free_space, do menor para o maior. Com isso, você pode saber quais unidades precisam de sua atenção o mais rápido possível.

SELECT * FROM DBA_Storage ORDER BY free_space;

*Consulta para visualizar a lista de drives ordenados por espaço_usado, do maior para o menor. Com isso, você pode saber quais têm mais dados que os outros.

SELECT * FROM DBA_Storage ORDER BY used_space DESC;

Aqui está o código completo do procedimento armazenado:

*No início do script, você verá o valor padrão que o procedimento armazenado assume se nenhum valor for passado para cada parâmetro.
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

Conclusão

  • Você pode implantar este SP em todas as instâncias do SQL Server sob seu suporte e implementar um mecanismo de alerta em toda a sua pilha de instâncias com suporte.
  • Se você implementar um trabalho de agente que consulta essas informações com relativa frequência, poderá ficar no topo do jogo em termos de tomar as medidas para cuidar do armazenamento sempre que determinados limites forem atendidos, dentro de seus ambientes suportados .
  • Certifique-se de verificar mais ferramentas publicadas aqui no CodingSight.