Udostępnij za pośrednictwem


DBCC SHRINKFILE (Transact-SQL)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Zmniejsza rozmiar określonego pliku dziennika lub danych bieżącej bazy danych. Można go użyć do przenoszenia danych z jednego pliku do innych plików w tej samej grupie plików, która opróżnia plik i umożliwia usunięcie bazy danych. Możesz zmniejszyć rozmiar pliku do mniejszego niż rozmiar podczas tworzenia, zresetować minimalny rozmiar pliku do nowej wartości. Używaj pliku DBCC SHRINKFILE tylko wtedy, gdy jest to konieczne.

Notatka

Operacje zmniejszania nie powinny być traktowane jako regularne operacje konserwacji. Pliki danych i dzienników, które rosną z powodu regularnych, cyklicznych operacji biznesowych nie wymagają operacji zmniejszania.

Transact-SQL konwencje składni

Składnia

DBCC SHRINKFILE   
(  
    { file_name | file_id }   
    { [ , EMPTYFILE ]   
    | [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]  
    }  
)  
[ WITH 
  {     
      [ WAIT_AT_LOW_PRIORITY 
        [ ( 
            <wait_at_low_priority_option_list>
        )] 
      ] 
      [ , NO_INFOMSGS]
  }
]
       
< wait_at_low_priority_option_list > ::=  
    <wait_at_low_priority_option>
    | <wait_at_low_priority_option_list> , <wait_at_low_priority_option>
 
< wait_at_low_priority_option > ::=
    ABORT_AFTER_WAIT = { SELF | BLOCKERS }

Argumenty

file_name

Nazwa logiczna pliku, który ma zostać zmniejszony.

file_id

Numer identyfikacyjny (ID) pliku, który ma zostać zmniejszony. Aby uzyskać identyfikator pliku, użyj funkcji systemu FILE_IDEX lub wykonaj zapytanie dotyczące widoku wykazu sys.database_files w bieżącej bazie danych.

target_size

Liczba całkowita reprezentująca nowy rozmiar megabajtu pliku. Jeśli nie określono wartości lub 0, DBCC SHRINKFILE zmniejsza rozmiar tworzenia pliku.

Rozmiar domyślny pustego pliku można zmniejszyć przy użyciu DBCC SHRINKFILE <target_size>. Jeśli na przykład utworzysz plik o rozmiarze 5 MB, a następnie zmniejsz plik do 3 MB, gdy plik jest nadal pusty, domyślny rozmiar pliku jest ustawiony na 3 MB. Dotyczy to tylko pustych plików, które nigdy nie zawierały danych.

Ta opcja nie jest obsługiwana w przypadku kontenerów filegroup FILESTREAM.

Jeśli zostanie to określone, DBCC SHRINKFILE spróbuje zmniejszyć plik do docelowego rozmiaru . Strony używane w obszarze pliku, które mają zostać zwolnione, są przenoszone do wolnej przestrzeni w zachowanych obszarach pliku. Na przykład w przypadku pliku danych o rozmiarze 10 MB operacja DBCC SHRINKFILE z 8target_size przenosi wszystkie używane strony w ciągu ostatnich 2 MB pliku do jakichkolwiek nieprzydzielonych stron w pierwszych 8 MB pliku. DBCC SHRINKFILE nie zmniejsza pliku poza wymaganym rozmiarem przechowywanych danych. Na przykład, jeśli zużyto 7 MB z pliku danych o rozmiarze 10 MB, instrukcja DBCC SHRINKFILE z docelowym rozmiarem o wartości 6 zmniejsza plik do 7 MB, a nie do planowanych 6 MB.

PUSTY PLIK

Migruje wszystkie dane z określonego pliku do innych plików w tej samej grupie plików. Innymi słowy, EMPTYFILE migruje dane z określonego pliku do innych plików w tej samej grupie plików. EMPTYFILE zapewnia, że żadne nowe dane nie zostaną dodane do pliku, mimo że ten plik nie jest tylko do odczytu. Aby usunąć plik, możesz użyć instrukcji ALTER DATABASE. Jeśli używasz instrukcji ALTER DATABASE w celu zmiany rozmiaru pliku, flaga tylko do odczytu zostanie zresetowana i można dodać dane.

W przypadku kontenerów grupy plików FILESTREAM nie można użyć ALTER DATABASE do usunięcia pliku, dopóki moduł zbierania śmieci FILESTREAM nie zostanie uruchomiony i nie usunie wszystkich niepotrzebnych plików kontenerów grupy plików, które zostały skopiowane do innego kontenera przez EMPTYFILE. Aby uzyskać więcej informacji, zobacz sp_filestream_force_garbage_collection. Aby uzyskać informacje na temat usuwania kontenera FILESTREAM, zobacz odpowiednią sekcję w ALTER DATABASE File and Filegroup Options (Transact-SQL)

EMPTYFILE nie jest obsługiwana w usłudze Azure SQL Database ani w hiperskala usługi Azure SQL Database.

NOTRUNCATE

Przenosi przydzielone strony z końca pliku danych do nieprzydzielonych stron na początku pliku z lub bez określania target_percent. Wolne miejsce na końcu pliku nie jest zwracane do systemu operacyjnego, a rozmiar fizyczny pliku nie zmienia się. W związku z tym, jeśli NOTRUNCATE jest określony, plik wydaje się nie zmniejszać.

NOTRUNCATE dotyczy tylko plików danych. Nie ma to wpływu na pliki dziennika.

Ta opcja nie jest obsługiwana w przypadku kontenerów filegroup FILESTREAM.

TRUNCATEONLY

Zwalnia całe wolne miejsce znajdujące się na końcu pliku i zwraca je do systemu operacyjnego, ale nie dokonuje żadnego przenoszenia stron wewnątrz pliku. Plik danych jest zmniejszany tylko do ostatniego przydzielonego zakresu.

target_size jest ignorowany, jeśli jest określony razem z parametrem TRUNCATEONLY.

Opcja TRUNCATEONLY nie przenosi informacji w dzienniku, ale usuwa nieaktywne funkcje VFS z końca pliku dziennika. Ta opcja nie jest obsługiwana w przypadku kontenerów filegroup FILESTREAM.

Z NO_INFOMSGS

Pomija wszystkie komunikaty informacyjne.

WAIT_AT_LOW_PRIORITY z operacjami zmniejszania

Dotyczy: SQL Server 2022 (16.x) i nowsze wersje, Azure SQL Database, Azure SQL Managed Instance

Funkcja oczekiwania na niskim priorytcie zmniejsza rywalizację o blokadę. Aby uzyskać więcej informacji, zobacz Zrozumienie problemów związanych z współbieżnością w DBCC SHRINKDATABASE.

Ta funkcja jest podobna do WAIT_AT_LOW_PRIORITY w operacjach na indeksach online, ale istnieją pewne różnice.

  • Nie można określić opcji ABORT_AFTER_WAIT jako NONE.

CZEKAJ_NISKI_PRIORYTET

Dotyczy: SQL Server (SQL Server 2022 (16.x) i nowsze) oraz Azure SQL Database).

Gdy polecenie zmniejszania jest wykonywane w trybie WAIT_AT_LOW_PRIORITY, nowe zapytania wymagające stabilności schematu (Sch-S) nie są blokowane przez oczekującą operację zmniejszania, dopóki operacja zmniejszania nie przestanie czekać i rozpocznie wykonywanie. Operacja zmniejszania jest wykonywana, gdy możliwe jest uzyskanie blokady modyfikacji schematu (Sch-M). Jeśli nowa operacja zmniejszania w trybie WAIT_AT_LOW_PRIORITY nie może uzyskać blokady z powodu długotrwałego zapytania, operacja zmniejszania wygaśnie po 1 minucie i zakończy się dyskretnie, domyślnie.

Jeśli nowa operacja zmniejszania w trybie WAIT_AT_LOW_PRIORITY nie może uzyskać blokady z powodu długotrwałego zapytania, operacja zmniejszania wygaśnie domyślnie po jednej minucie i zakończy się bez informowania użytkownika. Dzieje się tak, jeśli operacja zmniejszania nie może uzyskać blokady Sch-M z powodu współbieżnych zapytań utrzymujących blokady Sch-S. Gdy wystąpi przekroczenie limitu czasu, błąd 49516 jest wysyłany do dziennika błędów programu SQL Server, na przykład: Msg 49516, Level 16, State 1, Line 134 Shrink timeout waiting to acquire schema modify lock in WLP mode to process IAM pageID 1:2865 on database ID 5. Spróbuj ponownie wykonać operację zmniejszania w trybie WAIT_AT_LOW_PRIORITY.

ABORT_AFTER_WAIT = [ SELF | BLOKERY ]

Dotyczy: SQL Server (SQL Server 2022 (16.x) i nowsze wersje) oraz Azure SQL Database.

  • JAŹŃ

    Zakończ operację zmniejszania pliku, która jest obecnie wykonywana bez podejmowania żadnej akcji.

  • BLOKERY

    Zabij wszystkie transakcje użytkownika, które blokują operację zmniejszania pliku, aby operacja mogła kontynuować. Aby skorzystać z opcji BLOCKERS, login musi mieć uprawnienie ALTER ANY CONNECTION.

Zestaw wyników

W poniższej tabeli opisano kolumny zestawu wyników.

Nazwa kolumny Opis
DbId Numer identyfikacyjny pliku bazy danych, który silnik bazy danych próbował zmniejszyć.
FileId Numer identyfikacyjny pliku, który silnik bazy danych próbował zmniejszyć.
CurrentSize Liczba stron 8 KB, które obecnie zajmuje plik.
MinimumSize Liczba 8 KB stron, które plik może zajmować co najmniej. Ta liczba odpowiada minimalnemu rozmiarowi lub pierwotnie utworzonemu rozmiarowi pliku.
UsedPages Liczba stron 8 KB używanych obecnie przez plik.
EstimatedPages Liczba stron o rozmiarze 8 KB, do jakiej silnik bazy danych szacuje, że można zmniejszyć plik.

Uwagi

DBCC SHRINKFILE dotyczy plików bieżącej bazy danych. Aby uzyskać więcej informacji na temat zmiany bieżącej bazy danych, zobacz USE (Transact-SQL).

Operacje DBCC SHRINKFILE można zatrzymać w dowolnym momencie, a wszystkie ukończone prace zostaną zachowane. Jeśli używasz parametru EMPTYFILE i anulujesz operację, plik nie zostanie oznaczony, aby zapobiec dodawaniu dodatkowych danych.

Gdy operacja DBCC SHRINKFILE zakończy się niepowodzeniem, zostanie zgłoszony błąd.

Inni użytkownicy mogą pracować w bazie danych podczas zmniejszania pliku; baza danych nie musi być w trybie pojedynczego użytkownika. Nie trzeba uruchamiać wystąpienia programu SQL Server w trybie jednego użytkownika, aby zmniejszyć systemowe bazy danych.

Po zastosowaniu opcji WAIT_AT_LOW_PRIORITY, żądanie blokady Sch-M będzie czekać z niskim priorytetem na wykonanie polecenia przez 1 minutę. Jeśli operacja zostanie zablokowana na określony czas, zostanie wykonana określona akcja ABORT_AFTER_WAIT.

Znane problemy

Dotyczy: SQL Server, Azure SQL Database, Azure SQL Managed Instance, dedykowana pula SQL usługi Azure Synapse Analytics

  • Obecnie typy kolumn LOB (varbinary(max), varchar(max)i nvarchar(max)) w skompresowanych segmentach kolumnowego magazynu danych nie są wpływane przez DBCC SHRINKDATABASE i DBCC SHRINKFILE.

Zrozum problematyczną współbieżność związaną z DBCC SHRINKFILE

Polecenia zmniejszania bazy danych i zmniejszania pliku mogą prowadzić do problemów ze współbieżnością, zwłaszcza w przypadku aktywnej konserwacji, takiej jak ponowne kompilowanie indeksów lub w zajętych środowiskach OLTP. Gdy aplikacja wykonuje zapytania względem tabel bazy danych, te zapytania będą uzyskiwać i utrzymywać blokadę stabilności schematu (Sch-S), dopóki zapytania nie zakończą swoich operacji. Podczas próby odzyskania miejsca podczas regularnego użytkowania, operacje zmniejszania bazy danych i plików wymagają obecnie blokady modyfikacji schematu (Sch-M) podczas przemieszczania lub usuwania stron IAM, blokując blokady Sch-S wymagane przez zapytania użytkowników. W związku z tym długotrwałe zapytania blokują operację zmniejszania do momentu ukończenia zapytań. Oznacza to, że wszystkie nowe zapytania wymagające blokad Sch-S są również ustawiane w kolejce za oczekującą operacją zmniejszania i będą również blokowane, co jeszcze bardziej pogłębia ten problem ze współbieżnością. Może to znacząco wpłynąć na wydajność zapytań aplikacji, co spowoduje również trudności z ukończeniem niezbędnej konserwacji w celu zmniejszenia plików bazy danych. Wprowadzona w programie SQL Server 2022 (16.x) funkcja zmniejszenia oczekiwania przy niskim priorytecie rozwiązuje ten problem przez przyjmowanie blokady modyfikacji schematu w trybie WAIT_AT_LOW_PRIORITY. Aby uzyskać więcej informacji, zobacz WAIT_AT_LOW_PRIORITY z operacjami zmniejszania.

Aby uzyskać więcej informacji na temat blokad Sch-S i Sch-M, przejrzyj przewodnik Blokowanie transakcji i wersjonowanie wierszy.

Zmniejszanie pliku dziennika

W przypadku plików dziennika silnik baz danych używa target_size do obliczania docelowego rozmiaru całkowitego dziennika. W związku z tym target_size jest na wolnej przestrzeni dziennika po operacji zmniejszania. Rozmiar docelowy całego dziennika jest następnie tłumaczony na rozmiar docelowy każdego pliku dziennika. DBCC SHRINKFILE próbuje natychmiast zmniejszyć rozmiar każdego fizycznego pliku dziennika do rozmiaru docelowego. Jeśli jednak część dziennika logicznego znajduje się w dziennikach wirtualnych poza rozmiarem docelowym, aparat bazy danych zwalnia jak najwięcej miejsca, a następnie wysyła komunikat informacyjny. Komunikat zawiera opis akcji wymaganych do przeniesienia dziennika logicznego z dzienników wirtualnych na końcu pliku. Po wykonaniu akcji można użyć DBCC SHRINKFILE, aby zwolnić pozostałe miejsce.

Ponieważ plik dziennika może być ograniczony tylko do wirtualnej granicy pliku dziennika, zmniejszanie pliku dziennika do rozmiaru mniejszego niż rozmiar pliku dziennika wirtualnego może nie być możliwe, nawet jeśli nie jest używany. Silnik bazy danych dynamicznie wybiera rozmiar wirtualnego dziennika pliku podczas tworzenia lub rozszerzania plików dziennika.

Najlepsze rozwiązania

Podczas planowania zmniejszania pliku należy wziąć pod uwagę następujące informacje:

  • Operacja zmniejszania jest najbardziej efektywna po operacji, która tworzy dużą ilość nieużywanego miejsca, na przykład obcięcie tabeli lub operację usuwania tabeli.

  • W przypadku codziennych operacji większość baz danych wymaga wolnego miejsca. Jeśli wielokrotnie zmniejszasz plik bazy danych i zauważasz, że rozmiar bazy danych ponownie wzrośnie, oznacza to, że wolne miejsce jest wymagane do regularnych operacji. W takich przypadkach wielokrotne zmniejszanie pliku bazy danych to zmarnowana operacja. Zdarzenia automatycznego zwiększania rozmiaru pliku bazy danych mogą utrudniać wydajność.

  • Operacja kompresji nie zachowuje stanu fragmentacji indeksów w bazie danych i zazwyczaj prowadzi do pewnego stopnia zwiększenia fragmentacji. Ta fragmentacja jest kolejnym powodem, dla którego nie należy wielokrotnie zmniejszać bazy danych.

  • Zmniejsz wiele plików w tej samej bazie danych sekwencyjnie zamiast współbieżnie. Konflikt dotyczący tabel systemowych może powodować zablokowanie i prowadzić do opóźnień.

Rozwiązywanie problemów

W tej sekcji opisano sposób diagnozowania i rozwiązywania problemów, które mogą wystąpić podczas uruchamiania polecenia DBCC SHRINKFILE.

Plik nie zmniejsza się

Jeśli rozmiar pliku nie zmieni się po operacji zmniejszania bez błędów, spróbuj wykonać następujące czynności, aby sprawdzić, czy plik ma odpowiednie wolne miejsce:

  • Uruchom następujące zapytanie.
SELECT name
    , size / 128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0 AS AvailableSpaceInMB
FROM sys.database_files;
  • Uruchom polecenie DBCC SQLPERF, aby zwrócić miejsce używane w dzienniku transakcji.

Operacja zmniejszania nie może jeszcze zmniejszyć rozmiaru pliku, jeśli jest za mało wolnego miejsca.

Zazwyczaj jest to plik dziennika, który wydaje się nie zmniejszać, zazwyczaj wynik pliku dziennika, który nie został obcięty przez zwykłą kopię zapasową dziennika transakcji. Aby obcinać dziennik, utwórz kopię zapasową dziennika transakcji, a następnie ponownie uruchom operację DBCC SHRINKFILE. Jeśli odzyskiwanie do punktu w czasie nie jest wymagane, rozważ model odzyskiwania bazy danych SIMPLE.

Operacja zmniejszania jest zablokowana

Transakcja uruchomiona w ramach poziomu izolacji opartej na wersji wiersza może blokować operacje zmniejszania. Na przykład, jeśli duża operacja usuwania uruchomiona w ramach poziomu izolacji opartego na wersjonowaniu wierszy jest w toku, gdy wykonywana jest operacja DBCC SHRINKDATABASE, operacja zmniejszania czeka na zakończenie usuwania przed kontynuowaniem. W przypadku tego blokowania operacje DBCC SHRINKFILE i DBCC SHRINKDATABASE wyświetlają komunikat informacyjny (5202 dla SHRINKDATABASE i 5203 dla SHRINKFILE) do dziennika błędów programu SQL Server. Ten komunikat jest rejestrowany co pięć minut w ciągu pierwszej godziny, a następnie co godzinę. Na przykład:

DBCC SHRINKFILE for file ID 1 is waiting for the snapshot
transaction with timestamp 15 and other snapshot transactions linked to
timestamp 15 or with timestamps older than 109 to finish.

Ten komunikat oznacza, że transakcje typu migawki ze znacznikami czasu starszymi niż 109 (ostatnia transakcja ukończona przez operację zmniejszania) blokują operację zmniejszania. Wskazuje także, że kolumny transaction_sequence_numlub first_snapshot_sequence_num w widoku dynamicznego zarządzania sys.dm_tran_active_snapshot_database_transactions zawierają wartość 15. Jeśli kolumna widoku transaction_sequence_num lub first_snapshot_sequence_num zawiera liczbę mniejszą niż ostatnia zakończona transakcja operacji zmniejszania (109), operacja zmniejszania czeka na zakończenie tych transakcji.

Aby rozwiązać ten problem, możesz wykonać jedno z następujących zadań:

  • Zakończ transakcję blokującą operację zmniejszania.
  • Zakończ operację zmniejszania. Ukończone zadania są zachowywane, jeśli operacja zmniejszania dojdzie do końca.
  • Nie rób nic i pozwól, by operacja zmniejszania czekała na zakończenie blokującej transakcji.

Uprawnienia

Wymaga członkostwa w ustalonej roli serwera sysadmin lub w ustalonej roli bazy danych db_owner.

Przykłady

A. Zmniejszanie pliku danych do określonego rozmiaru docelowego

Poniższy przykład zmniejsza rozmiar pliku danych o nazwie DataFile1 w bazie danych użytkownika UserDB do 7 MB.

USE UserDB;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO

B. Zmniejszanie pliku dziennika do określonego rozmiaru docelowego

Poniższy przykład zmniejsza plik dziennika w bazie danych AdventureWorks2022 do 1 MB. Aby umożliwić zmniejszenie pliku za pomocą polecenia DBCC SHRINKFILE, plik jest najpierw obcinany, poprzez ustawienie modelu odzyskiwania bazy danych na SIMPLE.

USE AdventureWorks2022;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2022
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2022_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2022
SET RECOVERY FULL;
GO

C. Skrócić plik danych

Poniższy przykład obcina podstawowy plik danych w bazie danych AdventureWorks2022. Widok katalogu sys.database_files jest odpytywany, aby uzyskać file_id pliku danych.

USE AdventureWorks2022;
GO
SELECT file_id, name
FROM sys.database_files;
GO
DBCC SHRINKFILE (1, TRUNCATEONLY);

D. Opróżnianie pliku

W poniższym przykładzie pokazano opróżnianie pliku, aby można go było usunąć z bazy danych. Na potrzeby tego przykładu plik danych jest najpierw tworzony i zawiera dane.

USE AdventureWorks2022;
GO
-- Create a data file and assume it contains data.
ALTER DATABASE AdventureWorks2022
ADD FILE (
    NAME = Test1data,
    FILENAME = 'C:\t1data.ndf',
    SIZE = 5MB
    );
GO
-- Empty the data file.
DBCC SHRINKFILE (Test1data, EMPTYFILE);
GO
-- Remove the data file from the database.
ALTER DATABASE AdventureWorks2022
REMOVE FILE Test1data;
GO

E. Zmniejszanie pliku bazy danych przy użyciu WAIT_AT_LOW_PRIORITY

Poniższy przykład próbuje zmniejszyć rozmiar pliku danych w bieżącej bazie danych użytkownika do 1 MB. Aby uzyskać file_id pliku danych, zostanie zapytany widok wykazu sys.database_files, w tym przykładzie file_id 5. Jeśli nie można uzyskać blokady w ciągu jednej minuty, operacja zmniejszania przerywa.

USE AdventureWorks2022;
GO

SELECT file_id, name
FROM sys.database_files;
GO

DBCC SHRINKFILE (5, 1) WITH WAIT_AT_LOW_PRIORITY (ABORT_AFTER_WAIT = SELF);