Типи блокировок бази даних Oracle
Знайшов цікаву тему Хочу її трохи розгорнути.
В ORACLE автоматично застосовуються такі основні класи блокувань:
Блокування даних (DML-блокування, тобто блокування на рівні операторів мови маніпулювання даними), застосовується для таблиць і використовується для захисту даних (для забезпечення цілісності даних). До цього типу відносяться блокування рядка даних або блокування на рівні таблиці, що стосується всіх рядків таблиці. Генеруються під час виконання операторів insert, delete, update, select for update.
Блокування словника (блокування DDL, тобто блокування на рівні операторів визначення даних) використовується для захисту структури об'єктів. Генерується під час виконання операторів create, alter.
Внутрішнє блокування та клямка (enqueues, internal locks, latchs)захищають внутрішню структуру даних. Використовуються для блокування, наприклад бібліотечного кеша.
Блокування таблиць (TM)застосовуються, якщо в транзакції видається один із операторів insert, delete, update, select for update, lock table. Таблиці блокуються ораклом, щоб зарезервувати доступ до таблиці та запобігти конкуренції між операторами DDL за таблицю. Простіше кажучи, блокування таблиць дозволяє бути впевненим, що структура таблиці не зміниться при зміні її вмісту.
Блокування 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 надходить приблизно так:
Оскільки блокування зберігається як атрибут даних, сервер Oracle не потребує традиційного диспетчера блокувань. Транзакція просто переходить до відповідних даних та блокує їх (якщо вони ще не заблоковані). Іноді при зверненні дані здаються заблокованими,хоча фактично вони вже не заблоковані. При блокуванні рядка даних Oracle з блоком даних зв'язується ідентифікатор транзакції, причому залишається там після зняття блокування. Цей ідентифікатор є унікальним для нашої транзакції і задає номер сегмента відкату, слот та номер зміни (sequence number). Залишаючи його в блоці, що містить змінений рядок, ми говоримо іншим сеансам, що "ці дані належать нам" (не всі дані в блоці, тільки один рядок, який ми змінюємо). Коли інший сеанс звертається до блоку, він "бачить" ідентифікатор блокування і, "знаючи", що він представляє транзакцію, визначає, чи активна транзакція, що встановила блокування. Якщо транзакцію вже закінчено, сеанс може отримати дані "у власність". Якщо транзакція активна, сеанс "попросить" систему повідомити його про завершення транзакції. Таким чином, є механізм організації черги: сеанс, який потребує блокування, буде поміщений у чергу в очікуванні завершення транзакції, після чого отримає можливість працювати з даними.
Такі блокування встановлюються на об'єкт автоматично при виконанні команд DDL для захисту від інших сеансів. Є три типи DDL-блокувань:
Виключні блокуванняЗабороняють іншим сеансам встановлювати DDL-блокування та TM-блокування. Це означає, що в процесі виконання DDL-оператора можна вибирати дані з таблиці, але не можна змінювати дані. Переважна більшість операторів DDL встановлює саме таке блокування. Але є приємні винятки: команда create index ind1 on t1(pole) online згенерує таблицю TM –блокування в режимі 2 (ROW SHARE). Це означає, що інші сеанси не можуть змінити структуру таблиці, але дані в цій таблиці можна змінювати. Коли індекс буде створено, то будуть враховані потім ізміни даних таблиці проведених під час створення індексу.
Блокування, що розділяютьсяПри таких блокуваннях захищається структура об'єкта від інших сеансів, але дані можна змінювати. Встановлюються на об'єкти, від яких залежать скомпільовані об'єкти, що зберігаються (процедури, уявлення і т.д.) Наприклад, для виконання команди create view someview as select * from sometable. На таблицю деякихtable буде встановлено саме таке блокування. Дані в ній можна змінювати, але не можна змінювати структуру.
Порушуються блокування розборуВони дозволяють об'єкту, наприклад плану запиту, що зберігається в кеші пулу, що розділяється, зареєструвати свою залежність від іншого об'єкта. При виконанні оператора DDL над об'єктом, заблокованим таким чином, сервер Oracle помітить його як недійсний. Але DDL-оператор буде виконано без проблем.
Типи користувацьких та об'єктних блокувань
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 функція 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блокування екземпляра таблиці
Глобальне блокування черги визначення монтування MM
MR Media блокування відновлення
PA .. PZ Блокування примірника кешу кешу бібліотеки (A..Z = простір імен)
QA .. QZ Блокування екземпляра кешу рядків (A..Z = кеш)
RE USE_ROW_ENQUEUES примусове блокування
RT Повторити глобальне блокування черги
Блокування примірника номера фіксації системи SC
SH System commit number high water mark in queue lock
SN Блокування екземпляра порядкового номера
SQ Блокування порядкового номера в черзі
Блокування черги транзакцій ST Space
Блокування значення порядкового номера SV
TA Загальне блокування черги
Блокування черги TD DDL
TE Блокування черги розширеного сегмента
TS Тимчасове блокування сегмента в черзі (ID2=0)
TS Нове блокування черги розподілу блоків (ID2=1)
TT Тимчасове блокування таблиці в черзі
Блокування імені користувача UN
Блокування примірника повторного журналу WL
WS Write-atomic-log-switch глобальне блокування черги