Od czasów wersji Oracle Database 10g powszechnie wykorzystujemy mechanizmy automatycznego zarządzania pamięcią operacyjną instancji (Automatic Shared Memory Management – ASMM, czy później Automatic Memory Management – AMM). Pamiętamy ze szkoleń, że zwalniają one administratora m.in. z obowiązku ręcznego konfigurowania rozmiarów obszarów buforowych takich jak Buffer Cache i Shared Pool oraz z podejmowania decyzji o proporcji rozmiarów PGA/SGA. Wymagają jedynie określenia pożądanego rozmiaru całkowitego SGA (parametr SGA_TARGET) lub pożądanego sumarycznego rozmiaru PGA i SGA (parametr MEMORY_TARGET). Warto podkreślić, że nadal poprawne jest równoległe stosowanie parametrów wymiarujących poszczególne obszary buforowe w SGA – DB_CACHE_SIZE i SHARED_POOL_SIZE – lecz nabierają one wówczas innego znaczenia, określając mianowicie minimalne (a nie pożądane) rozmiary alokowanej pamięci operacyjnej.
Nie zawsze mechanizmy automatycznego zarządzania pamięcią operacyjną funkcjonują tak, jak byśmy tego oczekiwali. W systemach poddanych bardzo intensywnemu obciążeniu i jednocześnie „duszących się” w niewystarczającej pamięci SGA stosunkowo powszechnie spotykamy się z problemem „migotania” pamięci – częstego przenoszenia pamięci RAM pomiędzy Buffer Cache i Shared Pool (diagnostyka: select * from v$sga_resize_ops order by start_time
). Strony pamięci będące w trakcie transferu pomiędzy tymi buforami są w znacznej mierze nieużyteczne dla serwera (oznaczone jako „KGH: NO ACCESS”), co może prowadzić do szybkiego wyczerpania miejsca w Bufer Cache lub w Shared Pool (częściej w Shared Pool). Efektem może być raportowanie usterki ORA-04031 (ORA-04031: unable to allocate X bytes of shared memory) i szybka zapaść systemu.
Podstawowe rozwiązanie powyższego problemu polega na częściowym odstąpieniu od pełnej automatyzacji zarządzania pamięcią operacyjną instancji i ręczne określenie minimalnych rozmiarów obszarów buforowych Shared Pool i Buffer Cache. Aby jednak nadal korzystać ze skądinąd bardzo pożytecznych mechanizmów automatyzacji, proponuję rozdysponować w ten sposób jedynie ok. 50% dostępnej pamięci SGA. Wówczas pozostałą część pamięci serwer bazy danych będzie mógł nadal przydzielać dynamicznie w oparciu o monitorowane potrzeby, ale jednocześnie nie doprowadzi do nieakceptowalnie małych rozmiarów krytycznych obszarów SGA. Przykładowo, gdyby SGA_TARGET ustawiony był na 40 GB, ustawienia Buffer Cache i Shared Pool mogłyby być następujące:
alter system set db_cache_size=10GB;
alter system set shared_pool_size=10GB;
Powodzenia!