sql >> Database >  >> RDS >> Sqlserver

Hoe dwing je de filestream garbage collector om zijn werk met de hoogste prioriteit af te ronden?

Helaas is er momenteel geen manier om het verzamelen van afval (GC) van filestream-gegevens te forceren. Het wordt afgehandeld door een asynchrone achtergrondtaak die slechts af en toe wordt aangeroepen en die een limiet heeft in het aantal bestanden dat in een enkele aanroep kan worden verwerkt. Andere mensen hebben hier al over geklaagd en Microsoft heeft beloofd dit probleem in toekomstige releases aan te pakken.

Dat gezegd hebbende, zijn er enkele dingen die u proactief kunt doen om ervoor te zorgen dat alle verwijderde bestanden in aanmerking komen voor garbagecollection. Een bestand komt niet automatisch in aanmerking voor garbagecollection op het moment dat het uit de database wordt verwijderd - er moet aan bepaalde aanvullende voorwaarden worden voldaan.

De voorwaarden zijn afhankelijk van het herstelmodel van de database, daarom is het belangrijk dat u weet in welk herstelmodel uw database zich bevindt. Houd er rekening mee dat zelfs als het herstelmodel (zoals gespecificeerd door sys.databases) vol is, maar u geen db/log-back-up sinds het inschakelen van het volledige herstelmodel (of sinds het maken van de db), zal de database zich in veel opzichten gedragen alsof het nog steeds in een eenvoudig herstelmodel was.

Volgens een eenvoudig herstelmodel is het enige dat nodig is om een ​​bestand in aanmerking te laten komen voor verwijdering, dat de huidige LSN van het controlepunt (de LSN van het laatste controlepunt) groter is dan de LSN van de wisbewerking die het bestand heeft verwijderd. Daarom is alles wat u kunt doen nadat u de 40.000 rijen heeft verwijderd, een enkel CHECKPOINT-statement afgeven en wachten.

Het wordt ingewikkelder wanneer de database zich in een "echt volledig" herstelmodel bevindt. Als dat het geval is, moet naast de checkpoint LSN ook de back-up LSN (de LSN van de laatste logback-up) voorbij de delete LSN liggen. Verder werkt de GC in 2 fasen:bij de eerste doorgang markeert het alleen een bestand voor verwijdering, maar verwijdert het niet fysiek. Pas wanneer GC het bestand voor de tweede keer verwerkt, wordt dat bestand fysiek van de schijf verwijderd. Om het nog interessanter te maken, "reset" de eerste doorgang van de GC de verwijder-LSN, zodat de tweede doorgang het bestand alleen mag verwerken wanneer de checkpoint LSN en back-up LSN groter zijn dan de LSN van de eerste GC-pass.

Als u precies wilt weten wat er in het systeem gebeurt, kunt u de huidige GC-voortgang bijhouden door naar een speciale interne "grafstenen"-tabel te kijken. Elke keer dat een filestream-waarde uit de database wordt verwijderd, wordt er een grafsteen in deze tabel ingevoegd. De grafsteen wordt pas verwijderd nadat het bestand van de schijf is verwijderd. De naam van de tombstone-tabel is sys.filestream_tombstone_ waar een nummer is. U kunt de exacte naam verkrijgen door de volgende zoekopdracht te gebruiken:

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

Omdat het een interne tabel is, moet u zich aanmelden via DAC (dedicated admin connection).

Laten we bijvoorbeeld zeggen dat ik een rij met een enkele filestream-waarde heb verwijderd. Nu kan ik de status van de grafsteen zien door de volgende vraag te stellen (van DAC):

select * from sys.filestream_tombstone_2073058421

De eerste 3 velden geven de LSN van de wisbewerking aan, maar het belangrijkste om te observeren is de status. Nadat ik logback-up + checkpoint heb uitgegeven en het een paar seconden heb laten lopen, vraag ik de tombstone-tabel opnieuw en krijg ik:

Merk op dat de status is gewijzigd (de laatste 2 bits veranderen van 1 naar 2), wat aangeeft dat het bestand is verwerkt bij de eerste GC-pass. Bovendien is de LSN bijgewerkt met de LSN van de eerste GC-pas, dus om ervoor te zorgen dat de tweede GC-pas het bestand uiteindelijk kan verwijderen, moeten we checkpoint LSN en back-up LSN boven de nieuwe LSN brengen. Ik geef nog een checkpoint + logback-up uit, wacht een paar seconden en vraag de grafstenentabel opnieuw op. Het is nu leeg en het bestand is van de schijf verdwenen.

Houd er rekening mee dat er andere dingen zijn (bijv. replicatie, andere transacties wanneer versiebeheer is ingeschakeld) die kunnen voorkomen dat bepaalde bestanden worden verzameld, maar in de meeste gevallen zijn checkpoint- en logback-up de 2 belangrijkste.

Oeps, ik denk dat ik misschien te diep in de details ben gegaan, maar misschien helpt dit op de een of andere manier om het GC-gedrag te begrijpen.



  1. Kan ik MySQL-API's in PHP mixen?

  2. records van één en slechts één type verkrijgen

  3. Selecteer de resultaatset in een variabele en gebruik die variabele vervolgens in een update later in dezelfde opgeslagen procedure

  4. SQL-probleem met uitchecktijden