Простое использование Lock Print

Простое использование Lock Print

Мы посмотрим на пример очень простой статистики, полученной от Lock Print без переключателей.

* Заголовок блока всегда будет первым.

* Далее идут группы владельцев - за группой владельца следуют все запросы этого владельца. Каждый владелец цепочки выводится с его запросами.

* После всех владельцев и запросов идут блокировки.

* Последним элементом является история записей.

Группа Lock_Header

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

Рис. 40.2. Группа Lock_Header

Наш отчет Lock Print представляет только что созданную базу данных, к которой имеет доступ одна копия isql в версии l.O.x Суперсервера для Windows.

Таблица 40.2. Записи группы Lock_Header

Элемент

Объяснение

1

LOCK_HEADER_BLOCK

Первая группа любого отчета Lock Print. Каждый отчет выводит ровно одну группу заголовка блока

2

Version (Версия)

Номер версии Менеджера блокировок. В Firebird 1.5 версия будет 115 для Суперсервера и 5 для Классического сервера. В Firebird 1.0.x (для нашего примера) такими версиями будут 114 и 4 соответственно

3

Active owner (Активный владелец)

Смещение в группе владельца, представляющее владельца, который в настоящий момент управляет таблицей блокировок, если такой существует. Если ни один процесс не пишет в таблицу блокировок, то активным владельцем будет 0

4

Length (Длина)

Общий объем памяти, выделенный таблице блокировок в байтах

5

Used (Используется)

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

6

Semmask (Маска семафора)

В системах, которые используют статичные семафоры (например, POSIX), это указатель на блок SMB, содержащий количество используемых семафоров. Когда нужен семафор, и ни один недоступен, Менеджер блокировок проходит через группы владельцев для поиска того владельца, имеющего неиспользуемый семафор. Если такого нет, система выдает сообщение об ошибке "Semaphores are exhausted" (Семафоры исчерпаны), означающее, что все скомпилированные в системе семафоры используются

7

Flags (Флаги)

Определены два битовых флага: LHB_shut_manager, который, если установлен, указывает, что база данных остановлена, и Менеджер блокировок не может обработать больше запросов; и LHB_lock ordering. В Firebird значение по умолчанию LHB_lock_ordering означает, что блокировки предоставляются в порядке запросов (порядок FIFO - первый пришел - первый ушел). Другая установка связана с устаревшей стратегией блокировки и сейчас не используется

8

Enqs (Запросы в очереди)

Запросы в очереди- полученные запросы на блокировку. Это число включает запросы, которые пока не могут быть удовлетворены, и запросы, которые могут быть удовлетворены немедленно, но не запросы, которые пришли и ушли

9

Converts (Преобразования)

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

10

Rejects (Отмены)

Запросы, которые не могут быть удовлетворены. Это могут быть блокировки, запрошенные в режиме "no wait", или это могут быть блокировки, которые были отменены, потому что приводили к взаимным блокировкам. Так как методы доступа иногда запрашивают блокировку "по wait" для внутренних структур, то вы увидите отмены, даже если все транзакции выполняются в режиме "wait" и не существует конфликтов между их операциями

11

Blocks(Блоки)

Запросы, которые не могут быть удовлетворены немедленно, потому что некоторый другой владелец имеет несовместимую блокировку на этот ресурс

12

Deadlock scans (Сканирование взаимных блокировок)

Сколько раз Менеджер блокировок просматривает цепочку блокировок и владельцев в процессе поиска взаимных блокировок. Менеджер блокировок начинает сканирование, когда процесс ожидает блокировки в течение 10 секунд

13

Deadlocks (Взаимные блокировки)

Количество найденных взаимных блокировок. См. разд. "Взаимные блокировки"

14

Scan interval (Интервал сканирования)

Количество секунд, которые ожидает Менеджер блокировок после начала запроса, прежде чем запустить сканирование взаимных блокировок. Значение по умолчанию 10 секунд

15

acquires(Запросы)

Количество раз, сколько владелец- или сервер от имени конкретного владельца - запрашивает исключительное управление для таблицы блокировок, чтобы выполнить изменения

16

Acquire blocks (Заблокированные запросы)

Количество раз, сколько владелец - или сервер от имени конкретного владельца - находился в состоянии ожидания при запросе исключительного управления таблицей блокировок

17

Spin count (Количество блокировок)

Это режим для ожидания взаимной блокировки и повторения запроса к таблице блокировок Firebird. По умолчанию установлено в ноль (отключено), но может быть сделано доступным в файле конфигурации

18

Mutex wait (Ожидание блокировок)

Процент попыток, которые были заблокированы, когда владелец старался обратиться к таблице блокировок - т.е. ((acquire blocks) / (acquires)) * 100

19

Hash slots (Сегменты хэша)

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

20

Hash lengths(Длина сегмента)

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

21

Remove node (Удаление узла)

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

22

Insert queue (Добавить очередь)

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

23

Insert prior (Предыдущее добавление)

Для очистки ошибочного добавления необходимо знать не только, что было добавлено, но и где это размещалось. Это как раз где

24

Owners (Владельцы)

Количество владельцев, которые соединены с таблицей блокировок. Только один из этих владельцев может изменять таблицу в конкретный момент ("активный владелец"). Другие владельцы ожидают освобождения блокировок. В нашем примере существует четыре владельца, не являющихся активными. Два владельца подключены через isql; один может быть подключен через DSQL, а еще один - сама база данных

25

Free owners (Свободные владельцы)

Количество блоков владельцев, выделенных владельцам, которые завершили их соединения, оставив блоки неиспользованными. В этом случае, вероятно, существует две транзакции, занимавшиеся созданием базы данных, которые были подтверждены

26

Free locks (Свободные блокировки)

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

27

Free requests (Свободные запросы)

Группы запросов идентифицируют запросы на блокировки ресурсов, неважно, удовлетворенные или нет. Этот элемент является количеством групп запросов, которые были освобождены и не использованы повторно

28

Lock ordering (Порядок блокировок)

Порядок блокировок означает получение запросов на блокировку в порядке их поступления, даже если последующие запросы должны быть обслужены немедленно. Включено, если флаг LHB_lock_ordering (см. элемент 7) установлен, и является значением по умолчанию для Firebird, т. к. обеспечивает оптимальную производительность. Альтернативой является (не используется сейчас) предоставление блокировок всем владельцам, желающим совместно использовать и "подавлять" владельцев, которые имеют существующие запросы. Эта не используемая стратегия гарантирует, что участники будут обработаны быстро, однако с риском причинения вреда другим

Группы владельцев

Группы владельцев, изображенные на рис. 40.3, описывают транзакцию или другого пользователя в Менеджере блокировок. Владельцы делятся на несколько типов, идентифицируемых пятью числами:

* 1 - процесс;

* 2 - база данных;

* 3 - клиентское соединение (в Классическом сервере клиентские соединения всегда являются процессами);

* 4 - транзакция;

* 5 - фиктивный процесс.

! ! !

ПРИМЕЧАНИЕ. В некоторых причудливых соглашениях по кодированию на транзакции никогда не ссылаются по их идентификационному номеру (4), а используют номер 255.

. ! .

Рис. 40.3. Группа владельца

Смещение конкретной группы владельца в таблице блокировок (здесь это 11 872) также является идентификатором, используемым в заголовке блокировок для "активного владельца", если этот пользователь активно изменяет таблицу блокировки. Первая выводимая группа обычно является номером, выводимым в группу заголовка блокировок в начале списка владельцев. Значение в списке указателей является полем в группе, которое содержит прямые и обратные указатели на группы владельцев. В табл. 40.3 описаны записи в группе владельца.

! ! !

СОВЕТ. Если вы просматриваете ваш результат работы утилиты в текстовом редакторе, вы можете отыскивать запросы, принадлежащие идентификатору этого владельца.

. ! .

Таблица 40.3. Записи групп владельцев

Элемент

Объяснение

1

OWNER BLOCK

Идентифицирует конкретного владельца. Число, следующее за заголовком (11 872), является смещением группы владельца в таблице блокировок и используется в качестве идентификатора владельца в этой таблице

2

Owner ID (Идентификатор владельца)

В Классическом сервере владельцем всегда является процесс, а идентификатором владельца всегда является идентификатор процесса. В Суперсервере владельцем является либо база данных и идентификатором будет группа базы данных, либо соединение и идентификатором будет эта группа соединения

3

Owner type (Тип владельца)

Типом владельца является число между 1 и 4 или 255 (фиктивный процесс)

4

Flags (Флаги)

Биты, которые определяют состояние. Процесс в одно и то же время может находиться более чем в одном состоянии (см. табл. 40.4)

5

Pending (Ожидание завершения)

Смещение группы запроса блокировки, описывающей запрошенную владельцем блокировку, но еще им не полученную. Владелец может иметь не более одного ожидающего запроса в один момент времени

6

Semid (Идентификатор семафора)

Идентификатор семафора, назначенного этому пользователю. Если он может быть использован, то слово "Available" (Доступен) должно следовать после идентификатора

7

Process_id (Идентификатор процесса)

В Классическом сервере это идентификатор процесса владельца. В Суперсервере, если владельцем является соединение, база данных или транзакция, то этот владелец станет идентификатором процесса

8

UID (Идентификатор пользователя)

В POSIX это идентификатор пользователя, являющегося владельцем процесса. В Windows это всегда ноль

9

Alive | Dead (Живой | Мертвый)

Lock Printer вызывает подпрограмму ISC_check_process_ existence и сообщает результат

10

Flags (Флаги)

Мнемоника флагов - корректно выводится 2 в виде 0x02 (а не 0x202, как в пункте (4))

11

Requests (Запросы)

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

12

Blocks (Группы)

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

В табл. 40.4 описаны состояния, представленные разнообразными флагами владельца.

Таблица 40.4. Состояния флагов владельца

Символ

Значение

Состояние

OWN blocking

1

Владелец заблокирован. Если установлен, значит процесс имеет, по меньшей мере, один блок, который другой процесс не хочет совместно использовать

OWN scanned

2

Владелец был проверен в текущем сканировании взаимных блокировок

OWN manager

4

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

OWN signal

8

Владелец должен был выдать сообщение, но не смог это сделать из-за ошибки, поэтому сигнал будет вызван менеджером блокировок

OWN wakeup

32

Владелец сообщил об освобождении блокировки

OWN starved

128

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

OWN signaled

16

Предполагается, что сигнал был отправлен. Он обращается к флагу OWN ast flags, но был суммирован по OR с указанными флагами. Обратите внимание: похоже, что выведенное здесь шестнадцатеричное число 202 является ошибкой синтаксического анализатора

Группы блокировок (группы ресурсов)

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

Типы блокировок"серии"

Блокировки ресурсов приходят различных типов или в виде серий в соответствии с типом ресурса, блокировку которого владельцы запрашивают у таблицы блокировок. В табл. 40.5 определяются и описываются различные типы блокировки ресурсов и их назначение.

Таблица 40.5. Типы ресурсов (серии)

Символ

Серия

Тип

LCK_database

1

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

LCK_relation

2

Индивидуальная таблица блокировки. Таблица блокировки указывает, что процесс читает и пишет в указанную таблицу в своей текущей транзакции или что он использует предложение RESERVING в операторе START TRANSACTION для сообщения своего намерения читать таблицу или писать в таблицу. В этой таблице ключевым полем является RDB$RELATION_ID. Заметьте, что оба запроса сообщают ее состояние как 2(2), указывая, что они запросили и получили блокировку на совместное чтение из таблицы

LCK_bdb

3

Индивидуальный блок буфера. Блокировка BDB является блокировкой страницы базы данных. Такие блокировки возводятся, когда два или более владельца соединяются с базой данных в Классическом сервере. Они устанавливаются, когда процесс собирается читать или писать страницу, и освобождаются, когда процесс завершает работу с буфером и требует освобождения памяти, или когда другому владельцу нужна эта страница

LCK_tra

4

Блокировка индивидуальной транзакции. Каждое действие получает исключительную блокировку для своей транзакции при ее старте. Другие владельцы могут получать пустую блокировку для чтения их состояния

LCK_rel_exist

5

Блокировка существования отношения. Предотвращает удаление таблиц, в то время как любые другие владельцы подготавливают запрос, который использует эту таблицу

LCK idx exist

6

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

LCK_attachment

7

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

LCK shadow

8

Блокировка для синхронизации добавления теневых копий (shadow). Главным образом для Классического сервера

LCK_sweep

9

Блокировка чистки для одного процесса чистки. Чистка является довольно дорогой операцией и лучше работает, если выполняется только одним потоком или соединением. Реальные "чистильщики" сохраняют исключительную блокировку в своей серии для исключения конфликтов. Эта серия используется для межпроцессных связей в Классическом сервере

LCK file_extend

10

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

LCK retaining

11

Самая молодая транзакция, подтвержденная с сохранением контекста (commit retaining). Это используется только в VMS. Возможно, это отмечает то место, где Firebird имеет расширенную семантику блокировок для нужд VMS и, следовательно, требует специальных средств для работы с Менеджером блокировок VMS

LCK expression

12

Механизм кэширования выражения индекса. Первоначально эта серия предназначалась для описания выражений индексов - как их вычислять, как должен выглядеть результат вычислений и т.д. По разным причинам сейчас это используется при удалении индекса

LCK record locking

13

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

LCK record

14

Блокировка записи. Эта серия также используется только в устаревшем коде эмуляции PC и использует RDB$DB_KEY в качестве имени блокировки

LCK_prc exist

15

Блокировка существующей процедуры. Не позволяет удалять процедуры и триггеры, пока любой другой владелец подготавливает запрос, который использует этот ресурс (или зависит от него)

LCK range_relation

16

Блокировка диапазона отношения. Опять же, эта серия используется только в коде эмуляции PC, который имеет концепцию изменения диапазонов

LCK_update_shadow

17

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

Варианты синтаксиса для отображения групп блокировок

Для вывода групп блокировок ресурсов заданной серии вам нужно включить номер серии в качестве аргумента:

fb_lock_print -s 2

Серия 1:база данных

Группа блокировки на рис. 40.4 представляет саму базу данных. Она имеет исключительный доступ для одного владельца- базы данных. В Классическом сервере вы увидите несколько владельцев для базы данных.

Рис. 40.4. Группа блокировки серии 1 (база данных) В табл. 40.6 объяснено, что означают записи этого отчета.

Таблица 40.6. Записи группы блокировки (ресурсов)

Значение

Объяснение

1

LOCK BLOCK

Идентифицирует группу описания заблокированного ресурса. Число является смещением этой группы в таблице блокировок. Оно указывает группу в другой группе, которая на нее ссылается

2

Series (Серия)

Тип ресурса, представляемого этой блокировкой. Это серия типа 1 - ресурс базы данных

3

Parent (Родитель)

Родитель для всех блокировок, связанных с базой данных. Является блокировкой самой базы данных. Единственными блокировками ресурсов, которые имеют значение 0 для родителя, являются блокировки базы данных и журналы. Ключи, которые идентифицируют блокировки в серии, имеют смысл только в контексте базы данных. Обратите внимание: несовпадения (ошибки) будут замечены внимательным читателем

4

State (Состояние)

Наивысшее текущее состояние блокировки. Блокировки имеют семь возможных состояний - см. рис. 40.1. Состояния внутренних блокировок Firebird описаны в самом начале этой главы. Пустая блокировка позволяет процессу получить блокировку ресурса, независимо от того, заблокирован ли (и как) этот ресурс кем-либо другим. Получение такой блокировки позволяет этому владельцу читать данные самой блокировки. Firebird сохраняет важную, но быстро меняющуюся информацию в блокировках- см. разд. "Использование пустой блокировки"

5

Size (Размер)

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

6

Length (Длина)

Фактическая длина ключа, которая из-за округления может быть меньше, чем размер

7

Data (Данные)

Только блокировки журналов и транзакций содержат данные. Данные являются 32-битовым целым числом

8

Key (Ключ)

Идентификатор заблокированного ресурса. Комбинация ключа, серии и родителя уникально идентифицирует заблокированный ресурс. Для базы данных ключом является имя базы данных (или некоторый эквивалент). Он может не выводиться в системах, которые используют целые числа как идентификаторы. Для отношения и существующей блокировки отношения ключ является идентификатором отношения. Для существующей блокировки индекса ключом является идентификатор отношения * 1000 плюс идентификатор индекса. Для блокировки теневой копии ключом является NULL, потому что существует только одно состояние теневого копирования базы данных. Для транзакции ключом является идентификатор транзакции. Для соединения ключом является идентификатор соединения

9

Hash queue (Очередь)

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

10

Requests (Запросы)

Вначале количество запросов на блокировку этого ресурса, затем указатели вперед и назад на группы блокировок. Имейте в виду, что обратный указатель ссылается на конец последнего блока

--

Request (Запрос)

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

--

Flags (Флаги)

Флаг запроса содержит биты, которые могут комбинироваться. Это:

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

2. Ожидание завершения: это наиболее часто просматриваемый бит. Он указывает, что запрос ожидает, когда блокирующий процесс освободит эту блокировку. Вы не должны смотреть установку этого бита в блокировках BDB.

4. Конвертирование: запрос конвертируется, если процесс уже имеет блокировку этого ресурса и требует более высокого уровня блокировки, а преобразование не может быть выполнено немедленно.

8. Отмена: запрос блокировки отменяется, если запрос в режиме NO WAIT и не может быть удовлетворен немедленно или если удовлетворение запроса может привести к взаимной блокировке

Серия 2: отношение

На рис. 40.5 показана группа для ресурса отношения (таблица, просмотр).

Рис. 40.5. Группа серии 2 (ресурс отношения)

В этом случае оба владельца читают отношение. Для отношения ключевым полем является значение RDB$RELATION_ID. Заметьте, что оба запроса сообщают о своем состоянии как 2(2), указывая, что они запросили и получили блокировку на совместное чтение таблицы.

Серия 3: дескриптор BDB (страница базы данных)

На рис. 40.6 показана группа блокировки страницы базы данных (дескриптор BDB).

Рис. 40.6. Блокировка серии 3 (дескриптор BDB)

Блокировка BDB является блокировкой страницы базы данных. Такие блокировки присутствуют, когда два или более владельца подключены к базе данных в Классическом сервере. Они появляются, когда процесс собирается читать или писать страницу, и освобождаются, когда процесс выходит из буферов в кэше и должен освободить пространство или когда другому владельцу нужна эта страница. В этом примере оба владельца читают страницу 14 (ключевое значение). В Классическом сервере существует множество блокировок типа серия 3 - по одному на каждый буфер страниц в кэше для каждого независимого подключения. В Суперсервере большинство блокировок страниц выполняется сервером и не присутствует в таблице блокировок.

Серия 4: транзакция

На рис. 40.7 показана группа ресурсов транзакции.

Рис. 40.7. Группа серии 4 (ресурсы транзакции)

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

Серии 5, 6 и 15: существование

На рис. 40.8 показаны группы блокировок существования для отношения.

Рис. 40.8. Серии 5, 6 и 15. Группы блокировок существования

Блокировки существования отношений (серия 5) предотвращают удаление таблицы, когда какой-нибудь процесс подготавливает запрос, который использует эту таблицу. Эта блокировка является источником ошибок "Object in use" (Объект находится в использовании), которая часто появляется при попытках удаления таблиц.

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

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

Эта блокировка существования отношения присутствует в отношении, которое имеет значением поля RDB$RELATION_ID 22.

Блокировки существования индексов предотвращают удаление или деактивацию индексов, когда другой процесс сохраняет запрос, использующий этот индекс.

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

Когда процесс собирается удалить или деактивировать индекс, он должен получить исключительную блокировку на существование этого индекса.

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

Идентификатор блокировки существования индекса 12 000, который равен идентификатору отношения, умноженному на 1000, плюс идентификатор индекса. Эта блокировка сообщает о заинтересованности в существовании индекса 0 для отношения 12.

Блокировки существования процедуры в точности аналогичны блокировкам существования отношения и индекса и служат аналогичным целям. Ключ является идентификатором процедуры из системной таблицы RDB$PROCEDURES.

Серия 8: теневая копия

На рис. 40.9 показаны группы блокировок ресурса теневой копии (shadow).

Рис. 40.9. Серии 8. Группы блокировок ресурса теневой копии

Каждый процесс, который подключается к базе данных, получает блокировку на совместное чтение на состояние теневого копирования базы данных. Если процесс собирается добавить новый файл теневой копии, он должен преобразовать его блокировку в исключительное состояние, что сообщает всем другим процессам о том, что появляется новый файл теневой копии и что они должны писать изменения в этот файл. Эта серия используется для общения между процессами в Классическом сервере. Она также используется в Суперсервере, хотя не при всех эффектах, когда не требуется IPC.

Группы запросов

На рис. 40.10 показаны некоторые группы запросов. В табл. 40.7 объясняется значение записей в группе запроса.

Рис. 40.10. Некоторые группы запросов

Таблица 40.7. Записи группы запросов

Значение

Объяснение

1

LOCK BLOCK

Идентифицирует конкретный запрос

2

Process (Процесс)

Смещение группы процесса, которая описывает процесс, выполнивший запрос

3

Lock (Блокировка)

Смещение группы блокировки, которая описывает блокируемый ресурс

4

State (Состояние)

Состояние блокировки, которое назначено этому ресурсу

5

Mode(Режим)

Состояние, которое было запрошено для блокировки. В первых двух примерах состояние (state) такое же, как и режим (mode). Это предоставленные блокировки. Первой был предоставлен режим защищенного чтения, второй - исключительный. В третьем примере находится в состоянии ожидания, следовательно, ее состояние 0 (нет блокировки), но режим 3 (защищенное чтение)

6

Flags (Флаги)

Флаг запроса содержит биты, которые могут комбинироваться. Это:

1: блокировка; 2: ожидание; 4: преобразование; 8: отмена

7

AST

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

Уровень блокировки базы данных будет понижен от исключительного (для первого пользователя) до совместного чтения, когда второй пользователь появляется в классической архитектуре. В Суперсервере база данных сохраняет для себя исключительную блокировку.

Блокировка на совместное чтение теневой копии освобождается, когда другой процесс запрашивает блокировку в исключительном режиме, следовательно, он может создавать новый файл (файлы) теневой копии. Коль скоро новые файлы будут созданы, любой другой сможет получить блокировку на совместное чтение в состоянии теневого копирования.

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

8

Argument (Аргумент)

Адрес чего-либо, что может понадобиться подпрограмме AST. В случае BDB это адрес структуры в процессе, которая описывает буфер.

В случае блокировок базы данных и теневой копии это адрес главной группы (DBB), которая описывает базу данных

Группа истории

Менеджер блокировок отслеживает действия ввода/вывода, которые он выполнял для каждого владельца. Самые последние действия выводятся в виде двух последних элементов отчета- истории (History) и событий (Events). На рис. 40.11 показана последовательность записей истории.

Рис. 40.11. Вывод записей истории

Владельцу 11 628 предоставлена блокировка на ресурс 11 744. Владелец 12 056 ставит в очередь запрос на тот же ресурс, запрашивая его в режиме NO WAIT. Блокировка у владельца 11 628 находится в несовместимом режиме, следовательно, этому запросу будет отказано (DENY). Владелец 12 056 опять приходит и ставит в очередь другой запрос, снова запрашивая блокировку, но уже в режиме WAIT. Менеджер блокировок отправляет сообщения владельцу 11 628 по поводу ресурса 11 744. Как было сказано, владелец находится в состоянии ожидания. Через 10 секунд владелец 12 056 все еще в состоянии ожидания, поэтому Менеджер блокировок запускает сканирование взаимных блокировок. Это не дает никаких результатов, и Менеджер блокировок опять отправляет сообщения владельцу 11 628 (POST, POST, POST). В конце концов владелец 11 628 снимает блокировку, и она предоставляется владельцу 12 056.

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

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