sql >> Base de Datos >  >> RDS >> Database

Procedimiento almacenado para obtener información de almacenamiento del servidor en el servidor

A pesar de lo populares que son los servicios en la nube hoy en día, todavía hay una buena parte de las implementaciones locales de SQL Server que aún requieren nuestros servicios para admitirlas. Una de las áreas de las configuraciones locales que debemos vigilar es el almacenamiento, justo donde se guardan los datos.

Voy a presentarle un procedimiento almacenado para visualizar información clave del espacio de almacenamiento dentro de su instancia de SQL Server.

Consideraciones iniciales

  • Asegúrese de que la cuenta que ejecuta este procedimiento almacenado tenga suficientes privilegios.
  • Los objetos de la base de datos (tabla de la base de datos y procedimiento almacenado) se crearán dentro de la base de datos seleccionada en el momento en que se ejecute el script, así que elija con cuidado.
  • La secuencia de comandos está diseñada de manera que se puede ejecutar varias veces sin que se produzca un error. Para el procedimiento almacenado, utilicé la declaración CREATE OR ALTER PROCEDURE, disponible desde SQL Server 2016 SP1.
  • Siéntase libre de cambiar el nombre de los objetos de base de datos creados.
  • Cuando elige conservar los datos devueltos por el procedimiento almacenado, la tabla de destino se trunca primero para que solo se almacene el conjunto de resultados más reciente.
  • Tenga en cuenta que esta solución no tiene sentido en implementaciones en la nube donde el proveedor de la nube administra las cosas por usted y usted no tiene acceso al sistema de archivos.

¿Cómo usar el procedimiento almacenado?

  1. Copie y pegue el código TSQL (disponible en este artículo).
  2. El SP espera 2 parámetros:
    1. @persistData:'Y' si el DBA desea guardar la salida en una tabla de destino y 'N' si el DBA solo quiere ver la salida directamente.
    2. @driveDetail:aunque es opcional, si pasa una letra de unidad, el parámetro @persistData no tendrá ningún efecto.

Campos presentados y su significado

  • unidad: la letra de la unidad que contiene los archivos de datos para la instancia actual.
  • espacio_total: el tamaño de la unidad, en GB.
  • espacio_libre: la cantidad de GB que quedan en la unidad.
  • espacio_usado: la cantidad de GB ocupados por todas las bases de datos en la instancia.
  • datos_coleccion_marca de tiempo: visible solo si se pasa "Y" al parámetro @persistData, y se usa para saber cuándo se ejecutó el SP y la información se guardó correctamente en la tabla DBA_Storage.

Pruebas de ejecución

Demostraré algunas ejecuciones del procedimiento almacenado para que pueda tener una idea de qué esperar de él:

EXEC GetStorageData @persistData = 'N'

Desde que ejecuté esto en una instancia de prueba donde tengo todo guardado en la unidad C:\ (lo sé, la peor práctica de todas), solo se devolvió una fila. Ahora, déjame mostrarte una captura de pantalla del uso de mi unidad C:\, según lo informado por Windows, solo para ver si el SP no está mintiendo:

Se ve bien, en su mayor parte. Sin embargo, si observa más de cerca, notará que el "Espacio usado" en el gráfico dice 25 GB y el SP dice "0.170 GB", eso es extraño, ¿verdad? Bueno, la razón es que el significado en el SP es un poco diferente:aquí informa la cantidad de GB ocupados solo por los archivos de la base de datos, así que tenlo en cuenta.

Ahora, esa salida parece un poco seca, ¿no? Quiero decir, no sabemos qué es exactamente lo que está ocupando el espacio utilizado informado. Ahí es donde entra en juego el otro parámetro, así que vamos a comprobarlo:

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

Ejecutarlo así le dará la lista de bases de datos específicas que tienen al menos 1 archivo de base de datos en el disco pasado como parámetro. Si suma la columna "espacio total", obtendrá exactamente el mismo valor que el resultado resumido anterior.

Déjame probar una cosa más para ver qué devuelve el SP. Voy a crear una nueva base de datos, pero colocaré los archivos de la base de datos en otra unidad que tengo por ahí. Llamaré a la base de datos "prueba" y la colocaré en la unidad S:\.

Entonces ahora el SP también genera esa unidad en el conjunto de resultados. Pero de nuevo, veamos qué sucede si arrojamos el parámetro @driveDetail con 'S' como valor:

Bingo, informa la base de datos de "prueba" que creé con el tamaño que elegí (1 GB para el archivo de datos y 8 MB para el archivo de registro de transacciones).

Consultas secundarias

Ahora, para brindar más valor al DBA, he preparado algunas consultas que pueden ayudarlo a obtener información útil de los datos persistentes en la tabla.

*Consulta para encontrar bases de datos con al menos 1 archivo de datos alojado en la unidad C:\.

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

* Consulta para visualizar la lista de unidades ordenadas por free_space, de menor a mayor. Con esto, puede saber qué unidades necesitan su atención lo antes posible.

SELECT * FROM DBA_Storage ORDER BY free_space;

* Consulta para visualizar la lista de unidades ordenadas por used_space, de mayor a menor. Con esto, puedes saber cuáles tienen más datos que los demás.

SELECT * FROM DBA_Storage ORDER BY used_space DESC;

Aquí está el código completo del procedimiento almacenado:

*Al principio de la secuencia de comandos, verá el valor predeterminado que asume el procedimiento almacenado si no se pasa ningún valor 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

Conclusión

  • Puede implementar este SP en cada instancia de SQL Server bajo su soporte e implementar un mecanismo de alerta en toda su pila de instancias compatibles.
  • Si implementa un trabajo de agente que consulta esta información con relativa frecuencia, puede estar al tanto del juego en términos de tomar las medidas necesarias para cuidar el almacenamiento siempre que se alcancen ciertos umbrales, dentro de su(s) entorno(s) compatible(s). .
  • Asegúrese de consultar más herramientas que se publican aquí en CodingSight.