Защелки. LATCH. Выполнение блокировок с помощью защелок. Параметр _spin_count

dbstalker, 03 июня

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

Защелки – это простейший способ обеспечения очередности доступа к общим объектам, файлам. Это двоичные переменные, фактически переключатели-триггеры, которые применяются на короткое время и защищают структуры памяти. Защелка имеет только два состояния – занята или свободна.

Прежде чем процесс получит доступ к разделяемой структуре, которая должна быть защищена защелкой, ему должна быть выделена защелка.

  • Если защелка в настоящее время свободна (другой процесс не имеет к ней доступа), в таком случае процесс получит защелку немедленно.
  • Защелка занята. Есть два варианта действия в зависимости от типа защелки : немедленная установка, установка с ожиданием. (“willing-to-wait” и “no-wait” (= immediate)). Если процесс имеет возможность продолжать работу, не получив запрашиваемую защелку, то это запрос no-wait (например, redo copy latch). Если процесс не может продолжать работу, не получив запрашиваемую блокировку, то это режим willing-to-wait. Число попыток определяется параметром инициализации _spin_count. Когда число повторений достигнет _spin_count , процесс переходит в состояние ожидания. Через установленное время процесс активизируется, и процедура повторяется снова.

Так как возможности установить защелку могут ожидать несколько процессов, то одни могут ждать дольше, чем другие. Защелки выдаются случайным образом - «Кому повезет». Сеанс, который запросил защелку сразу после её освобождения, получит её. То есть, очереди получить защелку как таковой нет, есть «толпа» пытающихся получить её.

Для работы с защелками ORACLE использует неделимые инструкции типа «проверить установить». Поэтому операционная система может гарантировать, что только один процесс может получить защелку. К тому же это происходить очень быстро. Защелки удерживаются очень короткое время. Как этот механизм работает?

(выдержка из документации)

В общем случае защелка - это некая булевская переменная, которая показывает, что ресурс свободен или занят. Если значение переменной 0 (false), то это означает, что блокировка свободна и любой процесс может изменить ее значение на 1 (true), а затем обращаться к защищаемому ресурсу. Если значение блокировки true, то процессу следует подождать, поскольку кто-то еще пользуется этим ресурсом.

Для реализации механизма установки и снятия защелки (блокирования и разблокирования) требуется участие аппаратного обеспечения. Процессоры многопроцессорных ЭВМ имеют специальную команду, которая в разных источниках называется TSL (Test and Set Lock), CAS (Compare and Swap) или LL/SC (Load Link /Store Conditions).

Установка защелки

Процессор, выполняющий эту команду, блокирует шину памяти так, чтобы остальные процессоры не могли обратиться к оперативной памяти, и затем выполняет команду ‘test’, читая соответствующую ячейку памяти. Если возвращаемое значение равно нулю (false), то это значит, что переменная свободна, и процессор выполняет команду ‘set’, которая записывает в эту переменную значение 1 (true), и шина памяти разблокируется.

Освобождение блокировки выполняется путем записи 0 (false) в переменную блокировки.

Если другой процессор позже попытается запросить блокировку, то команда ‘test’ возвратит ему значение 1 (true), означающее, что блокировка уже установлена. В этом случае второму процессу придется подождать некоторое время, а затем снова запросить блокировку. При выполнении каждой TSL-команды происходит блокирование шины ЭВМ.

Таким образом, команда типа TSL аппаратно обеспечивает неделимость обращения к переменной блокировки, ибо процесс может быть снят с выполнения либо до начала команды, либо после ее окончания. В результате чего блокировки СУБД ORACLE спускаются на уровень аппаратного обеспечения и блокируют шину ЭВМ. Блокирование шины сервера означает, что во время выполнения команды TSL все остальные процессоры и процессы не могут получить доступ к оперативной памяти и вынуждены ждать завершения операции (однако они могут обращаться к данным в своем локальном кеше). В общем, защелки представляют собой чрезвычайно затратный механизм поддержания целостности и непротиворечивости системы, но другого механизма поддержки непротиворечивости пока не существует.

Снятие защелки

Поскольку блокирующий процесс не оповещает остальные процессы об освобождении блокировки, то ожидание освобождения блокировки может происходить только двумя способами:

  • непрерывно выполнять команду TSL в цикле с тем, чтобы непрерывно опрашивать значение переменной;
  • с помощью системного вызова sleep(time) процесс может на некоторое время “заснуть” и тем самым освободить процессор, отдав управление в ОС, чтобы она “разбудила” этот процесс по истечении периода time. Sleep() – это системный вызов, в результате которого вызывающий процесс снимается с процессора и переводится в неактивное состояние на время указанное в параметре этой команды. Wakeup(pid) – обратная к sleep команда, которой на вход передается один параметр – pid процесса, который следует запустить на ЦПУ.

Первый способ, очевидно, является достаточно затратным, с точки зрения потребления ресурсов ЦПУ, потому что он загружает холостой работой все процессоры, на которых выполняются процессы, запрашивающие блокировку. Достоинство spin-подхода в том, что в этом случае отсутствует простой процесса (процесс получает блокировку сразу же, как только она освободится). Кроме того, отсутствует переключение контекста (переключение процессора с одного процесса на другой). Переключение контекста является длительной операцией, поскольку требует сохранения контекста текущего процесса (сохранение регистров процессора в стеке), загрузки нового контекста (загрузки в регистры процессора значений нового процесса). Кроме того, новый процесс начнет выполнение с непопадания в кеш, потому что кеш хранит данные старого процесса.

Второй способ является более экономным для ЦПУ, но время ожидания освобождения блокировки здесь будет больше. Достоинство второго подхода в том, что занятый процессор освобождается и может быть загружен полезной работой, но взамен происходит переключение контекста, что долго и дорого.

В общем, жертвовать придется всегда, либо общей производительностью ЭВМ, либо временем отдельного процесса, и главная задача здесь оптимальным образом сбалансировать запросы на блокировки, выполняемые тем или другим способом.

Есть механизм очистки (фоновый процесс PMON), если владелец сеанса, удерживающего защелку, прекратил своё существование, не освободив её.

Перечень все защелок можно увидеть в представлении v$latchname:

   Select * from v$latchname; 

Информацию о защелках можно почерпнуть из следующих представлений:

  • v$latch – показывает все статистические данные по применяемым защелкам
    GETS            количество удачных запросов для защелок, которые 
                    ожидались
    MISSES          количество неудачных запросов для защелок, которые 
                    ожидались
    SLEEPS          количество попыток получить защелку для процесса в 
                    ожидающем режиме, который после серии неудачных попыток 
                    переведен в состояние «сна»
    IMMEDIATE_GETS  количество успешных запросов для защелок в немедленном 
                    режиме IMMEDIATE_MISSES – количество неудачных запросов 
                    для защелок в немедленном режиме. 
    SPIN_GETS       количество раз, которое защелка была получена с 
                    повторной попытки без перевода в состояние «сна».
    SLEEP1, SLEEP2, 
    SLEEP3, SLEEP4,
    SLEEP5, SLEEP6,
    SLEEP7,SLEEP8, 
    SLEEP9, SLEEP10,
    SLEEP11         как только процесс переходит в состояние «сна»,значение 
                    в столбцах увеличивается . напрмер, если процесс 
                    переходит в состояние «сна» з раза перед получением 
                    защелки, то столбец SLEEP3 увеличивается на 1.
    
  • v$lathholder – можно выявить сеанс, который удерживает защелку, в случае проблемы конкуренции (столбец PID - идентификатор сеанса , который держит в данный момент защелку).
  • v$session_wait – можно выявить «зависший» сеанс, который ожидает защелку. select * from v$session_wait where event='latch free'; Если в столбце wait_time значение 0, то сеанс в данный момент ждет защелку. Столбец p2 – номер защелки.

Защелки используются в СУБД Oracle во многих случаях, например:

  • для управления буферным кешем. Защелки вызываются при вставке/удалении/перемещении блока в кеше. Если учесть, что кешей может быть пять штук (2k,4k,8k,16k,32k), в каждом по три типа (Default, Keep,Recycle), поэтому для всех 15 областей памяти потребуется до 30 Защелки, по две Защелки на кеш;
  • для управления журнальным буфером: минимум по две Защелки на каждый log_buffer (2*log_parallelism);
  • для управления Library Cache & Shared Pool: 16 защелок на library cache lock + 26 защелок на library cache pin. Особенно стоит отметить Защелки на library cache pin. Эта защелка вызывается при каждом выполнении PL/SQL;
  • 26 защелок для выполнения операций над Row Cache;
  • защелка на SCN;
  • защелка на SMON;
  • защелка на обращение к файлам БД (по одной блокировке на файл данных);
  • защелка на транзакцию над контрольным файлом;
  • защелка, управляющая job (работами);
  • защелка на выделение/удаление сегментов в табличных пространствах TEMP и UNDO;
  • защелка на выполнение действий над файлом паролей и файлом инициализации (ALTER SYSTEM SET …).

А теперь попробуем разобраться с некоторыми важными защелками:

Cache buffers lru chain (цепочка кеш-буферов в порядке обращения) – используется для защиты средств доступа к буферам блоков в кеш-буфере. Размер кеш-буфера устанавливается параметром инициализации db_block_buffers. Размещается он в SGA, содержит кешированную копию данных, считанных с файла данных. Если процессы используют данные, считанные предыдущими процессами и находящимися в кеш-буфере, то значительно ускоряется выполнение операций ввода/вывода. Кеш буфер организован в виде двух списков: список измененных буферов (содержит перечень измененных, но не записанных на диск буферов) и списка LRU. Список LRU содержит перечень закрепленных буферов (буфера, используемые другими процессами); перечень измененных буферов, но еще не занесенных в список измененных буферов; перечень свободных буферов ( незанятые буфера, могут быть использованы). Процесс, который должен считать данные с диска, каких нет в кеш-буфере, просматривает список LRU на наличие свободных буферов. При интенсивном использовании кеш-буфера, интенсивно используется список LRU, что приводит к конкуренции за использование защелки Cache buffers lru chain. Минимизировать конкуренцию за защелку можно, увеличив значения параметра инициализации db_block_lru_latches; увеличив значение параметра инициализации db_block_buffer; оптимизировав sql-операторы, чтобы потребность в свободных буферах была минимальной.

Redo allocation – используется для защиты буфера журнала регистрации транзакций. Эта защелка используется, если объем информации, которую нужно записать в журнал, не превышает значения параметра инициализации log_small_entry_max_size. Наличие конкуренции за буфер журнала регистрации транзакций можно определить запросом: select * from v$sysstat where name ='redo log space requests'; если значение value велико нужно увеличить значение параметра инициализации log_buffer.

Redo copy – используется для защиты буфера журнала регистрации транзакций. Эта защелка используется, если объем информации, которую нужно записать в журнал, превышает значения параметра инициализации log_small_entry_max_size. Одновременно может существовать несколько защелок redo copy (определяется параметром инициализации log_simultaneus_copies, но не превышает количества центральных процессоров помноженного на два). Если существует конкуренция за redo allocation, то уменьшив log_small_entry_max_size, можно спровоцировать использование защелки redo copy. Если же существует конкуренция за redo copy, то необходимо увеличить log_small_entry_max_size ( чтобы использовалась redo allocation) или увеличить log_simultaneus_copies ( чтобы увеличить количество доступных защелок redo copy).

Можно увеличить параметр инициализации log_entry_prebuild_threshold, так, чтобы данные, записанные в буфер журнала регистрации транзакций, группировались и записывались на диск. При увеличении этого параметра множество операций записи может быть сгруппировано в одну операцию и поэтому уменьшится конкуренция за использование защелок.

Library cache – используется для контроля за доступом к кешу библиотеки. Кеш библиотеки включает разделяемую область sql, неразделяемую область sql, пакеты процедур, и другие управляющие структуры. В разделяемой области содержаться sql-операторы которые совместно используются несколькими сеансами. Повысив степень совместного доступа к этим операторам, можно избежать конкуренции при использовании защелок. Большой объем синтаксического анализа, очень частые запросы на открытие курсора из-за низкого уровня разделения ресурсов между процессами – основная причина конкуренции за использование защелок. Избежать такой конкуренции можно если придерживаться определенных стандартов кодирования, применяя стандарты оформления абзацев и использования регистров для символов, избегать ненужных пробелов, использовать связанные переменные и т. д. Синтаксический разбор может быть сокращен закреплением в разделяемом пуле часто используемых объектов , таких как процедуры и пакеты: они никогда не будут покидать разделяемый пул и поэтому время синтаксического разбора уменьшиться. Для определения часто используемых объектов ( executions большое) используется запрос select * from v$db_object_cache. Закрепить объект в разделяемом пуле можно с помощью dbms_share_pool.keep(‘название объекта’,’P’). Незакрепленные объекты в разделяемом пуле определяются запросом: select * from v$db_object_cache where kept=’NO’

В отличие от защелок, очереди запросов (enqueue) действительно образуют упорядоченную очередь FIFO. Каждый запрос в очереди, кроме порядкового номера, отражает еще и режим запроса (share, exclusive). Например, запросы на чтение могут выполняться одновременно, не блокируя друг друга. Если запрос на блокировку enqueue не может быть удовлетворен, то он ставится в очередь. Порядковые номера в очереди запрашиваются через системные вызовы ОС (семафоры).

1 комментарий

Прокоментировать

Vladimir
31 марта 2009 г. в 13:40

увеличив значение параметра db_block_lru_latches
нельзя мимнимизировать конкуренцию за защелку
т.к данная защелка сache_buffers_lru_chain на WS(рабочую область)
Cache buffers lru chain - не цепочка буферов, а защелка!
db_block_lru_latches можно увеличивать лишь в двух случаях
1)при увеличичении числа CPU
2)при увеличении db_writer_processes
хотя во втором случае Oracle сам увеличивает
db_block_lru_latches (количество защелок на WS)

 

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

Я не спамер: введите суму 2+4



 

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

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

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

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


 
 

Бизнес форум

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

Микрофон
19 августа, 2 ответа
Сумочка
19 августа, 2 ответа
средства для рук
17 августа, 3 ответа