Цель
Защелки - это блокировка словарей данных. И также как и обычная блокировка строки влияет на время выполнения запроса. Чем больше защелок - тем дольше выполняется запрос.
Далее мы разберем как узнать их количество - эта информация поможет в анализе производительности запросов, поможет выявить слабые места.
Описание компонентов
v$latch
Представление выводит информацию о защелках по последней выполненной транзакции. Группируя информацию о родительской и дочерней защелке. Состоит из следующих полей:
Поле | Тип | Описание |
---|---|---|
addr | raw(4|8) | адрес защелки |
latch# | number | идентификатор защелки |
level# | number | уровент защелки |
name | varchar2(64) | имя защелки |
hash | number | хэш защелки |
gets | number | количество запросов на защелку в режиме ожидания |
misses | number | cколько раз была запрошена защелка в режиме ожидания, и запрашивающая сторона должна была ждать |
sleeps | number | количество раз, когда запрос защелки с ожиданием приводил к спящему сеансу в ожидании защелки |
immediate_gets | number | количество запросов на защелку в режиме без ожидания |
immediate_misses | number | количество раз, когда запрос блокировки без ожидания не удался (то есть был пропущен) |
waiters_woken | number | неподдерживаемый Oracle столбец, всегда будет равен 0 |
waits_holding_latch | number | неподдерживаемый Oracle столбец, всегда будет равен 0 |
spin_gets | number | запросы с готовностью подождать защелки, которые пропустили первую попытку, но были успешными во время вращения |
sleep1-11 | number | неподдерживаемые Oracle столбцы, всегда будут равны 0 |
wait_time | number | время ожидания защелки (в микросекундах) |
con_id | number | идентификатор контейнера (для мультиарендной контейнерной базы данных CDB) |
Права
Для выполнения представления у пользователя (в моем случае PROD) должен быть доступ на все таблицы, подключаемся к БД с помощью пользователя SYS с ролью SYSDBA и выполняем скрипты ниже:
Пример измерения количества защелок
Получение количества одной защелки
Рассмотрим как узнать конкретную защелку DML lock allocation (Распределение блокировки DML). В примере показанном ниже, будут меняться ранее сгенерированные данные, умышленно будет добавлен rollback в цикл, чтобы увидеть защелки.
Результат:
Получение количества всех защелок
Усложним задачу, чтобы видеть все защелки по двум запросам и сразу выводить по ним разницу для этого:
- Необходимо добавить себе программу по сбору и сравнению статистики, если уже есть, идем далее.
- Расширим наше представление prod.stats_vw, добавив в конце 4-й скрипт вывода информации о защелках:
create or replace view prod.stats_vw as --первый скрипт по выводу статистики select 'STAT' as inf_type, -- для inf_type в stats_tbl a.name as name, -- для name в stats_tbl b.value as value -- для value в stats_tbl from v$statname a join v$mystat b on a.statistic# = b.statistic# --команда объединения union all --второй скрипт по фиксации общего времени select 'ETIME', -- сокращенно от Elapsed time (общее время) 'Elapsed Time', hsecs from v$timer --команда объединения union all --третий скрипт по фиксации времени CPU select 'CTIME', --сокращенно от CPU time (время ЦПУ) 'CPU Time', dbms_utility.get_cpu_time from dual --команда объединения union all --четвертый скрипт по фиксации защелок select 'LATCH', --сокращенно от CPU time (время ЦПУ) l.name, l.gets from v$latch l;
- Преобразуем пример, показанный ранее, в новый, с применением программы:
begin --фиксируем начало работы fix_inf_prc(1,'before'); --ROLLBACK в конце for rec in 1..1000 loop update prod.operation set op_date = trunc(sysdate) where rownum = 1 and op_date != trunc(sysdate); end loop; rollback; --фиксируем завершение работы fix_inf_prc(1,'after'); --фиксируем начало работы fix_inf_prc(2,'before'); --ROLLBACK в цикле for rec in 1..1000 loop update prod.operation set op_date = trunc(sysdate) where rownum = 1 and op_date != trunc(sysdate); rollback; end loop; rollback; --фиксируем завершение работы fix_inf_prc(2,'after'); --вывести отчет stats_report_prc(1000); --показывать значение, отличающиеся на 1000 end;
Результат:
Спасибо за внимание!