Tabela de 200 GB truncada, mas o espaço em disco não foi liberado

23

Eu tenho apenas 2 GB restantes, por isso preciso remover esta tabela de histórico. Esta tabela agora está vazia, mas o espaço em disco do banco de dados não foi liberado. E o arquivo do banco de dados é de 320 GB.

Lucas Rodrigues Sena
fonte
Eu fundei alguns traços de replicação no banco de dados, isso aumentou drasticamente o tamanho do log e evitou excluir ou encolher.
Lucas Rodrigues Sena

Respostas:

25

Se você estiver referenciando o consumo real do arquivo de banco de dados no volume, o SQL Server não tratará isso automaticamente . Só porque você removeu dados do banco de dados não significa que os arquivos do banco de dados serão reduzidos para caber apenas nos dados existentes.

O que você procuraria, se precisar recuperar espaço no volume, reduziria o arquivo específico DBCC SHRINKFILE. É importante destacar algumas práticas recomendadas, conforme a documentação:

Melhores práticas

Considere as seguintes informações ao planejar reduzir um arquivo:

  • Uma operação de redução é mais eficaz após uma operação que cria muito espaço não utilizado, como uma tabela truncada ou uma operação de remoção da tabela.

  • A maioria dos bancos de dados requer algum espaço livre disponível para operações diárias regulares. Se você reduzir um banco de dados repetidamente e perceber que o tamanho do banco de dados aumenta novamente, isso indica que o espaço que foi reduzido é necessário para operações regulares. Nesses casos, reduzir repetidamente o banco de dados é uma operação desperdiçada.

  • Uma operação de redução não preserva o estado de fragmentação dos índices no banco de dados e geralmente aumenta a fragmentação em um grau. Esse é outro motivo para não reduzir repetidamente o banco de dados.

  • Reduza vários arquivos no mesmo banco de dados sequencialmente, em vez de simultaneamente. A contenção nas tabelas do sistema pode causar atrasos devido ao bloqueio.

Também de nota:

DBCC SHRINKFILE as operações podem ser interrompidas em qualquer ponto do processo e qualquer trabalho concluído é mantido.

Certamente, há algumas coisas a considerar ao fazer isso, e eu recomendo que você dê uma olhada na postagem de Paul Randal no que acontece quando você faz essa operação.

A primeira etapa seria definitivamente verificar quanto espaço e espaço livre você realmente pode substituir, bem como o espaço usado no (s) arquivo (s):

use AdventureWorks2012;
go

;with db_file_cte as
(
    select
        name,
        type_desc,
        physical_name,
        size_mb = 
            convert(decimal(11, 2), size * 8.0 / 1024),
        space_used_mb = 
            convert(decimal(11, 2), fileproperty(name, 'spaceused') * 8.0 / 1024)
    from sys.database_files
)
select
    name,
    type_desc,
    physical_name,
    size_mb,
    space_used_mb,
    space_used_percent = 
        case size_mb
            when 0 then 0
            else convert(decimal(5, 2), space_used_mb / size_mb * 100)
        end
from db_file_cte;
Thomas Stringer
fonte
6

Esse é um comportamento normal quando você trunca a tabela e envolve a remoção de mais de 128 extensões conforme o Per Books Online

Quando você elimina ou reconstrói índices grandes ou elimina ou trunca tabelas grandes, o Mecanismo de Banco de Dados adia as desalocações da página real e seus bloqueios associados, até depois que uma transação é confirmada. Essa implementação suporta transações de confirmação automática e explícita em um ambiente multiusuário e se aplica a tabelas e índices grandes que usam mais de 128 extensões.

O Mecanismo de Banco de Dados evita os bloqueios de alocação necessários para descartar objetos grandes, dividindo o processo em duas fases separadas: lógica e física.

Na fase lógica, as unidades de alocação existentes usadas pela tabela ou índice são marcadas para desalocação e bloqueadas até que a transação seja confirmada. Com um índice clusterizado que é descartado, as linhas de dados são copiadas e, em seguida, movidas para novas unidades de alocação criadas para o armazenamento, como um índice clusterizado reconstruído ou um heap. (No caso de uma reconstrução de índice, as linhas de dados também são classificadas.) Quando há uma reversão, apenas essa fase lógica precisa ser revertida.

A fase física ocorre após a transação ser confirmada. As unidades de alocação marcadas para desalocação são descartadas fisicamente em lotes. Essas descargas são tratadas em transações curtas que ocorrem em segundo plano e não exigem muitos bloqueios.

Como a fase física ocorre depois que uma transação é confirmada, o espaço de armazenamento da tabela ou índice ainda pode parecer indisponível. Se esse espaço for necessário para o banco de dados crescer antes da conclusão da fase física, o Mecanismo de Banco de Dados tentará recuperar o espaço das unidades de alocação marcadas para desalocação. Para localizar o espaço atualmente usado por essas unidades de alocação, use a exibição do catálogo sys.allocation_units.

As operações de recebimento diferido não liberam espaço alocado imediatamente e introduzem custos adicionais adicionais no Mecanismo de Banco de Dados. Portanto, tabelas e índices que usam 128 ou menos extensões são descartados, truncados e reconstruídos como no SQL Server 2000. Isso significa que as fases lógicas e físicas ocorrem antes que a transação seja confirmada.

Você precisaria esperar e, é claro, reduziria manualmente o arquivo para recuperar espaço. Também vale mencionar que a redução causa fragmentação lógica e deve ser evitada, a menos que sua necessidade seja grave. Você precisaria, de certa forma, o equilíbrio entre encolher e fragmentar. É melhor se perguntar se o encolhimento realmente resolveria o problema, considerando o cenário em que os dados voltarão a crescer de qualquer maneira.

Use a consulta abaixo para verificar quanto espaço livre há no banco de dados

SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;
Shanky
fonte
6

Além das respostas de Tom e Shanky, se o seu banco de dados contiver dados LOB / BLOB, o DBCC SHRINKFILE pode não funcionar. Se for esse o caso, você tem duas opções, dependendo de poder colocar o banco de dados offline ou não. Se você pode colocar o banco de dados offline, precisará copiar os dados e copiá-los novamente para remover o espaço vazio. Você pode fazer isso de uma das seguintes maneiras:

  1. Usando uma instrução SELECT INTO para transferir a tabela inteira para uma nova tabela. Solte a tabela original, execute DBCC SHRINKFILE . Renomeie a nova tabela para o nome da tabela original.
  2. Usando o bcp para copiar a tabela no modo nativo, solte a tabela, execute DBCC SHRINKFILE , crie a tabela e bcp os dados na tabela.
  3. Usando Exportar / Importar para mover todos os dados para um novo banco de dados, soltar o banco de dados existente, renomear o novo banco de dados para o nome original do banco de dados.

Se você não conseguir colocar o banco de dados offline, poderá usar o comando DBCC SHRINKFILE com a opção EMPTYFILE .

Detalhes para cópia offline: http://support.microsoft.com/kb/324432/en-us

Informações atuais sobre a opção EMPTYFILE http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx

stacylaray
fonte