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
Группа блокировки на рис. 40.4 представляет саму базу данных. Она имеет исключительный доступ для одного владельца- базы данных. В Классическом сервере вы увидите несколько владельцев для базы данных.
< image l:href="#"/>Рис. 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 и не может быть удовлетворен немедленно или если удовлетворение запроса может привести к взаимной блокировке |
На рис. 40.5 показана группа для ресурса отношения (таблица, просмотр).
Рис. 40.5. Группа серии 2 (ресурс отношения)
В этом случае оба владельца читают отношение. Для отношения ключевым полем является значение RDB$RELATION_ID. Заметьте, что оба запроса сообщают о своем состоянии как 2(2), указывая, что они запросили и получили блокировку на совместное чтение таблицы.
На рис. 40.6 показана группа блокировки страницы базы данных (дескриптор BDB).
Рис. 40.6. Блокировка серии 3 (дескриптор BDB)
Блокировка BDB является блокировкой страницы базы данных. Такие блокировки присутствуют, когда два или более владельца подключены к базе данных в Классическом сервере. Они появляются, когда процесс собирается читать или писать страницу, и освобождаются, когда процесс выходит из буферов в кэше и должен освободить пространство или когда другому владельцу нужна эта страница. В этом примере оба владельца читают страницу 14 (ключевое значение). В Классическом сервере существует множество блокировок типа серия 3 - по одному на каждый буфер страниц в кэше для каждого независимого подключения. В Суперсервере большинство блокировок страниц выполняется сервером и не присутствует в таблице блокировок.