DBCC SHRINKDATABASE (Transact-SQL)
gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Minskar storleken på data och loggfiler i den angivna databasen.
Notera
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
Syntax för SQL Server:
DBCC SHRINKDATABASE
( database_name | database_id | 0
[ , target_percent ]
[ , { 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 }
Syntax för Azure Synapse Analytics:
DBCC SHRINKDATABASE
( database_name
[ , target_percent ]
)
[ WITH NO_INFOMSGS ]
Argumenten
database_name | database_id | 0
Databasnamnet eller ID:t som ska krympas. 0 anger att den aktuella databasen används.
target_percent
Procentandelen ledigt utrymme som du vill ha kvar i databasfilen när krympningsåtgärden har slutförts.
NOTRUNCATE
Flyttar tilldelade sidor från filens slut till otilldelade sidor framför filen. Den här åtgärden komprimerar data i filen. target_percent är valfritt. Azure Synapse Analytics stöder inte det här alternativet.
Det lediga utrymmet i slutet av filen returneras inte till operativsystemet och filens fysiska storlek ändras inte. Därför verkar databasen inte krympa när du anger NOTRUNCATE
.
NOTRUNCATE
gäller endast för datafiler.
NOTRUNCATE
påverkar inte loggfilen.
TRUNCATEONLY
Frigör allt ledigt utrymme i slutet av filen till operativsystemet. Flyttar inga sidor i filen. Datafilen krymper endast till den senast tilldelade omfattningen. Ignorerar target_percent om detta anges med TRUNCATEONLY
. Azure Synapse Analytics stöder inte det här alternativet.
DBCC SHRINKDATABASE
med alternativet TRUNCATEONLY
påverkar endast databasens transaktionsloggfil. Om du vill trunkera datafilen använder du DBCC SHRINKFILE
i stället. Mer information finns i DBCC SHRINKFILE.
UTAN NO_INFOMSGS
Undertrycker alla informationsmeddelanden som har allvarlighetsgrad mellan 0 och 10.
WAIT_AT_LOW_PRIORITY med krympåtgärder
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åelse för samtidighetsproblem med DBCC SHRINKDATABASE.
Den här funktionen liknar WAIT_AT_LOW_PRIORITY med onlineindexåtgärder, med vissa skillnader.
- Du kan inte ange
ABORT_AFTER_WAIT
alternativNONE
.
VÄNTA MED LÅG PRIORITET
När ett krympkommando körs i WAIT_AT_LOW_PRIORITY
läge blockeras inte nya frågor som kräver 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 erhålla ett schemaändringslås (Sch-M)-låset. Om en ny krympningsåtgärd i WAIT_AT_LOW_PRIORITY
-läge inte kan hämta ett lås på grund av en långvarig fråga, kommer krympningsåtgärden slutligen att tidsbegränsas efter 1 minut som standard och avslutas utan fel.
Om en ny krympningsåtgärd i WAIT_AT_LOW_PRIORITY
-läge inte kan få ett lås på grund av en tidskrävande fråga, kommer krympningsåtgärden att gå ut på tid efter 1 minut som standard och avslutas utan fel. Detta inträffar om krympningsåtgärden inte kan hämta Sch-M låset på grund av samtidiga frågor eller frågor som innehåller 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 krympa igen i läge WAIT_AT_LOW_PRIORITY
.
ABORT_AFTER_WAIT = [ SELF | BLOCKERS ]
SJÄLV
SELF
är standardalternativet. Avsluta den krympningsdatabasåtgärd som för närvarande körs utan att vidta några åtgärder.BLOCKERARE
Avsluta alla användartransaktioner som blockerar krympningsdatabasåtgärden så att åtgärden kan fortsätta. Alternativet
BLOCKERS
kräver att inloggningen harALTER ANY CONNECTION
behörighet.
Resultatuppsättning
I följande tabell beskrivs kolumnerna i resultatuppsättningen.
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 skulle kunna uppta, minst. Det här värdet 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. |
Note
Databasmotorn visar inte rader för dessa filer som inte krympts.
Anmärkningar
Om du vill krympa alla data och loggfiler för en specifik databas kör du kommandot DBCC SHRINKDATABASE
. Om du vill krympa en data- eller loggfil åt gången för en specifik databas kör du kommandot DBCC SHRINKFILE.
Om du vill visa den aktuella mängden ledigt (oallokerat) utrymme i databasen kör du sp_spaceused.
DBCC SHRINKDATABASE
åtgärder kan stoppas när som helst i processen och allt slutfört arbete sparas.
Databasen får inte vara mindre än databasens konfigurerade minsta storlek. Du anger den minsta storleken när databasen ursprungligen skapades. Eller så kan den minsta storleken vara den sista storleken som uttryckligen anges med hjälp av en ändringsåtgärd för filstorlek. Åtgärder som DBCC SHRINKFILE
eller ALTER DATABASE
är exempel på filstorleksförändrande åtgärder.
Överväg att en databas ursprungligen har skapats med storleken 10 MB. Sedan växer den till 100 MB. Den minsta databasen kan minskas till 10 MB, även om alla data i databasen har tagits bort.
Ange antingen alternativet NOTRUNCATE
eller alternativet TRUNCATEONLY
när du kör DBCC SHRINKDATABASE
. Om du inte gör det blir resultatet detsamma som om du kör en DBCC SHRINKDATABASE
-åtgärd med NOTRUNCATE
följt av att köra en DBCC SHRINKDATABASE
-åtgärd med TRUNCATEONLY
.
Den krympta databasen behöver inte vara i enst användarläge. Andra användare kan arbeta i databasen när den är krympt, inklusive systemdatabaser.
Du kan inte krympa en databas när databasen säkerhetskopieras. Omvänt kan du inte säkerhetskopiera en databas medan en krympningsåtgärd på databasen pågår.
När den anges med WAIT_AT_LOW_PRIORITY väntar krympåtgärdens Sch-M låsbegäran med låg prioritet i en minut när kommandot körs. Om åtgärden blockeras under den angivna tiden, kommer den angivna åtgärden ABORT_AFTER_WAIT att köras.
I Azure Synapse SQL-pooler rekommenderas inte att köra ett krympningskommando eftersom det här är en I/O-intensiv åtgärd och kan ta din dedikerade SQL-pool (tidigare SQL DW) offline. Dessutom kommer det att uppstå kostnadsimplikationer för snapshots av datalagret när du har kört det här kommandot.
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 kolumner som använder LOB-datatyper (varbinary(max), varchar(max)och nvarchar(max)) i komprimerade kolumnlagringssegment av
DBCC SHRINKDATABASE
ochDBCC SHRINKFILE
.
Så här fungerar DBCC SHRINKDATABASE
DBCC SHRINKDATABASE
krymper datafiler per fil, men krymper loggfiler som om alla loggfiler fanns i en sammanhängande loggpool. Filer krymps alltid från slutet.
Anta att du har ett par loggfiler, en datafil och en databas med namnet mydb
. Data- och loggfilerna är 10 MB vardera och datafilen innehåller 6 MB data. Databasmotorn beräknar en målstorlek för varje fil. Det här värdet är storleken som filen ska krympas till. När DBCC SHRINKDATABASE
anges med target_percentberäknar databasmotorn målstorleken till att motsvara target_percent av mängden ledigt utrymme i filen efter krympning.
Om du till exempel anger en target_percent på 25 för krympning mydb
beräknar databasmotorn målstorleken för datafilen till 8 MB (6 MB data plus 2 MB ledigt utrymme). Därför flyttar databasmotorn alla data från datafilens sista 2 MB till ledigt utrymme i datafilens första 8 MB och krymper sedan filen.
Anta att datafilen för mydb
innehåller 7 MB data. Om du anger en target_percent på 30 kan datafilen krympas till den kostnadsfria procentandelen på 30. Att ange en target_percent på 40 krymper dock inte datafilen eftersom det inte går att skapa tillräckligt med ledigt utrymme i datafilens aktuella totala storlek.
Du kan tänka dig det här problemet på ett annat sätt: 40 procent ville ha ledigt utrymme + 70 procent fullständig datafil (7 MB av 10 MB) är mer än 100 procent. Alla target_percent större än 30 krymper inte datafilen. Den kommer inte att krympa eftersom den procentuella mängden fri utrymme du vill ha plus den aktuella mängden som datafilen upptar är över 100 procent.
För loggfiler använder databasmotorn target_percent för att beräkna målstorleken för hela loggen. Det är därför target_percent är mängden ledigt utrymme i loggen efter krympningsåtgärden. Målstorleken för hela loggen översätts sedan till en målstorlek för varje loggfil.
DBCC SHRINKDATABASE
försöker krympa varje fysisk loggfil till målstorleken omedelbart. Anta att ingen del av den logiska loggen finns kvar i de virtuella loggarna utöver loggfilens målstorlek. Därefter trunkeras filen framgångsrikt och DBCC SHRINKDATABASE
avslutas utan några meddelanden. Men om en del av den logiska loggen finns kvar 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 körts kan DBCC SHRINKDATABASE
användas för att frigöra återstående utrymme.
En loggfil kan bara krympas till en gräns för en virtuell loggfil. Det är därför det inte går att krympa en loggfil till en storlek som är mindre än storleken på en virtuell loggfil. Det kanske inte är möjligt även om det inte används. Storleken på den virtuella loggfilen väljs dynamiskt av databasmotorn när loggfiler skapas eller utökas.
Förstå samtidighetsproblem med DBCC SHRINKDATABASE
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 förvärvar och bibehåller dessa frågor ett schemastabilitetslås (Sch-S) tills de har slutfört sina operationer. När du försöker frigöra utrymme under regelbunden användning kräver krympning av databas och krympningsåtgärder för fil för närvarande ett schemalås för ändring (Sch-M) när du flyttar eller tar bort IAM-sidor (Index Allocation Map), vilket blockerar de lås Sch-S som krävs av användarfrågor. Därför blockerar långvariga frågor en krympningsåtgärd tills frågorna har slutförts. Det innebär att alla nya frågeställningar som kräver Sch-S-lås också köas 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 shrink wait at low priority (WLP) introducerades i SQL Server 2022 (16.x) och åtgärdar problemet genom att ta ett schemaändringslås i läge WAIT_AT_LOW_PRIORITY
. Mer information finns i WAIT_AT_LOW_PRIORITY med krympningsåtgärder.
Mer information om Sch-S och Sch-M-lås finns i Transaktionslåsnings- och versionshanteringsguide.
Metodtips
Tänk på följande information när du planerar att krympa en databas:
- En krympningsåtgärd är mest effektiv efter en åtgärd som skapar oanvänt utrymme, till exempel när man trunkerar en tabell eller utför en åtgärd för att ta bort en tabell.
- 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 öka databasfilen hindrar prestanda.
- En krympningsåtgärd bevarar inte fragmenteringstillståndet för index i databasen och ökar vanligtvis fragmenteringen i viss utsträckning. Det här resultatet är en annan anledning att inte krympa databasen upprepade gånger.
- Om du inte har ett specifikt krav ska du inte ange alternativet
AUTO_SHRINK
databas till PÅ.
Felsöka
Det är möjligt att blockera krympningsoperationer av en transaktion som körs under en radversionsbaserad isoleringsnivå. Till exempel pågår en stor borttagningsåtgärd som körs under en radversionsbaserad isoleringsnivå när en DBCC SHRINKDATABASE
-operation utförs. När den här situationen inträffar väntar krympningsåtgärden på att borttagningsåtgärden ska slutföras innan filerna krymps. När krympåtgärden väntar skriver åtgärderna DBCC SHRINKFILE
och DBCC SHRINKDATABASE
ut ett informationsmeddelande (5202 för SHRINKDATABASE
och 5203 för SHRINKFILE
). Det här meddelandet skrivs ut till SQL Server-felloggen var femte minut under den första timmen och sedan varje kommande timme. Om till exempel felloggen innehåller följande felmeddelande:
DBCC SHRINKDATABASE for database ID 9 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 felet innebär att ögonblicksbildstransaktioner som har tidsstämplar som är äldre än 109 blockerar krympningsåtgärden. Den transaktionen är den sista transaktionen som krympningsåtgärden slutförde. Det anger också att kolumnerna transaction_sequence_num
eller first_snapshot_sequence_num
i sys.dm_tran_active_snapshot_database_transactions (Transact-SQL) dynamisk hanteringsvy innehåller värdet 15. Kolumnen transaction_sequence_num
eller first_snapshot_sequence_num
i vyn kan innehålla ett tal som är mindre än den senaste transaktionen som slutfördes av en krympningsåtgärd (109). I så fall väntar krympprocessen på att transaktionerna 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 slutfört arbete behålls.
- 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 databas och ange en procentandel ledigt utrymme
I följande exempel minskar storleken på data och loggfiler i UserDB
användardatabas så att det finns 10 procent ledigt utrymme i databasen.
DBCC SHRINKDATABASE (UserDB, 10);
GO
B. Trunkera en databas
I följande exempel krymper data- och loggfilerna i AdventureWorks2022
exempeldatabasen till den senaste tilldelade omfattningen.
DBCC SHRINKDATABASE (AdventureWorks2022, TRUNCATEONLY);
C. Krymp en Azure Synapse Analytics-databas
DBCC SHRINKDATABASE (database_A);
DBCC SHRINKDATABASE (database_B, 10);
D. Krymp en databas med WAIT_AT_LOW_PRIORITY
I följande exempel försöker du minska storleken på data och loggfiler i AdventureWorks2022
databas för att tillåta 20% ledigt utrymme i databasen. Om ett lås inte kan hämtas inom en minut avbryts krympningsåtgärden.
DBCC SHRINKDATABASE ([AdventureWorks2022], 20) WITH WAIT_AT_LOW_PRIORITY (ABORT_AFTER_WAIT = SELF);