Немного об LRU списке. _db_againg_cool_count, _db_aging_hot_criteria, _db_aging_stay_count, _db_aging_touch_time

dbstalker, 23 апреля

Задача этой статьи - немного осветить работу оракла по ведению списка "чистых" буферов.

Сначала немного общих понятий в контексте статьи:

Буфер – блок данных, помещенный в буферный кеш.

Буфера в буферном кеше могут пребывать в следующих состояниях:

  • Clean (чистые) буфера - означает, что буфер в настоящее время не закреплен (unpinned) и является кандидатом на удаление из кэша, если на его содержимое не буде опять ссылок. Содержимое буфера либо синхронизировано с блоком на диске, либо буфер использовался для генерации и обработки старого моментального снимка блока в режиме целостного чтения (Consistent read – CR блок)
  • pinned буфера («закрепленные») - означает, что несколько сеансов не могут в один и тот же момент времени писать в один блок и вынуждены ждать доступа к блоку
  • free/unused (свободный/неиспользуемый) – означает, что буфер пустой, т.к. экземпляр только что был запущен. Состояние очень похоже на Clean, за исключение того, что буфер еще не использовался.
  • Dirty («грязный») – буфер больше не является закрепленным, но его содержимое было изменено и должно быть записано на диск процессом DBWR перед удалением из кэша.

Список – перечень ссылок на кешированные блоки данных, то есть на буфера. Буфер (вернее - ссылка на него) может одновременно находиться в нескольких списках.

Если немного абстрагироваться, то можно считать, что буферы в буферном кеше в основном мониторятся двумя списками:

  • Список грязных буферов, которые должны быть записаны DBWn (процессом записи буферов базы данных) на диск.Этот список еще называется checkpoint queue
  • Список чистых буферов (условно «чистых» - в этом списке находятся Clean, pinned,free/unused буфера и еще грязные буфера, которые не успели попасть в грязный список).

Задача этой статьи - немного осветить работу оракла по ведению списка "чистых" буферов.

Основная цель, которую преследует оракл работая со списком "чистых" буферов, это удержать в памяти как можно дольше популярные блоки данных для минимизации затрат на операции ввода-вывода.

Список чистых буферов упорядочен от MRU (most recently used –только что использованных) буферов до LRU (least recently used давно использованных) буферов, то есть, организован в виде LRU списка. Проще говоря, один конец LRU списка – это популярные буфера (MRU), другой конец – непопулярные буфера (LRU). По умолчанию, MRU и LRU концы списка занимают по 50% от общего числа буферов. Это соотношение можно изменить, установив в необходимое значение параметр _db_percent_hot_default.

В версиях оракла до 8.0 включительно, буферы в этом списке упорядочивались по времени последнего использования.

Использовался алгоритм "read and heat". Только что прочитанные блоки сразу же помещались в MRU конец списка. Негативные последствия этого: когда большая таблица сканировалась (FTS – full table scan), то из кэша вытеснялись даже буфера, которые были более востребованы. В дальнейшем алгоритм был усовершенствован – при FTS буфера размещаются в LRU конце списка и, к тому же, разрешается только ограниченное число таких блоков иметь в кэше. Блоки, прочитанные по одиночке, по-прежнему помещаются в MRU конец списка.

Как только буфер был использован, он сразу же перемещался в горячий (MRU) конец списка, тем самым, смещая все прочие буферы (точнее – ссылки на них) к холодному концу списка (LRU) . То есть по списку происходило движение при каждом обращении к буферу. Подчеркиваю, буфера не перемещаются, перемещаются только ссылки в LRU списке.

Если для новых блоков нет места в буферном кеше, то самый холодный буфер вытесняется.

В последующих версиях сервер Oracle этим списком управляет исходя из частоты использования буфера. Это так называемый Touch Count Algorithm (TCA). Основная идея нового алгоритма – каждый блок должен заработать очки для продвижения от холодного конца списка к горячему и таким образом заслужить право остаться в буферном кэше. Этот алгоритм организован с помощью счетчика, связанного с каждым буфером. Значение счетчика ("touch count") возрастает, если буфер является востребованным. Чем более востребован буфер, тем больше значение этого счетчика. Периодичность наращивания счетчика определяется параметром _db_aging_touch_time (default: 3 seconds). Буферы, имеющие большее значение этого счетчика, остаются в буферном кэше, буфера с низким значением – кандидаты на вылет из кэша.

Есть еще некоторые отличительные моменты. Например, такие:

  • Блок,только что прочитанный с диска, помещается в средину LRU- списка между горячей и холодной частью списка (midpoint insertion), но так, что попадает в холодную часть списка. Для этого буфера touch count получает значение 1. А дальше буфер должен еще заработать, чтобы продвинуться в горячий конец. Это - фундаментальная концепция этого алгоритма.
  • Счетчик не наращивается для буферов, используемых для согласованного чтения.
  • LRU не упорядочивается по touch count, т.е. в произвольный момент времени блок с меньшим tch может находиться ближе к горячему концу, чем блок с большим tch.
  • Только что использованный буфер не переносится зразу же в начало списка. Он остается на месте, только его "счетчик обращений" увеличивается.
  • Блоки перемещаются по списку в зависимости от значения счетчика (touch count) во время поиска свободного буфера. В это время измененные буфера (их указатели) переносятся в грязный список; буфера,у которых tch<2,считаются свободными, а у которых tch больше двух (это значение контролируется параметром _db_aging_hot_criteria) переносятся в горячую часть списка. Когда буфер попадает на горячий конец списка, tch у него устанавливается в нулевое значение (это значение контролируется параметром _db_aging_stay_count). Таким образом, буфер должен заново зарабатывать право оставаться в буферном кэше.
  • Манипуляции с touch count происходят без использования защелок, в то время как прочие операции со LRU- списком защищены блокировками. И как следствие – значение touch count не изменяется, если одновременно другой процесс корректирует заголовок буфера. Но это самое худшее, что может произойти. Зато отсутствует конкуренция за защелку.
  • Когда буфер переносится из холодной части в горячую, то midpoint маркер также перемещается на одну позицию, чтобы обеспечить равновесие между числом горячих и холодных буферов. Следствием этого является переход буферов из горячего конца списка в холодный. Этим буферам счетчик устанавливается равным единице (это значение контролируется параметром _db_againg_cool_count). Таким образом, буфер должен заново зарабатывать право оставаться в буферном кэше.

Представление v$bh покажет вам много полезной информации по каждому блоку в буферном кеше. Вот таким простеньким запросиком можно посмотреть самые часто используемые объекты вашей базы:

Select b.Object_name object, a.tch touches from x$bh a, dba_objects b
 Where a.obj=b.object_id and a.tch > 100
Order by a.tch desc;

На заметку: The CACHE hint specifies that the blocks retrieved for the table are placed at the most recently used end of the LRU list in the buffer cache when a full table scan is performed. This option is useful for small lookup tables.

Использовались следующие материалы:

http://youngcow.net/doc/oracle10g/server.102/b14220/memory.htm

http://resources.orapub.com/product_p/tc.htm «All About Oracle's Touch-Count Data Block Buffer Algorithm»

http://oracle-online-help.blogspot.com/2006/11/touch-count-algorithm-in-advancement-to.html

P.S. В интернете попалась на столько красивая картинка, что не могу не показать ее Вам:

 

Новый комментарий

Я не спамер: введите суму 7+5



 

От авторов блога

О Блоге - прочитай перед началом.

Задать вопрос и получить ответ - уже решено 94 вопросов

Глоссарий - список терминов и сокращений


 
 

Бизнес форум

Последние темы:

Досуг для взрослых
19 июня, 1 ответа
авто
19 июня, 1 ответа
Отдых
18 июня, 2 ответа