30.08.2016 09:56
Нашел интересную тему
Хочу ее немного развернуть.

В ORACLE автоматически применяются следующие основные классы блокировок:

Блокировки данных (DML-блокировка, то есть блокировка на уровне операторов языка манипулирования данными) применяется для таблиц и используется для защиты данных (для обеспечения целостности данных). К этому типу относятся блокировки строки данных или блокировка на уровне таблицы, затрагивающая все строки таблицы. Генерируются при выполнении операторов insert, delete, update, select for update.

Блокировки словаря (DDL-блокировка, то есть блокировка на уровне операторов определения данных) используется для защиты структуры объектов. Генерируется при выполнении операторов create, alter.

Внутренняя блокировка и защелка (enqueues, internal locks, latchs)защищают внутреннюю структуру данных. Используются для блокировки, например, библиотечного кеша.

Блокировки DML

Блокировки таблиц (TM) применяются, если в транзакции выдается один из операторов insert, delete, update, select for update, lock table. Таблицы блокируются ораклом, чтобы зарезервировать доступ к таблице и предотвратить конкуренцию между операторами DDL за таблицу. Проще говоря, блокировка таблиц (TM) позволяет быть уверенным, что структура таблицы не изменится при изменении её содержимого.

Блокировки TM могут быть в следующих режимах (lmode) : 3- row exclusive монопольная блокировка строки (RX) при выполнении операторов insert, delete, update; 2- row share разделяемая блокировка строки (RS) при выполнении select for update; 6 – exclusive монопольная блокировка ( X) при выполнении lock table.

Блокировка транзакций TX устанавливается при выполнении следующих операторов insert, delete, update, select for update. Блокировки транзакций работают только в режиме (lmode) - 6 exclusive (X) монопольная блокировка. Блокировки транзакций всегда осуществляются на уровне строк: блокируется строка и предотвращается изменение строки другими транзакциями до тех пор, пока не буде выполнен откат текущей транзакции или транзакция не будет зафиксирована. Чтобы была установлена блокировка TX, сначала устанавливается блокировка TM для таблицы в режиме 3 (RX). Затем устанавливается блокировка TX в режиме 6 (X). Блокировка TX не будет установлена, если другая транзакция установила блокировку TX на эту же строку.

Блокировки могут быть еще в режиме 4 (разделяемая блокировка таблицы share mode, генерируется, например, оператором lock table <…> in share mode) и 5 (разделяемая блокировка таблицы и монопольная блокировка строк share row exclusive; генерируется, например, оператором lock table <…..> in share row exclusive mode). Но эти режимы встречаются крайне редко.

А теперь немножко про так называемое «преобразование блокировок» или «распространение блокировок». Что это за механизм? Вот описание из Том Кайта :

Берется блокировка самого низкого из возможных уровней (наименее ограничивающая блокировка) и преобразуется к более высокому (ограничивающему) уровню.

Например, при выборе select строки из таблицы с конструкцией FOR UPDATE будет создано две блокировки. Одна из них устанавливается на выбранную строку (или строки); это — исключительная блокировка exclusive (6 режим): ни один сеанс уже не сможет заблокировать соответствующие строки в исключительном режиме. Другая блокировка, ROW SHARE (2 режим) (совместное блокирование строк таблицы), устанавливается на соответствующую таблицу. Это предотвратит исключительную блокировку таблицы другими сеансами и, следовательно, возможность изменения, например, структуры таблицы. Все остальные операторы смогут работать с таблицей.

Другой сеанс может даже сделать таблицу доступной только для чтения с помощью оператора LOCK TABLE X IN SHARE MODE, предотвратив тем самым ее изменение. Однако этот другой сеанс не должен иметь права предотвращать изменения, которые уже происходят.

Поэтому, как только будет выполнена команда фактического изменения строки (update), сервер Oracle преобразует блокировку ROW SHARE (2 режим) в более ограничивающую блокировку ROW EXCLUSIVE (3 режим), и изменение будет выполнено. Такое преобразование блокировок происходит само собой независимо от приложений.

То есть блокировка таблицы TM преобразуется из низкого (лояльного) уровня (режим 2) в более высокий (жесткий) уровень (режим 3).

В отличие от других баз данных , база данных ORACLE никогда не переводит блокировки на уровень таблицы , если заблокирована основная часть строк в таблице. То есть в ORACLE никогда не применяется эскалация блокировок (увеличение размера блокируемых объектов). Это связано с тем, что ORACLE нет необходимости уменьшать нагрузку на диспетчер блокировок баз данных, так как нет традиционного диспетчера блокировок. То есть, нет диспетчера, поддерживающего список со всеми строками, заблокированными в базе. В ORACLE блокировки хранятся как атрибут данных (см. описание формата блока ORACLE) . У Тома Кайта есть очень красивое объяснение, как организованы блокировки в ORACLE. Привожу выдержку:

Сервер Oracle поступает примерно так:

Находит адрес строки, которую необходимо заблокировать.
Переходит на эту строку.
Блокирует ее (ожидая снятия блокировки, если она уже заблокирована и при этом не используется опция NOWAIT).

Вот и все.

Поскольку блокировка хранится как атрибут данных, серверу Oracle не нужен традиционный диспетчер блокировок. Транзакция просто переходит к соответствующим данным и блокирует их (если они еще не заблокированы). Иногда при обращении данные кажутся заблокированными, хотя фактически они уже не заблокированы.При блокировании строки данных в Oracle с блоком данных связывается идентификатор транзакции, причем остается там после снятия блокировки. Этот идентификатор уникален для нашей транзакции и задает номер сегмента отката, слот и номер изменения (sequence number). Оставляя его в блоке, содержащем измененную строку, мы как бы говорим другим сеансам, что "эти данные принадлежат нам" (не все данные в блоке, только одна строка, которую мы меняем). Когда другой сеанс обращается к блоку, он "видит" идентификатор блокировки и, "зная", что он представляет транзакцию, определяет, активна ли еще транзакция, установившая блокировку. Если транзакция уже закончена, сеанс может получить данные "в собственность". Если же транзакция активна, сеанс "попросит" систему уведомить его о завершении транзакции. Таким образом, имеется механизм организации очереди: сеанс, нуждающийся в блокировке, будет помещен в очередь в ожидании завершения транзакции, после чего получит возможность работать с данными.

Блокировки DDL

Такие блокировки устанавливаются на объект автоматически при выполнении DDL –команд для защиты от других сеансов. Есть три типа DDL-блокировок:

Исключительные блокировки
Запрещают другим сеансам устанавливать DDL-блокировки и TM-блокировки. Это означает, что в процессе выполнения DDL-оператора можно только выбирать данные из таблицы, но нельзя изменять данные. Преобладающее большинство операторов DDL устанавливают именно такую блокировку. Но есть приятные исключения: команда create index ind1 on t1(pole) online сгенерирует на таблицу TM –блокировку в режиме 2 (ROW SHARE). Это означает, что другие сеансы не смогут изменить структуру таблицы, но данные в этой таблице менять можно. Когда индекс будет создан, то будут учтены затем и изменения в данных таблицы проведенных во время создания индекса.

Разделяемые блокировки
При таких блокировках защищается структура объекта от других сеансов, но данные можно изменять. Устанавливаются на объекты, от которых зависят скомпилированные хранимые объекты (процедуры, представления и т.д.) Например, для выполнения команды create view someview as select * from sometable. На таблицу sometable будет установлена именно такая блокировка. Данные в ней менять можно, но нельзя менять структуру.

Нарушаемые блокировки разбора Они позволяют объекту, например плану запроса, хранящемуся в кеше разделяемого пула, зарегистрировать свою зависимость от другого объекта. При выполнении оператора DDL, над объектом, заблокированным таким образом, сервер Oracle пометит его как недействительный. Но DDL-оператор будет выполнен без проблем.

Есть представление DBA_DDL_LOCKS для просмотра действующих блокировок. Особо хочу обратить внимание на значение столбца owner. В этом столбце прописан владелец объекта, а не владелец блокировки. Это представление весьма полезно для разработчиков приложений для выявления блокирующих сеансов. Например, если вы не можете откомпилировать процедуру или выполнить оператор grant, то в этом представлении можно увидеть , что необходимый объект выполняется другим сеансом.

Типы пользовательских и объектных блокировок

RW Row wait enqueue lock

TM DML enqueue lock

TX Transaction enqueue lock

UL User supplied lock

Типы системных блокировок

BL Buffer hash table instance lock

CF cross-instance function invocation instance lock

CI Control file schema global enqueue lock

CS Control file schema global enqueue lock

DF Data file instance lock

DM Mount/startup db primary/secondary instance lock

DR Distributed recovery process lock

DX Distributed transaction entry lock

FI SGA open-file information lock

FS File set lock

IR Instance recovery serialization global enqueue lock

IV Library cache invalidation instance lock

LA .. LP Library cache lock instance lock (A..P = namespace)

LS Log start/log switch enqueue lock

MB Master buffer hash table instance lock

MM Mount definition global enqueue lock

MR Media recovery lock

PA .. PZ Library cache pin instance lock (A..Z = namespace)

QA .. QZ Row cache instance lock (A..Z = cache)

RE USE_ROW_ENQUEUES enforcement lock

RT Redo thread global enqueue lock

SC System commit number instance lock

SH System commit number high water mark enqueue lock

SN Sequence number instance lock

SQ Sequence number enqueue lock

ST Space transaction enqueue lock

SV Sequence number value lock

TA Generic enqueue lock

TD DDL enqueue lock

TE Extend-segment enqueue lock

TS Temporary segment enqueue lock (ID2=0)

TS New block allocation enqueue lock (ID2=1)

TT Temporary table enqueue lock

UN User name lock

WL Being-written redo log instance lock

WS Write-atomic-log-switch global enqueue lock

Блокировкой управляют два параметра файла init.ora: serializable=false, row_locking=always.
30.08.2016 10:29
Достаточно удобный скрипт просмотра блокировок находится здесь
$ORACLE_HOME/rdbms/admin/utllockt.sql
30.08.2016 11:10
Скрипт на просмотр заблокированных объектов

SQL код:
select distinct
       o.object_type||' '||o.owner||'.'||o.object_name Object,
       to_char(sh.LOGON_TIME,'HH24:MI DD.MM.YY') "Holder logon",
       sh.username || '(' || sh.sid || ',' || sh.serial# || ')' "Holder session",
       sh.event "Holder event",
       sh.osuser||'@'||sh.machine "Holder OS",
       sh.module "Holder module",
       to_char(sw.LOGON_TIME,'HH24:MI DD.MM.YY') "Waiter logon",
       sw.username || '(' || sw.sid || ',' || sw.serial# || ')' "Waiter session",
       sw.event "Waiter event",
       sw.osuser||'@'||sw.machine "Waiter OS",
       sw.module "Waiter module",
decode(lh.lmode,
              1,'null',
              2,'row share',
              3,'row exclusive',
              4,'share',
              5,'share row exclusive',
              6,'exclusive') "Lock Type"
from v$session   sw,
     v$lock      lw,
     all_objects o,
     v$session   sh,
     v$lock      lh
where lh.id1 = o.object_id
      and lh.id1 = lw.id1
      and sh.sid = lh.sid
      and sw.sid = lw.sid
      and sh.lockwait is null
      and sw.lockwait is not null
      and lh.type = 'TM'
      and lw.type = 'TM'; 
Часовой пояс GMT +3, время: 11:08.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.