Tabella da 200 GB troncata ma spazio su disco non rilasciato


23

Mi rimangono solo 2 GB, quindi devo rimuovere questa tabella di cronologia. Questa tabella ora è vuota ma lo spazio su disco del database non è stato rilasciato. E il file di database è di 320 GB.


Ho trovato alcune tracce di replica sul database, questo aumenta notevolmente la dimensione del registro e impedisce di eliminarlo o ridurlo.
Lucas Rodrigues Sena

Risposte:


25

Se si fa riferimento al consumo effettivo del file di database sul volume, SQL Server non lo gestisce automaticamente . Solo perché hai rimosso i dati dal database non significa che i file del database si ridurranno per adattarsi solo ai dati esistenti.

Cosa saresti cercando, se si dispone di recuperare spazio sul volume, sarebbe riducendo il file particolare con DBCC SHRINKFILE. Vale la pena notare alcune buone pratiche, come da quella documentazione:

Migliori pratiche

Considerare le seguenti informazioni quando si prevede di ridurre un file:

  • Un'operazione di compattazione è più efficace dopo un'operazione che crea molto spazio inutilizzato, ad esempio una tabella troncata o un'operazione di trascinamento della tabella.

  • La maggior parte dei database richiede che sia disponibile dello spazio libero per le normali operazioni quotidiane. Se si restringe ripetutamente un database e si nota che le dimensioni del database aumentano di nuovo, ciò indica che lo spazio che è stato ridotto è necessario per le normali operazioni. In questi casi, ridurre ripetutamente il database è un'operazione sprecata.

  • Un'operazione di compattazione non preserva lo stato di frammentazione degli indici nel database e generalmente aumenta la frammentazione a un livello. Questo è un altro motivo per non ridurre ripetutamente il database.

  • Riduci più file nello stesso database in sequenza anziché in concomitanza. La contesa sulle tabelle di sistema può causare ritardi dovuti al blocco.

Da notare anche:

DBCC SHRINKFILE le operazioni possono essere interrotte in qualsiasi momento del processo e qualsiasi lavoro completato viene conservato.

Ci sono sicuramente alcune cose da considerare quando lo fai, e ti consiglio di dare un'occhiata al post sul blog di Paul Randal su cosa succede quando si esegue questa operazione.

Il primo passo sarebbe sicuramente verificare quanto spazio e spazio libero sei effettivamente in grado di sostituire, così come lo spazio utilizzato nei file:

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;

6

Questo è un comportamento normale quando si tronca la tabella e che comporta la rimozione di oltre 128 estensioni come per la documentazione online

Quando si eliminano o ricostruiscono indici di grandi dimensioni o si eliminano o troncano tabelle di grandi dimensioni, Motore di database difende le deallocazioni di pagina effettive e i relativi blocchi associati, fino a quando non viene eseguito il commit di una transazione. Questa implementazione supporta sia autocommit che transazioni esplicite in un ambiente multiutente e si applica a tabelle e indici di grandi dimensioni che utilizzano più di 128 estensioni.

Motore di database evita i blocchi di allocazione necessari per eliminare oggetti di grandi dimensioni suddividendo il processo in due fasi distinte: logica e fisica.

Nella fase logica, le unità di allocazione esistenti utilizzate dalla tabella o dall'indice vengono contrassegnate per la deallocazione e bloccate fino al completamento della transazione. Con un indice cluster che viene eliminato, le righe di dati vengono copiate e quindi spostate in nuove unità di allocazione create nell'archivio o in un indice cluster ricostruito o in un heap. (Nel caso di una ricostruzione di indice, anche le righe di dati vengono ordinate.) Quando si verifica un rollback, è necessario eseguire il rollback solo di questa fase logica.

La fase fisica si verifica dopo il commit della transazione. Le unità di allocazione contrassegnate per la deallocazione vengono eliminate fisicamente in batch. Questi drop sono gestiti all'interno di brevi transazioni che si verificano in background e non richiedono molti blocchi.

Poiché la fase fisica si verifica dopo il commit di una transazione, lo spazio di archiviazione della tabella o dell'indice potrebbe apparire come non disponibile. Se questo spazio è necessario per la crescita del database prima del completamento della fase fisica, Motore di database tenta di recuperare spazio dalle unità di allocazione contrassegnate per la deallocazione. Per trovare lo spazio attualmente utilizzato da queste unità di allocazione, utilizzare la vista del catalogo sys.allocation_units.

Le operazioni di rilascio differito non rilasciano immediatamente spazio allocato e introducono costi generali aggiuntivi nel Motore di database. Pertanto, le tabelle e gli indici che utilizzano 128 o meno estensioni vengono eliminati, troncati e ricostruiti proprio come in SQL Server 2000. Ciò significa che entrambe le fasi logica e fisica si verificano prima del commit della transazione.

Dovresti aspettare e, naturalmente, dovresti ridurre manualmente il file per recuperare spazio. Vale anche la pena ricordare che la riduzione causa frammentazione logica e dovrebbe essere evitata a meno che il tuo bisogno non sia grave. Dovresti pensare in qualche modo all'equilibrio tra contrazione e frammentazione. È meglio chiedersi se la riduzione potrebbe effettivamente risolvere il problema considerando lo scenario in cui i dati cresceranno di nuovo comunque.

Utilizzare la query seguente per verificare la quantità di spazio libero disponibile nel database

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

6

Oltre alle risposte di Tom e Shanky, se il database contiene dati LOB / BLOB, DBCC SHRINKFILE potrebbe non funzionare. In tal caso, sono disponibili due opzioni, a seconda che sia possibile portare offline il database o meno. Se riesci a portare offline il database, dovrai copiare i dati e copiarli nuovamente per rimuovere lo spazio vuoto. È possibile ottenere questo risultato in uno dei seguenti modi:

  1. Utilizzo di un'istruzione SELECT INTO per trasferire l'intera tabella in una nuova tabella. Eliminare la tabella originale, eseguire DBCC SHRINKFILE . Rinomina la nuova tabella con il nome originale della tabella.
  2. Utilizzando bcp per copiare la tabella in modalità nativa, eliminare la tabella, eseguire DBCC SHRINKFILE , creare una tabella e quindi bcp i dati nella tabella.
  3. Utilizzando Esporta / Importa per spostare tutti i dati in un nuovo database, eliminare il database esistente, rinominare il nuovo database con il nome del database originale.

Se non è possibile portare offline il database, è possibile utilizzare il comando DBCC SHRINKFILE con l' opzione EMPTYFILE .

Dettagli per la copia offline: http://support.microsoft.com/kb/324432/en-us

Informazioni correnti per l'opzione EMPTYFILE http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.