Jak działa Database Buffer Cache? (część 1)

Buffer Cache to obszar pamięci wewnątrz SGA pełniący rolę dwukierunkowego bufora dyskowego uczestniczącego w operacjach odczytu i zapisu obiektów użytkowników (tabele, indeksy). Jego rozmiar jest określany automatycznie lub jest narzucony przez administratora (parametr db_cache_size). Buffer Cache służy redukcji aktywności dyskowej serwera. Zanim zapytanie SQL odczyta blok danych z dysku, najpierw próbuje znaleźć ten blok w Buffer Cache. Gdy szukany blok nie znajduje sie w Buffer Cache, wtedy jest odczytywany z dysku i (zwykle) umieszczany w Buffer Cache w celu ponownego użycia w przyszłości. Ponieważ zazwyczaj rozmiar bufora Buffer Cache jest dużo mniejszy niż rozmiar bazy danych, potrzebny jest algorytm zwalniający miejsce dla nowych bloków danych przybywających do bufora. Do wersji 8.0 Oracle wykorzystywał do tego celu klasyczny algorytm LRU (Least Recently Used), od wersji 8.1 używa rozwiązania hybrydowego nazywanego LRU Touch-Count Algorithm.

Ogólna idea działania algorytmu Touch-Count jest następująca. Każdy blok bufora Buffer Cache jest reprezentowany przez obiekt umieszczony na specjalnej liście nazywanej, historycznie, listą LRU. Jeden koniec tej listy nazywany jest „gorącym” (lub MRU – Most Recently Used), drugi koniec – „zimnym” (lub LRU – Least Recently Used). Bloki gorące są najbardziej pożądanymi gośćmi bufora, natomiast bloki zimne są kandydatami do usunięcia gdy tylko potrzebne będzie wolne miejsce. Gdy z dysku odczytywany jest pojedynczy blok, trafia on do Buffer Cache i na listę LRU – uwaga -w środek tej listy (tzw. Midpoint, wskazywany niejawnym parametrem _db_percent_hot_default). Gdy natomiast realizowana jest operacja pełnego odczytu dużej tabeli (powyżej _small_table_threshold), jej bloki odnotowywane są – uwaga – na zimnym końcu listy LRU (zmiana tego zachowania jest możliwa za pomocą klauzuli CACHE). Elementy listy LRU posiadają liczniki odwiedzin (tzw. Touch Counter). Za każdym razem gdy serwer korzysta z bloku znajdującego się w buforze Buffer Cache (lecz nie częściej niż raz na 3 sekundy, wskazywane niejawnym parametrem _db_aging_touch_time), zwiększa jego licznik odwiedzin. Gdy licznik odwiedzin osiągnie wartość większą niż dwa (niejawny parametr _db_aging_hot_criteria), wtedy blok przesuwa się na gorący koniec listy LRU (blok się rozgrzewa), a jego licznik odwiedzin jest resetowany. Jeśli takie przesunięcie spowoduje, że jakiś inny blok spadnie poniżej Midpoint, licznik odwiedzin takiego bloku będzie zresetowany do wartości 1 (wartość wskazywana niejawnym parametrem _db_aging_cool_count) (blok stygnie).

Konsekwencją powyższego algorytmu jest to, że bloki często i intensywnie wykorzystywane mają większe szanse na pozostawanie w buforze aniżeli bloki wykorzystywane mało intensywnie lub intensywnie lecz krótkotrwale. Dokładniejszy opis algorytmu LRU Touch-Count znajduje się w artykule „All About Oracle’s Touch Count Data Block Buffer Cache Algoruthm” autorstwa Craiga A. Shallahamera. Zainteresowanym eksperymentowaniem polecam wirtualną tabelę systemową X$BH, która udostępnia informacje o aktualnej zawartości bufora Buffer Cache (kolumny DBARFIL, DBABLK, OBJ), wartościach liczników odwiedzin (kolumna TCH) oraz o strukturze listy LRU (kolumny NXT_HASH, PRV_HASH). Przykładowo, poniższe zapytanie wyświetla raport o aktualnej zawartości Buffer Cache:

select substr(b.owner||'.'||b.object_name,1,30) object, count(*) num_blocks
from x$bh a, dba_objects b
where a.obj=b.object_id
group by owner, object_name
order by count(*)

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *