Programaticamente determinar o espaço livre disponível em um banco de dados?
-
06-09-2019 - |
Pergunta
Ok, eu tentei procurar em torno de esta resposta, mas sem sorte. Eu tenho cerca de 50 bases de dados em nosso SQL Server no trabalho que eu tenho que verificar quase todos os dias para ver se qualquer espaço pode ser liberado via encolhendo. Nossas unidades tendem a encher-se muito, então é por isso que é uma tarefa quase que diariamente.
Existe uma maneira rápida de verificar quais bancos de dados realmente tem espaço livre disponível? Alguém sabe de um sistema / custom procedimento ou visão do sistema que pode gerar uma lista de cada banco de dados e quanto espaço livre está disponível para ser encolheu nesse banco de dados armazenados?
A propósito, utilizando um servidor SQL 2005.
Solução
Executar sp_spacedused para cada banco de dados:
--temporary table to hold database names
CREATE TABLE #Databases (name varchar(255))
INSERT INTO #Databases
SELECT name FROM master..sysdatabases
DECLARE abc CURSOR FOR
SELECT name FROM #Databases
DECLARE @name varchar(255)
DECLARE @sql nvarchar(1024)
OPEN abc
FETCH NEXT FROM abc INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
--build sql to switch to that database...
SET @sql = 'USE '+@name
PRINT @sql
EXECUTE (@sql)
--and run spaceused on it
SET @sql = 'EXECUTE sp_spaceused @UpdateUsage=True'
PRINT @sql
EXECUTE (@sql)
FETCH NEXT FROM ABC INTO @name
END
CLOSE abc
DEALLOCATE abc
DROP TABLE #Databases
resultados singulares Amostra
Executar T-SQL:
USE Contoso
EXECUTE sp_spaceused @UpdateUsage=True
Resultados:
database_name: Contoso
database_size: 85.13 MB
unallocated_space: 15.41 MB
reserved: 70,368 KB (68.7 MB)
data: 42,944 KB (41.9 MB)
index_size: 24,200 KB (23.6 MB)
unused: 3,224 KB ( 3.1 MB)
Encolher:
DBCC SHRINKDATABASE (Contoso)
Verifique espaço novamente:
EXECUTE sp_spaceused @UpdateUsage=True
Resultados:
database_name: Contoso
database_size: 69.81 MB
unallocated_space: 0.20 MB
reserved: 70,256 KB (68.6 MB)
data: 43,024 KB (42.0 MB)
index_size: 24,200 KB (23.6 MB)
unused: 3,032 KB ( 3.0 MB)
Outras dicas
A resposta não é de se preocupar com quanto espaço livre existe nas bases de dados, e em vez disso executar uma tarefa de manutenção noturno ou semanal que corre compactação. As probabilidades são que você não está compactar seus arquivos de log (isto é onde eu costumo teve o maior crescimento).
Executar um backup completo, em seguida, executar um backup do log de transações com TRUNCATE_ONLY e uma vez que completa, executar DBCC SHRINKFILE () em seus arquivos de log e bancos de dados.
Em seguida, você só tem que monitorar total de espaço em disco disponível, e não o crescimento do banco de dados individual.
SQL Server Encolher banco de dados. Você absolutamente tem que executar um backup completo e um backup do log de transações antes de este trabalho.
Você pode obter informações sobre os arquivos individuais carregados executando 'SELECT * FROM master.dbo.sysdatabases' eo run '* selecione a partir de [dbname] .. sysfiles'. Eu não estou 100%, eu não tocar em uma instância do SQL Server em quase um ano, sysfiles pode estar no banco de dados 'master'.
Provavelmente algo em vista WMI ou SQL. Mas eu tenho que perguntar - como faz o custo do seu tempo bisbilhotando com isso todos os dias comparar a compra de algumas unidades de disco
Você pode usar sp_spaceused e consumir o seu resultado, ou você pode olhar-se na tabela de sys.allocations_units e contar as páginas usadas totais. Você não deve olhar para o nível de base de dados, mas a nível de arquivo, porque alguns podem ter vários NDFs. Comece com sys.database_files para ver todos os arquivos nos arquivos de banco de dados. A coluna de tamanho irão conter o número total de páginas na base de dados. A soma-se o total de páginas de sys.allocation_units para obter as páginas usadas:
with sum_au as (
select data_space_id
, sum(total_pages) as total_pages
from sys.allocation_units au
group by data_space_id)
select ds.name
, df.size
, total_pages as in_use
from sys.database_files df
join sys.data_spaces ds on df.data_space_id = ds.data_space_id
join sum_au au on au.data_space_id = ds.data_space_id