Skrócona tabela 200 GB, ale nie zwolniono miejsca na dysku

23

Zostały mi tylko 2 GB, więc muszę usunąć tę tabelę historii. Ta tabela jest teraz pusta, ale miejsce na dysku bazy danych nie zostało zwolnione. Plik bazy danych ma 320 GB.

Lucas Rodrigues Sena
źródło
Znalazłem pewne ślady replikacji w bazie danych, co znacznie zwiększa rozmiar dziennika i zapobiega usuwaniu lub zmniejszaniu.
Lucas Rodrigues Sena

Odpowiedzi:

25

Jeśli odwołujesz się do faktycznego zużycia pliku bazy danych na woluminie, SQL Server nie obsługuje tego automatycznie . Tylko dlatego, że usunąłeś dane z bazy danych, nie oznacza to, że pliki bazy danych zostaną zmniejszone, aby pasowały tylko do istniejących danych.

To, czego byś szukał, gdybyś musiał odzyskać miejsce na woluminie, zmniejszyłby konkretny plik DBCC SHRINKFILE. Warto zwrócić uwagę na kilka najlepszych praktyk, zgodnie z tą dokumentacją:

Najlepsze praktyki

Podczas zmniejszania pliku weź pod uwagę następujące informacje:

  • Operacja zmniejszania jest najbardziej skuteczna po operacji, która tworzy dużo nieużywanego miejsca, takiej jak operacja obcięcia tabeli lub operacji upuszczenia tabeli.

  • Większość baz danych wymaga pewnej wolnej przestrzeni do regularnych codziennych operacji. Jeśli wielokrotnie zmniejszasz bazę danych i zauważysz, że rozmiar bazy ponownie rośnie, oznacza to, że zmniejszona przestrzeń jest wymagana do regularnych operacji. W takich przypadkach wielokrotne zmniejszanie bazy danych to zmarnowana operacja.

  • Operacja zmniejszania nie zachowuje stanu fragmentacji indeksów w bazie danych i ogólnie zwiększa stopień fragmentacji do pewnego stopnia. To kolejny powód, aby nie zmniejszać wielokrotnie bazy danych.

  • Zmniejsz wiele plików w tej samej bazie danych sekwencyjnie zamiast jednocześnie. Konflikt w tabelach systemowych może powodować opóźnienia z powodu blokowania.

Uwaga:

DBCC SHRINKFILE operacje można zatrzymać w dowolnym momencie procesu, a wszelkie ukończone prace są zachowywane.

Robiąc to, z pewnością należy wziąć pod uwagę kilka rzeczy i polecam zajrzeć na blogu Paula Randala na temat tego, co dzieje się po wykonaniu tej operacji.

Pierwszym krokiem byłoby na pewno sprawdzenie, ile miejsca i wolnego miejsca faktycznie można zastąpić, a także wykorzystanego miejsca w plikach:

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
źródło
6

Jest to normalne zachowanie podczas obcinania tabeli i polegające na usunięciu ponad 128 zakresów w trybie Per Books Online

Po upuszczeniu lub odbudowaniu dużych indeksów lub upuszczeniu lub obcięciu dużych tabel Aparat baz danych odracza faktyczne zwolnienia stron i związane z nimi blokady, aż do momentu zatwierdzenia transakcji. Ta implementacja obsługuje zarówno automatyczne zatwierdzanie, jak i jawne transakcje w środowisku wielu użytkowników i ma zastosowanie do dużych tabel i indeksów, które używają więcej niż 128 zakresów.

Aparat baz danych unika blokad alokacji wymaganych do upuszczenia dużych obiektów, dzieląc proces na dwie oddzielne fazy: logiczną i fizyczną.

W fazie logicznej istniejące jednostki alokacji używane przez tabelę lub indeks są oznaczone do zwolnienia i blokowane do momentu zatwierdzenia transakcji. Po upuszczeniu indeksu klastrowego wiersze danych są kopiowane, a następnie przenoszone do nowych jednostek alokacji utworzonych w sklepie albo przebudowany indeks klastrowy, albo stertę. (W przypadku przebudowy indeksu wiersze danych są również sortowane.) W przypadku wycofania tylko ta logiczna faza musi zostać wycofana.

Faza fizyczna występuje po zatwierdzeniu transakcji. Jednostki alokacji oznaczone do zwolnienia są fizycznie upuszczane partiami. Krople te są obsługiwane w krótkich transakcjach, które występują w tle i nie wymagają wielu blokad.

Ponieważ faza fizyczna występuje po zatwierdzeniu transakcji, miejsce w tabeli lub indeksie może nadal wydawać się niedostępne. Jeśli przestrzeń ta jest wymagana do powiększenia bazy danych przed zakończeniem fazy fizycznej, Aparat baz danych próbuje odzyskać miejsce z jednostek alokacji oznaczonych do zwolnienia. Aby znaleźć miejsce aktualnie używane przez te jednostki alokacji, użyj widoku katalogu sys.allocation_units.

Operacje odroczonego upuszczania nie zwalniają natychmiast przydzielonego miejsca i wprowadzają dodatkowe koszty ogólne w silniku bazy danych. Dlatego tabele i indeksy, które używają 128 lub mniejszych zakresów, są upuszczane, obcinane i przebudowywane, tak jak w SQL Server 2000. Oznacza to, że zarówno logiczna, jak i fizyczna faza zachodzą przed zatwierdzeniem transakcji.

Trzeba będzie poczekać i oczywiście trzeba ręcznie zmniejszyć plik, aby odzyskać miejsce, warto również wspomnieć, że zmniejszanie powoduje logiczną fragmentację i należy tego unikać, chyba że twoja potrzeba jest poważna. Trzeba by się zastanowić, jak zachować równowagę między kurczeniem się a fragmentacją. Lepiej jest zadać sobie pytanie, czy zmniejszenie rzeczywiście rozwiązałoby problem, biorąc pod uwagę scenariusz, w którym dane i tak znów wzrosną.

Użyj poniższego zapytania, aby sprawdzić, ile wolnego miejsca jest w bazie danych

SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;
Shanky
źródło
6

Oprócz odpowiedzi Toma i Shanky'ego, jeśli twoja baza danych zawiera dane LOB / BLOB, DBCC SHRINKFILE może nie działać. W takim przypadku masz dwie opcje, w zależności od tego, czy możesz przełączyć bazę danych w tryb offline, czy nie. Jeśli możesz przełączyć bazę danych w tryb offline, musisz skopiować dane i skopiować je z powrotem, aby usunąć puste miejsce. Możesz to zrobić, wykonując jedną z następujących czynności:

  1. Używanie instrukcji SELECT INTO do przeniesienia całej tabeli do nowej tabeli. Upuść oryginalną tabelę, uruchom DBCC SHRINKFILE . Zmień nazwę nowej tabeli na pierwotną nazwę tabeli.
  2. Używając programu bcp do skopiowania tabeli w trybie macierzystym, upuść tabelę, uruchom DBCC SHRINKFILE , utwórz tabelę, a następnie bcp dane do tabeli.
  3. Za pomocą opcji Eksportuj / Importuj przenieś wszystkie dane do nowej bazy danych, usuń istniejącą bazę danych, zmień nazwę nowej bazy danych na pierwotną nazwę bazy danych.

Jeśli nie możesz przełączyć bazy danych w tryb offline, możesz użyć komendy DBCC SHRINKFILE z opcją EMPTYFILE .

Szczegóły dotyczące kopii offline: http://support.microsoft.com/kb/324432/en-us

Bieżące informacje dla opcji EMPTYFILE http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx

stacylaray
źródło