Desværre er der i øjeblikket ingen måde at fremtvinge skraldindsamling (GC) af filstreamdata. Det håndteres af en asynkron baggrundsopgave, der kun bliver kaldt frem hver gang, og som har en grænse for antallet af filer, den må behandle i en enkelt opkald. Andre mennesker har allerede klaget over dette, og Microsoft har lovet at løse dette problem i fremtidige udgivelser.
Når det er sagt, er der nogle ting, du proaktivt kan gøre for at sikre, at alle slettede filer er berettiget til affaldsindsamling. En fil bliver ikke automatisk berettiget til affaldsindsamling i det øjeblik, den bliver slettet fra databasen - visse yderligere betingelser skal være opfyldt.
Betingelserne afhænger af databasens gendannelsesmodel, derfor er det vigtigt, at du ved, hvilken gendannelsesmodel din database er i. Bemærk, at selvom gendannelsesmodellen (som specificeret af sys.databases) er fuld, men du ikke har taget en db/log backup siden aktivering af den fulde gendannelsesmodel (eller siden oprettelse af db), vil databasen opføre sig i mange aspekter, som om den stadig var i en simpel gendannelsesmodel.
Under en simpel gendannelsesmodel er alt, hvad der er nødvendigt for, at en fil er berettiget til sletning, at det aktuelle kontrolpunkt LSN (LSN for det sidste kontrolpunkt) er større end LSN for sletningsoperationen, der fjernede filen. Derfor er alt, hvad du kan gøre, efter at du har slettet de 40.000 rækker, at udstede en enkelt CHECKPOINT-erklæring og vente.
Tingene bliver mere komplicerede, når databasen er i "virkelig fuld" gendannelsesmodel. Hvis det er tilfældet, skal backup LSN (LSN for sidste log backup) ud over kontrolpunkt LSN være forbi slette LSN. Ydermere fungerer GC'en i 2 faser:ved den første gennemgang markerer den kun en fil til sletning, men sletter den ikke fysisk. Først når GC behandler filen for anden gang, bliver filen fysisk slettet fra disken. For at gøre tingene endnu mere interessante, "nulstiller" den første gennemgang af GC slette-LSN'et, så den anden gennemgang må kun behandle filen, når kontrolpunkt-LSN og backup-LSN er større end LSN for det første GC-pas.
Hvis du vil vide præcis, hvad der foregår i systemet, kan du holde styr på den aktuelle GC-fremgang ved at se på en speciel intern "gravstens"-tabel. Hver gang en filstrømsværdi slettes fra databasen, indsættes en gravsten i denne tabel. Gravstenen fjernes først, efter at filen er blevet slettet fra disken. Gravstenstabellens navn er sys.filestream_tombstone_ hvor er et tal. Du kan få det nøjagtige navn ved at bruge følgende forespørgsel:
select name from sys.internal_tables where name like '%tombstone%'
Da det er en intern tabel, skal du logge på med DAC (dedikeret admin-forbindelse) for at forespørge på den.
Lad os f.eks. sige, at jeg har slettet en række med en enkelt filestream-værdi. Nu kan jeg se status for gravstenen ved at udstede følgende forespørgsel (fra DAC):
select * from sys.filestream_tombstone_2073058421
De første 3 felter angiver LSN for sletningsoperationen, men det vigtigste at observere er status. Efter at have udstedt log backup + checkpoint og ladet det køre i et par sekunder, forespørger jeg gravstenstabellen igen, og jeg får:
Bemærk, at status er ændret (de sidste 2 bits ændres fra 1 til 2), hvilket indikerer, at filen er blevet behandlet af det første GC-pass. Derudover er LSN'et blevet opdateret med LSN'et for det første GC-pas, så for at det andet GC-pas i sidste ende skal kunne slette filen, skal vi bringe checkpoint LSN og backup LSN over det nye LSN. Jeg udsteder endnu et kontrolpunkt + log backup, vent et par sekunder og genforespørger gravstenstabellen. Den er nu tom, og filen er forsvundet fra disken.
Husk, at der er andre ting (f.eks. replikering, andre transaktioner, når versionsstyring er aktiveret), der kan forhindre bestemte filer i at blive indsamlet skrald, men i de fleste tilfælde er checkpoint og log backup de 2 vigtigste.
Ups, jeg gætter på, at jeg måske er gået for dybt ind i detaljerne, men måske vil dette hjælpe på en eller anden måde til at forstå GC-adfærden.