Базы данных Oracle - статьи

         

Последствия блокировок битовых карт


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

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

Тестовые данные: Создание структур данных для примера create table t1 (id number, bit_col number);

insert into t1 values(0,1); insert into t1 values(1,1); insert into t1 values(2,2); insert into t1 values(3,3); insert into t1 values(4,4);

create bitmap index t1_bit on t1(bit_col);

Изменение одной строки update t1 set bit_col = 2 where id = 1;

(0,1) битовая карта "откуда" (1,1) -> (1,2) заблокированная строка (2,2) битовая карта "куда" (3,3) (4,4)

Рисунок 3. Готовимcя к тестированию изменений.

Обратите внимание, что изменен проиндексированный столбец лишь одной строки таблицы. Если сбросить в символьном виде блоки индекса и таблицы, окажется, что байт блокировки установлен для одной строки таблицы, но заблокированы две секции индекса на основе битовых карт. Это секция для близких строк с текущим значением 1 в проиндексированном столбце (секция, "откуда" убирается строка) и секция для близких строк со значением 2 (секция, "куда" переносится строка). (На самом деле, эти две секции битовых карт скопированы, и обе копии заблокированы).

Теперь осталось разобраться, насколько "агрессивно" блокирует сервер Oracle в данном случае.

Ответ может показаться несколько неожиданным для тех, кто мыслит категориями "индексы на основе битовых карт приводят к блокированию таблицы".

Вполне можно сделать следующие изменения (каждое - в отдельном тесте).

Изменить строку в секции "откуда", если это изменение не затрагивает столбец индекса на основе битовых карт.

update t1 set id = 5 where id = 0;


Изменить строку в секции "куда", если это изменение не затрагивает столбец индекса на основе битовых карт.

update t1 set id = 6 where bit_col = 2;

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

Конечно, конфликты блокирвок возможны, - например, ни один из следующих операторов не сможет изменить заблокированную строку таблицы, но их выполнение вызовет ожидание соответствующим сеансом снятия блокировки "TX" в режиме 4 (разделяемой блокировки)

update t1 set bit_col = 4

where id = 2; -- bit_col = 2

update t1 set bit_col = 2

where id = 3 -- bit_col = 3

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

Помните, что вполне можно, в нашем случае, изменять столбец, по которому создан индекс на основе битовых карт, в близкой строке, если ни исходное, ни новое значения не равны 1 или 2. Например:

update t1 set bit_col = 4 where bit_col = 3;

Итак, индексы на основе битовых карт НЕ вызывают блокирование таблицы. Если изменения не затрагивают проиндексированный столбец, наличие индексов на основе битовых карт не вызывает вообще никаких проблем. Даже если проиндексированные столбцы изменяются, можно создать набор не конфликтующих изменений.


Содержание раздела