Oracle: что такое Latch Event и почему оно происходит в базе?

Oracle: что такое Latch Event и почему оно происходит в базе?

Недавно на форуме Oracle был вопрос о событии защелки (latch event):

latch: parallel query alloc buffer

Человек, опубликовавший вопрос, отметил, что информации о событии защелки (latch event) не так много, если таковая имеется. Вопрос, поставленный на этом форуме, был, по сути, заключался лишь в том, что такое это такое вообще и почему это происходит? Чтобы ответить на этот вопрос, необходимо будет понять некоторые "входы и выходы" параллельной обработки запросов, происходящей в СУБД Oracle.

Параллельная обработка запросов выделяет подчиненные фоновые процессы (slaves) для выполнения основной части работы; в результате этого параллельные координаторы выделяют буферы сообщений для обработки промежуточных результатов. В зависимости от конфигурации системы и нагрузки, которую должны обрабатывать фоновые процессы, может быть выделено удивительно большое количество буферов сообщений. Существует два уравнения, которые могут быть использованы для вычисления количества буферов, которые будут необходимы. Эти уравнения используют значение параллельной степени, которое либо вычисляется Oracle, либо указывается в подсказке (hint); для простоты это значение будет представлено переменной pd. Для базы данных Oracle без RAC количество требуемых буферов будет рассчитываться как:

pd(pd+1)*3

Использование RAC несколько усложняет схему и добавляет экземпляров, и в результате уравнение модифицируется:

 pd(pd+1)*4


В системах без RAC для вычисления расчетного количества буферов, которые Oracle может выделить, будут использоваться различные степени параллелизма. Рассмотрим запрос, выполненный с параллельной степенью, равной 4; первое уравнение дает следующие результаты:

4(4+1) * 3

становится:

 4(5) * 3 

и после упрощения:

20 * 3 = 60

Четыре параллельных фоновых процесса могут выделить 60 буферов. Теперь рассмотрим установку параллельной степени 16. Важно знать, что это вычисление буфера не пропорционально; степень 16 в четыре раза превышает исходную настройку, но результат далек от четырехкратного исходного результата:

 16(16+1) * 3

складываем:

16(17) * 3

что сводится к:

272 * 3 = 816

Параллельное выполнение с использованием 16 фоновых процессов требует в общей сложности 816 буферов сообщений, что почти в 14 раз больше, чем требуется для выполнения при параллельной степени 4. Учитывая вычислительную мощность современных серверов, нет ничего смешного в том, чтобы установить параллельную степень 128. Выполнение этого вычисления приводит к следующему результату:

126(128+1) * 3

Продолжаем как и в предыдущих расчетах:

128(129) * 3

в результате:

16512 * 3 = 45936

Это значительное увеличение по сравнению с буферами, выделенными для параллельного выполнения степени 4, и намного больше, чем можно было бы ожидать, если результат выполнения степени 4 умножить на 32. Наличие ожидания" latch: parallel query alloc buffer " в качестве одного из верхних ожиданий не является надуманной идеей. Определяющим фактором, влияющим на это ожидание, является то, где находится пул сообщений PX ('px msg pool'); и большой пул (large pool), и общий пул (shared pool) - это места, где обычно находится этот пул. Приведенный ниже запрос может быть выполнен, чтобы узнать, где он находится в данной конфигурации базы данных:

break on pool skip 1
column name format a32
 
select
    pool,
    name,
    bytes
from
    v$sgastat
where
      pool = 'large pool'
   or
      name like '%PX%'
   or
      name like '%para%'
order by
    pool, name;

Ниже приведен пример результатов этого запроса:

BING @ quanghoo > break on pool skip 1
BING @ quanghoo > column name format a32
BING @ quanghoo > 
BING @ quanghoo > select
              2         pool,
              3         name,
              4         bytes
              5 from
              6         v$sgastat
              7 where
              8         pool = 'large pool'
              9    or
             10         name like '%PX%'
             11    or
             12         name like '%para%'
             13 order by
             14         pool, name;

POOL               NAME            BYTES
------------ -------------------------------- ----------
large pool  PX msg pool         491520
               free memory         7897088

shared pool   PX QC deq stats         1696
              PX QC msg stats         3080
              PX list of chunk lists  1088
              PX msg pool struct      56
              PX scan rate stats      1080
              PX server deq stats     1696
              PX server msg stats     3080
              PX subheap              156344

POOL         NAME                   BYTES
------------ -------------------------------- ----------
shared pool  PX subheap desc            256
             parallel kcbibr               32
             parallel kcbibr dbwr bitv     16
             parallel_max_servers          14720
             param hash values             15912
             parameter blocks              31824
             parameter handle              137584
             parameter string values       291240
             parameter table block         1050648
             parameter text value          9400
             parameter value memory        1416


21 rows selected.

Из приведенного выше примера видно, что "px msg pool" для этой базы данных находится в большом пуле. Версии Oracle старше 11.2 (некоторые из них все еще работают) могут использовать общий пул; это может привести к тому, что ожидание "latch: parallel query alloc buffer" будет испытывать исключительно длительное время ожидания в результате конкуренции за доступные ресурсы.

Для конфигураций RAC уравнение изменяется незначительно, но это не означает, что вычисленные результаты будут следовать описанной выше тенденции. Используя те же самые параллельные настройки степени с первого раунда вычислений различия начинаются с малого, но вскоре резко возрастают:

4(4+1) * 4

 упрощаем:

4(5) * 4

и получаем окончательный результат:

20 * 4 = 80

Мы получили увеличение на 33% просто потому, что используем Oracle RAC. Переходя к параллельной степени 16 получаем следующее уравнение:

16(16+1) * 4

после упрощения:

 16(17) * 4

с результатом:

272 * 4 = 1088

Это еще 272 буфера в результате кластерной конфигурации базы данных.

СУБД Oracle и других поставщиков позволяют выставлять параллельную степень до 128 или выше. При этом при степени 128 вычисленное распределение становится:

128(128+1) * 4

упрощаем:

128(129) * 4

результат:

16512 * 4 = 66048

66 048 - это большое количество буферов сообщений. Даже 10 лет назад параллельная степень 128 могла нанести вред транзакционной базе данных и, возможно, некоторым меньшим хранилищам данных или витринам данных с ожиданием защелки "параллельного запроса". В зависимости от общего использования ресурсов (диск, память, своп) некоторые небольшие системы все еще могут стать жертвой этого ожидания.

Если планы параллельного выполнения редки в конфигурации базы данных, это ожидание фиксации (latch wait) может быть мало или вообще не беспокоить. Если существует разумная вероятность того, что параллельное выполнение может произойти, то осознание того, что параллельное выделение буфера может являться потенциальной проблемой. Тогда пресная жизнь DBA не достигнет уж такого резкого эмоционального всплеска  и это знание сократит время исследования и разрешения проблемы. Как говориться,  "Предупреждён — значит вооружён". Успехов в рулении базами данных, комрадос! :)

Вас заинтересует / Intresting for you:

Oracle и непроцедурный доступ ...
Oracle и непроцедурный доступ ... 6040 просмотров Antoni Tue, 21 Nov 2017, 13:32:50
Listener Oracle
Listener Oracle 5496 просмотров Rasen Fasenger Tue, 21 Nov 2017, 13:18:05
NULL в ORACLE и как с ним можн...
NULL в ORACLE и как с ним можн... 4710 просмотров Tue, 21 Nov 2017, 13:32:50
Instant Client
Instant Client 1593 просмотров Александров Попков Tue, 21 Nov 2017, 13:18:05