sql >> Databasteknik >  >> RDS >> Sqlserver

Hur tvingar man filströmssopsamlaren att slutföra sitt arbete med högsta prioritet?

Tyvärr finns det för närvarande inget sätt att tvinga fram skräpinsamling (GC) av filströmsdata. Det hanteras av en asynkron bakgrundsuppgift som bara anropas så ofta och som har en gräns för antalet filer som den får behandla i en enda anrop. Andra personer har redan klagat på detta och Microsoft har lovat att ta itu med detta problem i framtida utgåvor.

Med detta sagt finns det några saker du kan göra proaktivt för att säkerställa att alla raderade filer är kvalificerade för sophämtning. En fil blir inte automatiskt kvalificerad för sophämtning i det ögonblick den raderas från databasen – vissa ytterligare villkor måste uppfyllas.

Villkoren beror på databasens återställningsmodell, därför är det viktigt att du vet vilken återställningsmodell din databas är i. Observera att även om återställningsmodellen (som specificeras av sys.databases) är full, men du inte har tagit en db/log backup sedan den fullständiga återställningsmodellen aktiverades (eller sedan du skapade db), kommer databasen att bete sig i många aspekter som om den fortfarande var i en enkel återställningsmodell.

Under en enkel återställningsmodell är allt som krävs för att en fil ska vara kvalificerad för radering att den aktuella kontrollpunkten LSN (LSN för den sista kontrollpunkten) är större än LSN för raderingsoperationen som tog bort filen. Allt du kan göra efter att du tagit bort de 40 000 raderna är därför att utfärda ett enda CHECKPOINT-uttalande och vänta.

Saker och ting blir mer komplicerade när databasen är i "verkligen full" återställningsmodell. Om så är fallet måste, förutom kontrollpunkt LSN, backup LSN (LSN för senaste loggbackup) vara förbi raderings-LSN. Dessutom fungerar GC i 2 faser:vid första passet markerar den bara en fil för radering men tar inte bort den fysiskt. Först när GC bearbetar filen för andra gången kommer den filen att raderas fysiskt från disken. För att göra saker ännu mer intressant, "återställer" det första passet av GC borttagnings-LSN, så det andra passet kan bara bearbeta filen när kontrollpunkt-LSN och backup-LSN är större än LSN för det första GC-passet.

Om du vill veta exakt vad som händer i systemet kan du hålla reda på aktuella GC-framsteg genom att titta på en speciell intern "gravstenar"-tabell. Varje gång ett filströmsvärde tas bort från databasen, infogas en gravsten i den här tabellen. Gravstenen tas bort först efter att filen har raderats från skivan. Gravstenstabellens namn är sys.filestream_tombstone_ där är något nummer. Du kan få det exakta namnet med hjälp av följande fråga:

select name from sys.internal_tables where name like '%tombstone%'

Eftersom det är en intern tabell måste du logga in med DAC (dedikerad administratörsanslutning) för att fråga den.

Låt oss till exempel säga att jag har tagit bort en rad med ett enda filströmsvärde. Nu kan jag se statusen för gravstenen genom att skicka följande fråga (från DAC):

select * from sys.filestream_tombstone_2073058421

De första 3 fälten anger LSN för raderingsoperationen, men det viktigaste att observera är status. Efter att ha utfärdat loggbackup + kontrollpunkt och låtit den köras i några sekunder, frågar jag gravstenstabellen igen och jag får:

Observera att statusen har ändrats (de sista 2 bitarna ändras från 1 till 2), vilket indikerar att filen har bearbetats av det första GC-passet. Dessutom har LSN uppdaterats med LSN för det första GC-passet, så för att det andra GC-passet i slutändan ska kunna radera filen måste vi föra kontrollpunkt LSN och backup LSN ovanför det nya LSN. Jag utfärdar ytterligare en kontrollpunkt + loggbackup, väntar några sekunder och frågar om gravstenstabellen. Den är nu tom och filen har försvunnit från disken.

Tänk på att det finns andra saker (t.ex. replikering, andra transaktioner när versionshantering är aktiverad) som kan förhindra att vissa filer samlas in som skräp, men i de flesta fall är checkpoint och loggbackup de två huvudsakliga.

Hoppsan, jag antar att jag kanske har gått för djupt in i detaljerna, men kanske kommer detta att hjälpa på något sätt för att förstå GC-beteendet.



  1. Hur utför man en LEFT JOIN i SQL Server mellan två SELECT-satser?

  2. MYSQLI förberedd uttalande ger ingen utmatning

  3. Databasdesign för begränsningsframtvingande parning

  4. Säkra fjärranslutning för mysql