Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak zmusić garbage collector do zakończenia pracy z najwyższym priorytetem?

Niestety obecnie nie ma sposobu na wymuszenie wyrzucania śmieci (GC) danych strumienia plików. Jest obsługiwany przez asynchroniczne zadanie w tle, które jest wywoływane tylko co jakiś czas i ma limit liczby plików, które może przetworzyć w jednym wywołaniu. Inni ludzie już narzekali na to, a Microsoft obiecał rozwiązać ten problem w przyszłych wydaniach.

Biorąc to pod uwagę, jest kilka rzeczy, które możesz aktywnie zrobić, aby upewnić się, że wszystkie usunięte pliki kwalifikują się do wyrzucania śmieci. Plik nie kwalifikuje się automatycznie do wyrzucania śmieci w momencie, gdy zostanie usunięty z bazy danych - muszą być spełnione pewne dodatkowe warunki.

Warunki zależą od modelu odzyskiwania bazy danych, dlatego ważne jest, aby wiedzieć, w jakim modelu odzyskiwania znajduje się Twoja baza danych. Należy pamiętać, że nawet jeśli model odzyskiwania (określony przez sys.databases) jest pełny, ale nie wykonano Kopia zapasowa bazy danych/logu od momentu włączenia pełnego modelu odzyskiwania (lub od utworzenia bazy danych), baza danych będzie zachowywać się pod wieloma względami tak, jakby nadal była w prostym modelu odzyskiwania.

W prostym modelu odzyskiwania wszystko, co jest niezbędne, aby plik kwalifikował się do usunięcia, to to, że bieżący numer LSN punktu kontrolnego (LSN ostatniego punktu kontrolnego) jest większy niż numer LSN operacji usuwania, która usunęła plik. Dlatego wszystko, co możesz zrobić po usunięciu 40 000 wierszy, to wydać pojedynczą instrukcję CHECKPOINT i czekać.

Sprawy się komplikują, gdy baza danych jest w modelu odzyskiwania „naprawdę pełnego”. W takim przypadku, oprócz punktu kontrolnego LSN, zapasowa LSN (LSN ostatniej kopii zapasowej dziennika) musi być po usunięciu LSN. Co więcej, GC działa w 2 fazach:w pierwszym przebiegu tylko zaznacza plik do usunięcia, ale nie usuwa go fizycznie. Dopiero gdy GC przetworzy plik po raz drugi, plik ten zostanie fizycznie usunięty z dysku. Aby było jeszcze ciekawiej, pierwszy przebieg GC "resetuje" usuwanie LSN, więc drugi przebieg może przetworzyć plik tylko wtedy, gdy punkt kontrolny LSN i zapasowy LSN są większe niż LSN pierwszego przebiegu GC.

Jeśli chcesz dokładnie wiedzieć, co się dzieje w systemie, możesz śledzić bieżący postęp GC, patrząc na specjalną wewnętrzną tabelę „nagrobków”. Za każdym razem, gdy wartość strumienia plików jest usuwana z bazy danych, do tej tabeli wstawiany jest relikt. Nagrobek jest usuwany dopiero po usunięciu pliku z dysku. Nazwa tabeli nagrobków to sys.filestream_tombstone_, gdzie jest jakaś liczba. Możesz uzyskać dokładną nazwę za pomocą następującego zapytania:

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

Ponieważ jest to tabela wewnętrzna, aby ją wysłać, musisz zalogować się za pomocą DAC (dedykowane połączenie administratora).

Załóżmy na przykład, że usunąłem wiersz z pojedynczą wartością strumienia plików. Teraz mogę sprawdzić stan nagrobka, wydając następujące zapytanie (z DAC):

select * from sys.filestream_tombstone_2073058421

Pierwsze 3 pola oznaczają numer LSN operacji usuwania, ale najważniejszym do zaobserwowania jest status. Po utworzeniu kopii zapasowej logu + punktu kontrolnego i pozwoleniu na jego działanie przez kilka sekund, ponownie odpytuję tabelę nagrobków i otrzymuję:

Zauważ, że status się zmienił (ostatnie 2 bity zmieniają się z 1 na 2), wskazując, że plik został przetworzony przez pierwsze przejście GC. Dodatkowo, LSN został zaktualizowany o LSN pierwszego przebiegu GC, więc aby drugi przebieg GC mógł ostatecznie usunąć plik, musimy przenieść punkt kontrolny LSN i zapasowy LSN powyżej nowego LSN. Wydaję kolejny punkt kontrolny + kopię zapasową dziennika, czekam kilka sekund i ponownie pytam tabelę nagrobków. Jest teraz pusty, a plik zniknął z dysku.

Należy pamiętać, że istnieją inne rzeczy (np. replikacja, inne transakcje, gdy włączone jest wersjonowanie), które mogą uniemożliwić zbieranie śmieci określonych plików, ale w większości przypadków punkt kontrolny i kopia zapasowa dziennika to dwie główne.

Ups, myślę, że mogłem zagłębić się w szczegóły, ale być może pomoże to w jakiś sposób w zrozumieniu zachowania GC.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego newid() materializuje się na samym końcu zapytania?

  2. Jak napisać instrukcję if else w języku wyrażeń usług Reporting Services?

  3. Wydajność zwraca rekordy bazy danych przy użyciu LinqToSql?

  4. Nie znaleziono bliskich odpowiedników w CONTAINSTABLE

  5. Problem z zapytaniem sql podczas raportowania