Dela via


DBCC SHRINKFILE (Transact-SQL)

gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Krymper den aktuella databasens angivna data- eller loggfilstorlek. Du kan använda den för att flytta data från en fil till andra filer i samma filgrupp, vilket tömmer filen och tillåter borttagning av databasen. Du kan krympa en fil till mindre än dess storlek när den skapas och återställa den minsta filstorleken till det nya värdet. Använd endast DBCC SHRINKFILE när det behövs.

Observera

Krympningsåtgärder bör inte betraktas som en vanlig underhållsåtgärd. Data och loggfiler som växer på grund av regelbundna, återkommande affärsåtgärder kräver inte krympningsåtgärder.

Transact-SQL syntaxkonventioner

Syntax

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 }

Argument

file_name

Den logiska namnet på filen som ska krympas.

file_id

Filens ID-nummer för den fil som ska krympas. Om du vill hämta ett fil-ID använder du FILE_IDEX-systemfunktionen eller använder frågan i sys.database_files-katalogvyn i den aktuella databasen.

målstorlek

Ett heltal som representerar filens nya megabytestorlek. Om det inte anges eller 0 minskas DBCC SHRINKFILE till filgenereringsstorleken.

Du kan minska standardstorleken för en tom fil med DBCC SHRINKFILE <target_size>. Om du till exempel skapar en 5 MB-fil och sedan krymper filen till 3 MB medan filen fortfarande är tom, är standardfilens storlek inställd på 3 MB. Detta gäller endast för tomma filer som aldrig har innehållit data.

Det här alternativet stöds inte för FILESTREAM-filgruppscontainrar.

Om det anges försöker DBCC SHRINKFILE krympa filen till target_size. Använda sidor i filens område som ska frigöras flyttas till ledigt utrymme i filens behållna områden. Med en datafil på 10 MB flyttas till exempel en DBCC SHRINKFILE-åtgärd med en 8target_size alla använda sidor i filens sista 2 MB till alla oallokerade sidor i filens första 8 MB. DBCC SHRINKFILE krymper inte en fil efter den nödvändiga lagrade datastorleken. Om till exempel 7 MB av en datafil på 10 MB används, krymper en DBCC SHRINKFILE-instruktion med en target_size på 6 filen till endast 7 MB, inte 6 MB.

TOMFIL

Migrerar alla data från den angivna filen till andra filer i samma filgrupp. Med andra ord migrerar EMPTYFILE data från en angiven fil till andra filer i samma filgrupp. EMPTYFILE försäkrar dig om att inga nya data läggs till i filen, trots att filen inte är skrivskyddad. Du kan använda instruktionen ALTER DATABASE för att ta bort en fil. Om du använder instruktionen ALTER DATABASE för att ändra filstorlek återställs den skrivskyddade flaggan och data kan läggas till.

För FILESTREAM-filgruppscontainrar kan du inte använda ALTER DATABASE för att ta bort en fil förrän FILESTREAM-skräpinsamlaren har kört och tagit bort alla onödiga filgruppscontainerfiler som EMPTYFILE har kopierat till en annan container. Mer information finns i sp_filestream_force_garbage_collection. Information om hur du tar bort en FILESTREAM-container finns i motsvarande avsnitt i ALTER DATABASE File and Filegroup Options (Transact-SQL)

EMPTYFILE stöds inte i Azure SQL Database eller Azure SQL Database Hyperscale.

NOTRUNCATE

Flyttar allokerade sidor från en datafils slut till oallokerade sidor i en fils front med eller utan att ange target_percent. Det lediga utrymmet i filens slut returneras inte till operativsystemet och filens fysiska storlek ändras inte. Om NOTRUNCATE anges verkar filen därför inte krympa.

NOTRUNCATE gäller endast för datafiler. Loggfilerna påverkas inte.

Det här alternativet stöds inte för FILESTREAM-filgruppscontainrar.

TRUNKERA ENDAST

Frigör allt ledigt utrymme i slutet av filen till operativsystemet, men utför ingen sidflytt i filen. Datafilen krymps endast till den senaste allokerade omfattningen.

target_size ignoreras om det anges tillsammans med TRUNCATEONLY.

Alternativet TRUNCATEONLY flyttar inte information i loggen, men tar bort inaktiva VLFs från slutet av loggfilen. Det här alternativet stöds inte för FILESTREAM-filgruppscontainrar.

MED NO_INFOMSGS

Undertrycker alla informationsmeddelanden.

WAIT_AT_LOW_PRIORITY med krympningsoperationer

gäller för: SQL Server 2022 (16.x) och senare versioner, Azure SQL Database, Azure SQL Managed Instance

Funktionen "vänta med låg prioritet" minskar låskonkurrationen. Mer information finns i Förstå samtidighetsproblem med DBCC SHRINKDATABASE.

Den här funktionen liknar WAIT_AT_LOW_PRIORITY med onlineindexåtgärder, med vissa skillnader.

  • Du kan inte ange alternativet ABORT_AFTER_WAIT som NONE.

Vänta med låg prioritet

gäller för: SQL Server (SQL Server 2022 (16.x) och senare) och Azure SQL Database.

När ett krympningskommando körs i WAIT_AT_LOW_PRIORITY-läge blockeras inte nya frågor som kräver låsen för schemastabilitet (Sch-S) av den väntande krympningsåtgärden förrän krympningsåtgärden slutar vänta och börjar köras. Krympningsåtgärden körs när den kan hämta ett schemamodifieringslås (Sch-M). Om en ny krympningsåtgärd i läget WAIT_AT_LOW_PRIORITY inte kan hämta ett lås på grund av en långvarig fråga kommer krympningsåtgärden slutligen att överskrida tidsgränsen efter 1 minut som standardinställning och avslutas utan att märkas.

Om en ny krympningsåtgärd i läget WAIT_AT_LOW_PRIORITY inte kan hämta ett lås på grund av en tidskrävande fråga, kommer krympningsåtgärden slutligen att överskrida tidsgränsen efter 1 minut som standard och avslutas utan meddelande. Detta inträffar om krympningsåtgärden inte kan hämta Sch-M-låset på grund av samtidiga frågor eller att frågor innehar Sch-S-lås. När en timeout inträffar skickas fel 49516 till SQL Server-felloggen, till exempel: 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. Försök igen krympningsoperationen i WAIT_AT_LOW_PRIORITY-läget.

ABORT_AFTER_WAIT = [ SELF | BLOCKERS ]

gäller för: SQL Server (SQL Server 2022 (16.x) och senare) och Azure SQL Database.

  • SJÄLV

    Avsluta den krympningsfilåtgärd som för närvarande körs utan att vidta några åtgärder.

  • SPÄRRAR

    Avsluta alla användartransaktioner som blockerar krympningsfilåtgärden så att åtgärden kan fortsätta. Alternativet BLOCKERS kräver att inloggningen har behörigheten ÄNDRA ALLA ANSLUTNINGAR.

Resultatuppsättning

I följande tabell beskrivs kolumner för resultatuppsättningar.

Kolumnnamn Beskrivning
DbId Databasidentifieringsnumret för filen som databasmotorn försökte krympa.
FileId Filidentifieringsnumret för filen som databasmotorn försökte krympa.
CurrentSize Antal 8 KB-sidor som filen för närvarande upptar.
MinimumSize Antal 8-KB-sidor som filen minst kan uppta. Det här talet motsvarar den minsta storleken eller ursprungligen skapade storleken på en fil.
UsedPages Antal 8 KB-sidor som för närvarande används av filen.
EstimatedPages Antal 8 KB-sidor som databasmotorn uppskattar att filen kan krympas ned till.

Anmärkningar

DBCC SHRINKFILE gäller för den aktuella databasens filer. Mer information om hur du ändrar den aktuella databasen finns i USE (Transact-SQL).

Du kan stoppa DBCC SHRINKFILE åtgärder när som helst och allt slutfört arbete bevaras. Om du använder parametern EMPTYFILE och avbryter åtgärden markeras inte filen för att förhindra att ytterligare data läggs till.

När en DBCC SHRINKFILE åtgärd misslyckas utlöses ett fel.

Andra användare kan arbeta i databasen när filen krymper. databasen behöver inte vara i enanvändarläge. Du behöver inte köra instansen av SQL Server i enanvändarläge för att krympa systemdatabaserna.

När den specificeras med WAIT_AT_LOW_PRIORITY kommer krympåtgärdens Sch-M-låsbegäran att vänta med låg prioritet under körningen av kommandot i 1 minut. Om operationen blockeras under varaktigheten kommer den angivna åtgärden ABORT_AFTER_WAIT att köras.

Kända problem

gäller för: SQL Server, Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics dedikerad SQL-pool

  • För närvarande påverkas inte LOB-kolumntyper (varbinary(max), varchar(max)och nvarchar(max)) i komprimerade kolumnlagringssegment av DBCC SHRINKDATABASE och DBCC SHRINKFILE.

Förstå samtidighetsproblem med DBCC SHRINKFILE

Krympdatabasen och krympningsfilkommandona kan leda till samtidighetsproblem, särskilt med aktivt underhåll, till exempel återskapa index eller i upptagna OLTP-miljöer. När din applikation kör frågor mot databastabeller hämtar och upprätthåller dessa frågor ett schemastabilitetslås (Sch-S) tills de har slutfört sina åtgärder. När du försöker frigöra utrymme under regelbunden användning kräver operationer för att krympa databasen och krympa filer för närvarande ett schemaändringslås (Sch-M) när du flyttar eller tar bort IAM-sidor (Index Allocation Map), vilket blockerar de lås av typ Sch-S som krävs av användarfrågor. Därför blockerar långvariga sökfrågor en krympningsåtgärd tills sökfrågorna är klara. Det innebär att alla nya förfrågningar som kräver Sch-S-lås också placeras i kö bakom den väntande krympningsoperationen och även blockeras, vilket ytterligare förvärrar problemet med samtidighet. Detta kan avsevärt påverka programmets frågeprestanda och orsaka problem med att slutföra det nödvändiga underhållet för att krympa databasfiler. Funktionen för att krympa med låg prioritet i SQL Server 2022 (16.x) åtgärdar problemet genom att ta ett schemamodifieringslås i WAIT_AT_LOW_PRIORITY-läge. För mer information, se WAIT_AT_LOW_PRIORITY med komprimeringsoperationer.

För mer information om Sch-S- och Sch-M-lås, se Transaktionslåsning och radversionshanteringsguide.

Krympa en loggfil

För loggfiler använder databasmotorn target_size för att beräkna hela loggens målstorlek. Därför är target_size loggens lediga utrymme efter krympningsåtgärden. Hela loggens målstorlek översätts sedan till varje loggfils målstorlek. DBCC SHRINKFILE försöker krympa varje fysisk loggfil till målstorleken omedelbart. Men om en del av den logiska loggen finns i de virtuella loggarna utöver målstorleken frigör databasmotorn så mycket utrymme som möjligt och utfärdar sedan ett informationsmeddelande. Meddelandet beskriver vilka åtgärder som krävs för att flytta den logiska loggen från de virtuella loggarna i slutet av filen. När åtgärderna har utförts kan DBCC SHRINKFILE användas för att frigöra återstående utrymme.

Eftersom en loggfil bara kan krympas till en gräns för en virtuell loggfil kanske det inte går att krympa en loggfil till en storlek som är mindre än storleken på en virtuell loggfil, även om den inte används. Databasmotorn väljer dynamiskt storleken på den virtuella filloggen när loggfiler skapas eller utökas.

Metodtips

Tänk på följande information när du planerar att krympa en fil:

  • En krympningsåtgärd är mest effektiv efter en åtgärd som skapar en stor mängd oanvänt utrymme, till exempel en trunkeringstabell eller en drop table-åtgärd.

  • De flesta databaser kräver lite ledigt utrymme för regelbundna dagliga åtgärder. Om du krymper en databasfil upprepade gånger och märker att databasstorleken växer igen, anger detta att ledigt utrymme krävs för vanliga åtgärder. I dessa fall är det en bortkastad åtgärd att upprepade gånger krympa databasfilen. Autogrow-händelser som krävs för att utöka databasfilen påverkar prestandan negativt.

  • En krympningsåtgärd bevarar inte fragmenteringstillståndet för index i databasen och ökar vanligtvis fragmenteringen i viss utsträckning. Den här fragmenteringen är en annan anledning till att inte krympa databasen upprepade gånger.

  • Krymp flera filer i samma databas sekventiellt i stället för samtidigt. Konflikter i systemtabeller kan orsaka blockering och leda till fördröjningar.

Felsöka

I det här avsnittet beskrivs hur du diagnostiserar och korrigerar problem som kan uppstå när du kör kommandot DBCC SHRINKFILE.

Filen krymper inte

Om filstorleken inte ändras efter en felfri krympningsåtgärd kan du prova följande för att kontrollera att filen har tillräckligt med ledigt utrymme:

  • Kör följande fråga.
SELECT name
    , size / 128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0 AS AvailableSpaceInMB
FROM sys.database_files;
  • Kör kommandot DBCC SQLPERF för att returnera det utrymme som används i transaktionsloggen.

Krympningsåtgärden kan inte minska filstorleken ytterligare om det inte finns tillräckligt med ledigt utrymme.

Vanligtvis är det loggfilen som inte verkar krympa, vilket oftast är resultatet av att loggfilen inte har trunkerats genom en regelbunden säkerhetskopia av transaktionsloggen. Om du vill trunkera loggen säkerhetskopierar du transaktionsloggen och kör sedan åtgärden DBCC SHRINKFILE igen. Om återställning vid en viss tidpunkt inte krävs, bör du överväga SIMPLE-databasåterställningsmodellen.

Krympåtgärden blockeras

En transaktion som körs under en radversionsbaserad isoleringsnivå kan blockera krympningsåtgärder. Om en stor borttagningsåtgärd som körs under en radversionsbaserad isoleringsnivå pågår när en DBCC SHRINKDATABASE-åtgärd körs, väntar en krympningsåtgärd på att borttagningen ska slutföras innan den fortsätter. När blockeringen sker skriver DBCC SHRINKFILE och DBCC SHRINKDATABASE åtgärder ut ett informationsmeddelande (5202 för SHRINKDATABASE och 5203 för SHRINKFILE) till SQL Server-felloggen. Det här meddelandet loggas var femte minut under den första timmen och sedan varje timme. Till exempel:

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.

Det här meddelandet innebär att ögonblicksbildtransaktioner med tidsstämplar som är äldre än 109 (den senaste transaktionen som krympningsåtgärden slutförde) blockerar krympningsåtgärden. Det anger också att kolumnerna transaction_sequence_numeller first_snapshot_sequence_num i den dynamiska hanteringsvyn sys.dm_tran_active_snapshot_database_transactions innehåller värdet 15. Om kolumnen transaction_sequence_num eller first_snapshot_sequence_num innehåller ett tal som är mindre än den senaste slutförda transaktionen (109) för en krympningsåtgärd, väntar krympningsåtgärden på att dessa transaktioner ska slutföras.

Du kan lösa problemet genom att utföra någon av följande uppgifter:

  • Avsluta transaktionen som blockerar krympningsåtgärden.
  • Avsluta krympningsåtgärden. Allt utfört arbete behålls om krympningsåtgärden avslutas.
  • Gör ingenting och låt krympningsåtgärden vänta tills den blockerande transaktionen har slutförts.

Behörigheter

Kräver medlemskap i sysadmin fast serverroll eller db_owner fast databasroll.

Exempel

A. Krymp en datafil till en angiven målstorlek

I följande exempel krymps storleken på en datafil med namnet DataFile1 i UserDB användardatabas till 7 MB.

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

B. Krymp en loggfil till en angiven målstorlek

I följande exempel krymper loggfilen i AdventureWorks2022-databasen till 1 MB. För att tillåta att DBCC SHRINKFILE-kommandot krymper filen, trunkeras den först genom att databasåterställningsmodellen anges till ENKEL.

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. Trunkera en datafil

Följande exempel trunkar den primära datafilen i AdventureWorks2022-databasen. sys.database_files-katalogvyn frågas för att hämta file_id från datafilen.

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

D. Töm en fil

I följande exempel visas hur du tömmer en fil så att den kan tas bort från databasen. För det här exemplet skapas först en datafil och innehåller data.

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. Krymp en databasfil med WAIT_AT_LOW_PRIORITY

I följande exempel försöker man minska storleken på en datafil i den aktuella användardatabasen till 1 MB. sys.database_files katalogvyn efterfrågas för att hämta file_id av datafilen, i det här exemplet file_id 5. Om ett lås inte kan hämtas inom en minut avbryts krympningsåtgärden.

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);